作者:Thomas Graf
譯者:羅煜、張亮,均來自KubeSphere 團隊
Thomas Graf 是 Cilium 的聯合創始人,同時也是 Cilium 母公司 Isovalent 的 CTO 和聯合創始人。此前 Thomas 曾先后在 Linux 內核的網絡、安全和 eBPF 領域從事了 15 年的開發工作。
注:本文已取得作者本人的翻譯授權
大家好!👋
隨着越來越多的關鍵負載被遷移到 Kubernetes 上,網絡性能基准測試正在成為選擇 Kubernetes 網絡方案的重要參考。在這篇文章中,我們將基於過去幾周進行的大量基准測試的結果探討 Cilium 的性能特點。應廣大用戶的要求,我們也將展示 Calico 的測試結果,以便進行直接對比。
除了展示測試的結果數據外,我們還將對容器網絡基准測試這一課題進行更深入的研究,並探討以下幾個方面的問題:
- 吞吐量基准測試
- 容器網絡是否會增加開銷
- 打破常規:eBPF 主機路由(Host Routing)
- 測量延遲:每秒請求數
- Cilium eBPF 和 Calico eBPF 的 CPU 火焰圖對比
- 新連接處理速率
- WireGuard 與 IPsec 加密開銷對比
- 測試環境
測試結果匯總
在詳細分析基准測試及其數據之前,我們先展示匯總的測試結論。如果您希望直接了解測試細節並得出自己的結論,也可以跳過這一節的內容。
-
eBPF 起決定性作用:Cilium 在某些方面優於 Calico 的 eBPF 數據路徑(Data Path),例如在
TCP_RR
和TCP_CRR
基准測試中觀察到的延遲。此外,更重要的結論是 eBPF 明顯優於 iptables。在允許使用 eBPF 繞過 iptables 的配置環境中,Cilium 和 Calico 的性能都明顯優於不能繞過 iptables 的情況。在研究具體細節后,我們發現 Cilium 和 Calico 利用 eBPF 的方式並不完全相同。雖然二者的某些概念是相似的(考慮到開源的性質,這也並不奇怪),CPU 火焰圖顯示 Cilium 利用了額外的上下文切換節省功能。這或許可以解釋
TCP_RR
和TCP_CRR
測試結果的差異。總體而言,從基准測試結果來看,eBPF 無疑是解決雲原生需求挑戰的最佳技術。
-
可觀察性、NetworkPolicy 和 Service:對於這個基准測試,我們把關注的焦點放在二者的共性上,也就是網絡。這使得我們可以直接對比節點網絡帶來的性能差異。然而,在實際應用中也會需要用到可觀測性、NetworkPolicy 和 Service,在這些方面 Cilium 和 Calico eBPF 數據路徑差異巨大。Cilium 支持一些 Calico eBPF 數據路徑不具備的功能,但即便是 Kubernetes NetworkPolicy 之類的標准功能,Cilium 和 Calico 的實現方式也不一樣。如果我們投入更大的精力測試在這些更高級的用例中應用 eBPF,我們可能會發現二者在這些方面的性能有顯著差異。然而,限於篇幅本文將不對此作更多的探討,更加深入的研究將留給下一篇文章。
-
對比 WireGuard 和 IPsec:有些令人意外,盡管 WireGuard 在我們的測試中能夠實現更高的最大吞吐量,但 IPsec 在相同的吞吐量下 CPU 使用效率更高。這很有可能得益於 AES-NI CPU 指令集。該指令集支持卸載 IPsec 的加密工作,但 WireGuard 不能從中受益。當 AES-NI 指令集不可用時,結果就明顯反轉了。
好消息是,從 Cilium 1.10 開始,Cilium 不僅支持 IPsec 還支持 WireGuard。您可以選擇其中之一來使用。
吞吐量基准測試
免責聲明:
基准測試難度很大。測試結果很大程度上依賴於運行測試的硬件環境。除非是在相同的系統上收集的結果,否則不應直接用絕對的數值進行比較。
讓我們從最常見和最明顯的 TCP 吞吐量基准測試開始,測量運行在不同節點上的容器之間的最大數據傳輸速率。
上圖顯示了單個 TCP 連接可實現的最大吞吐量,最優的幾個配置性能剛好超過了 40 Gbit/s。以上結果由 netperf
的 TCP_STREAM
測試得出,測試環境使用了速率為 100 Gbit/s 的網口以確保網卡不會成為瓶頸。由於運行單個 netperf
進程通過單個 TCP 連接傳輸數據,大部分的網絡處理是由單個 CPU 核心完成的。這意味着上面的最大吞吐量受到單個核心的可用 CPU 資源限制,因此可以顯示當 CPU 成為瓶頸時每個配置可以實現的吞吐量。本文后面將會進一步擴展測試,使用更多的 CPU 核心來消除 CPU 資源的限制。
使用高性能 eBPF 實現的吞吐量甚至略高於節點到節點的吞吐量。這令人非常意外。通常普遍認為,相較於節點到節點的網絡,容器網絡會帶來額外的開銷。我們暫時先把這個疑惑擱置一旁,進一步研究之后再來分析這個問題。
100 Gbit/s 傳輸速率所需的 CPU 資源
TCP_STREAM
基准測試的結果已經暗示了哪些配置可以最有效地實現高傳輸速率,但我們還是看一下運行基准測試時系統整體的 CPU 消耗。
上圖顯示了達到 100 Gbit/s 吞吐量整個系統所需的 CPU 使用率。請注意,這不同於前一個圖中吞吐量對應的 CPU 消耗。在上圖中,所有的 CPU 使用率都已折算為傳輸速率穩定在 100 Gbit/s 時的數值以便可以直接對比。上圖中的條形圖越短,對應的配置在 100 Gbit/s 傳輸速率時的效率越高。
注意:TCP 流的性能通常受到接收端的限制,因為發送端可以同時使用 TSO 大包。這可以從上述測試中服務器側增加的 CPU 開銷中觀察到。
TCP 吞吐量基准測試的意義
雖然大多數用戶不太可能經常遇到上述的吞吐量水平,但這樣的基准測試對特定類型的應用程序有重要意義:
- 需要訪問大量數據的 AI/ML 應用程序
- 數據上傳/下載服務(備份服務、虛擬機鏡像、容器鏡像服務等)
- 流媒體服務,特別是 4K+ 分辨率的流媒體
在本文后面的章節,我們將繼續深入討論測量延遲:每秒請求數和新連接處理速率,以更好地展示典型微服務工作負載的性能特點。
容器網絡是否會增加開銷
在第一個基准測試的分析中我們提到,與節點網絡相比,容器網絡會帶來一些額外開銷。這是為什么呢?讓我們從架構的角度來對比這兩種網絡模型。
上圖表明容器網絡也需要執行節點到節點網絡的所有處理流程,並且這些流程都發生在容器的網絡命名空間中(深藍色部分)。
由於節點網絡的處理工作也需要在容器網絡命名空間內進行,在容器網絡命名空間之外的任何工作本質上都是額外開銷。上圖顯示了使用 Veth 設備時,Linux 路由的網絡路徑。如果您使用 Linux 網橋或 OVS,網絡模型可能略有不同,但它們基本的開銷點是相同的。
打破常規:eBPF 主機路由(Host-Routing)
在上面的基准測試中,您也許會疑惑 Cilium eBPF 和 Cilium eBPF 傳統主機路由(Legacy Host Routing)兩種配置的區別,以及為什么原生的 Cilium eBPF 數據路徑會比主機路由快得多。原生的 Cilium eBPF 數據路徑是一種被稱為 eBPF 主機路由的優化數據路徑,如下圖所示:
eBPF 主機路由允許繞過主機命名空間中所有的 iptables 和上層網絡棧,以及穿過 Veth 對時的一些上下文切換,以節省資源開銷。網絡數據包到達網絡接口設備時就被盡早捕獲,並直接傳送到 Kubernetes Pod 的網絡命名空間中。在流量出口側,數據包同樣穿過 Veth 對,被 eBPF 捕獲后,直接被傳送到外部網絡接口上。eBPF 直接查詢路由表,因此這種優化完全透明,並與系統上運行的所有提供路由分配的服務兼容。關於如何啟用該特性,請參閱調優指南中的 eBPF 主機路由。
Calico eBPF 正在將一些類似的繞過方法用於 iptables,但這與 Cilium 的原理並不完全相同,文章后面會進一步介紹。不管如何,測試結果證明繞過緩慢的內核子系統(例如 iptables)可以帶來極大的性能提升。
逼近 100 Gbit/s 的線速率(Line Rate)
在上文中,我們分析了只涉及一個 CPU 核心的基准測試結果。接下來我們將放開單核的限制,將 TCP 流並行化以運行多個 netperf
進程。
注意:由於硬件有 32 個線程,我們特意選擇了 32 個進程,以確保系統能夠均勻地分配負載。
上圖並沒有提供十分有價值的信息,僅僅表明如果投入足夠多的 CPU 資源,所有測試配置都能達到接近 100 Gbit/s 的線速率。然而,從 CPU 資源來看,我們仍然可以發現效率上的差異。
請注意,上圖中的 CPU 使用率涵蓋了全部的 CPU 消耗,包括正在運行的 netperf
進程的消耗,也包括工作負載執行網絡 I/O 所需的 CPU 資源。然而,它並不包括應用程序通常需要執行的任何業務邏輯所帶來的 CPU 消耗。
測量延遲:每秒請求數
每秒請求數與吞吐量指標幾乎完全相反。它可以衡量單個 TCP 持久連接上按順序的單字節往返的傳輸速率。此基准測試可以體現網絡數據包的處理效率。單個網絡數據包的延遲越低,每秒可處理的請求就越多。吞吐量和延遲的共同優化通常需要進行權衡。為了獲得最大的吞吐量,較大的緩沖區是理想的選擇,但是較大的緩沖區會導致延遲增加。這一現象被稱為緩沖區膨脹。Cilium 提供了一個稱為帶寬管理器(Bandwidth Manager)的功能,該功能可以自動配置公平隊列,可實現基於最早發出時間的 Pod 速率限制,並為服務器工作負載優化 TCP 棧設置,使吞吐量和延遲之間達到最佳平衡。
這個基准測試經常被忽視,但它對用戶來說通常比想象的重要得多,因為它模擬了一種十分常見的微服務使用模式:使用持久化的 HTTP 或 gRPC 連接在 Service 之間發送請求和響應。
下圖顯示單個 netperf
進程執行 TCP_RR
測試時,不同配置的性能表現:
在這個測試中表現更好的配置也實現了更低的平均延遲。然而,這並不足以讓我們對 P95 或 P99 延遲得出結論。我們將在未來的博客文章中探討這些問題。
我們進一步測試運行 32 個並行的 netperf
進程以利用所有可用的 CPU 核心。可以看到,所有配置的性能都有所提升。然而,與吞吐量測試不同的是,在本測試中投入更多的 CPU 資源並不能彌補效率上的欠缺,因為最大處理速率受延遲而非可用 CPU 資源限制。即便網絡帶寬成為瓶頸,我們也會看到相同的每秒請求數值。
總體而言,結果非常鼓舞人心,Cilium 可以在我們的測試系統上通過 eBPF 主機路由實現近 1,000,000 請求每秒的處理速率。
Cilium eBPF 和 Calico eBPF 的 CPU 火焰圖對比
總體而言,Cilium eBPF 和 Calico eBPF 的性能基本相同。這是因為它們使用了相同的數據路徑嗎?並不是。並不存在預定義的 eBPF 數據路徑。eBPF 是一種編程語言和運行時引擎,它允許構建數據路徑特性和許多其他特性。Cilium 和 Calico eBPF 數據路徑差異很大。事實上,Cilium 提供了很多 Calico eBPF 不支持的特性。但即使是在與 Linux 網絡棧的交互上,兩者也有顯著的差異。我們可以通過二者的 CPU 火焰圖來來進一步分析。
Cilium eBPF(接收路徑)
Cilium 的 eBPF 主機路由提供了很好的免上下文切換的數據傳送途徑(從網卡到應用程序的套接字)。這就是為什么在上面的火焰圖中整個接收端路徑能夠很好地匹配到一張火焰圖中。火焰圖也顯示了 eBPF、TCP/IP 和套接字的處理塊。
Calico eBPF(接收路徑)
Calico eBPF 接收端看起來卻不太一樣。雖然有着相同的 eBPF 處理塊執行 eBPF 程序,但 Calico eBPF 接收路徑穿過了額外的 Veth,這在 Cilium eBPF 數據路徑接收端並不需要。
上圖中的處理仍然在主機的上下文中執行。下面的這火焰圖顯示了 Pod 中被 process_backlog
恢復執行的工作。雖然這與 Cilium 場景下的工作一樣(都是 TCP/IP+套接字數據傳送),但因為穿過了 Veth 從而需要額外的上下文切換。
如果您希望自己進行更進一步的研究,可以點擊以下鏈接打開交互式的火焰圖 SVG 文件查看細節:
- Cilium eBPF SVG 火焰圖 - 發送端
- Cilium eBPF SVG 火焰圖 - 接收端
- Calico eBPF SVG 火焰圖 - 發送端
- Calico eBPF SVG 火焰圖 - 接收端
新連接處理速率
連接處理速率基准測試基於每秒請求數的基准測試,但為每個請求都建立了新的連接。此基准測試的結果顯示了使用持久連接和為每個請求創建新連接兩種方式的性能差別。創建新 TCP 連接需要涉及系統中的多個組件,所以這個測試是目前對整個系統壓力最大的測試。通過這個基准測試,我們可以看到,充分利用系統中大多數的可用資源是可能的。
這個測試展示了一個接收或發起大量 TCP 連接的工作負載。典型的應用場景是由一個公開暴露的服務處理大量客戶端請求,例如 L4 代理或服務為外部端點(例如數據抓取器)創建多個連接。這個基准測試能夠在卸載到硬件的工作最少的情況下盡可能地壓測系統,從而顯示出不同配置的最大性能差異。
首先,我們運行一個 netperf
進程來進行 TCP_CRR
測試。
在單個進程下不同配置的性能差異已經十分巨大,如果使用更多的 CPU 核心差異還將進一步擴大。同時也可以明顯看出,Cilium 再次能夠彌補網絡命名空間額外開銷造成的性能損失並達到和基線配置幾乎相同的性能。
后續計划:這個 CPU 資源使用率讓我們很驚訝並促使我們在接下來 1.11 的開發周期做進一步研究。似乎只要涉及到網絡命名空間的使用,發送端的資源開銷總是必不可少的。這一開銷在所有涉及網絡命名空間的配置中都存在,所以很有可能是由 Cilium 和 Calico 都涉及的內核數據路徑造成的。我們會及時更新這部分研究的進展。
當並行運行 32 個進行 TCP_CRR
測試的 netpert
進程以利用所有 CPU 核心時,我們觀察到了一個非常有意思的現象。
基線配置的連接處理速率顯著下降。基線配置的性能並沒有隨着可用 CPU 資源的增多而進一步提升,盡管連接跟蹤狀態表大小發生了相應變化並且我們確認並沒有發生因連接跟蹤表記錄達到上限而導致的性能降低。我們重復進行了多次相同的測試,結果仍然相同。當我們手動通過 -j NOTRACK
規則繞過 iptables 連接跟蹤表時,問題立刻解決了,基線配置性能恢復到 200,000 連接每秒。所以很明顯,一旦連接數超過某個閾值,iptables 連接跟蹤表就會開始出現問題。
注意:在這個測試中,Calico eBPF 數據路徑的測試結果一直不是很穩定。我們目前還不清楚原因。網絡數據包的傳輸也不是很穩定。我們沒有將測試結果納入考慮,因為測試結果不一定准確。我們邀請 Calico 團隊和我們一起研究這個問題並重新進行測試。
鑒於我們使用的是未經修改的標准應用程序來處理請求和傳輸信息,每秒處理 200,000 連接是一個非常優秀的成績。不過,我們還是看一下 CPU 的消耗。
這個基准測試結果顯示了不同配置的最大性能差異。為了達到每秒處理 250,000 新連接的目標,整個系統必須消耗 33% 到 90% 的可用資源。
由於發送端 CPU 資源消耗一直高於接收端,我們可以確信相同資源下每秒能接收的連接數要大於每秒能發起的連接數。
WireGuard 與 IPsec 加密開銷對比
可能所有人都會認為 WireGuard 的性能會優於 IPsec,所以我們先測試 WireGuard 在不同的最大傳輸單元(MTU)下的性能。
不同的配置之間有一些差異。值得注意的是,Cilium 與 kube-proxy 的組合比單獨 Cilium 的性能更好。然而,這個性能差異相對較小並且基本可以通過優化 MTU 彌補。
以下是 CPU 資源的消耗:
上述結果表明在 MTU 相同的情況下,不同配置之間的 CPU 使用率差異很小,因而可以通過優化 MTU 配置獲得最佳性能。我們還對每秒請求數進行了測試,得到的結果也相同。感興趣的讀者可以參閱 Cilium 文檔的 CNI 性能基准測試章節。
WireGuard 與 IPsec 對比
對 Wireguard 和 IPsec 的性能進行比較更加有趣。Cilium 支持 IPsec 已經有一段時間了。從 1.10 開始,Cilium 也開始支持 WireGuard。在其他方面相同的情況下,把這兩個加密方案放在一起進行對比,結果一定會非常有趣。
不出所料,WireGuard 的吞吐量更高,並且在兩種 MTU 配置下,WireGuard 的最大傳輸速率更高。
下面繼續測試當吞吐量達到 10 Gbit/s 時,WireGuard 和 IPsec 在不同的 MTU 配置下的 CPU 使用率。
雖然 WireGuard 的最大吞吐量更高,但 IPsec 在吞吐量相同的情況下 CPU 開銷更小從而更有效率,這個差異非常巨大。
注意:為了實現 IPsec 的高效率,需要使用支持 AES-NI 指令集的硬件來卸載 IPsec 的加密工作。
后續計划:目前我們還不清楚為什么 IPsec 的高效率沒有帶來更高的吞吐量。使用更多的 CPU 核心也沒有明顯提升性能。這很可能是由於 RSS 不能很好地跨 CPU 核心處理加密流量,因為通常用於哈希和跨 CPU 核心分配流量的 L4 信息是加密的,無法解析。因此,從哈希的角度來看,所有的連接都是一樣的,因為在測試中只利用了兩個 IP 地址。
這是否會影響延遲?讓我進一步研究。延遲基准測試最能准確地描述微服務工作負載的實際狀況,微服務工作負載通常都會使用持久連接來交換請求和響應。
CPU 效率與觀察到的每秒請求數相符。然而,每個配置總共消耗的 CPU 資源都不是很高。相比 CPU 消耗方面的差異,延遲方面的差異更為顯著。
測試環境
以下是我們使用的裸機配置。我們搭建了兩套完全一樣的互相直連的系統。
- CPU:AMD Ryzen 9 3950X,AM4 平台,3.5 GHz,16 核 32 線程
- 主板:X570 Aorus Master,支持 PCIe 4.0 x16
- 內存:HyperX Fury DDR4-3200 128 GB,XMP 頻率 3.2 GHz
- 網卡: Intel E810-CQDA2,雙端口,每端口速率 100 Gbit/s,PCIe 4.0 x16
- 操作系統內核: Linux 5.10 LTS(配置為
CONFIG_PREEMPT_NONE
)
除非特別說明,所有測試都使用了標准的 1500 字節 MTU。雖然 MTU 的值越高,測試結果的絕對數值會越好,但本文的基准測試的目的在於比較相對差異,而不是測試最高或最低性能的絕對數值。
測試配置
應廣大用戶的要求,我們展示了 Calico 的測試結果以便進行對比。為了盡可能清晰地進行對比,我們使用了以下配置類型進行測試:
- 基線配置(節點到節點):此配置不使用 Kubernetes 或容器,在基准測試過程中直接在祼機上運行
netperf
。通常情況下此配置的性能最優。 - Cilium eBPF: Cilium 版本為 1.9.6 並按照調優指南進行了調優,開啟了 eBPF 主機路由和 kube-proxy 替換。此配置需要操作系統內核版本為 5.10 或以上。此配置與 Calico eBPF 配置對比最具有參照性。我們重點進行了直接路由模式的基准測試,因為這種模式下性能通常尤為重要。后續我們也會進一步進行隧道模式的相關基准測試。
- Cilium eBPF(傳統主機路由):Cilium 版本為 1.9.6,以傳統主機路由的模式運行,使用標准 kube-proxy,支持 4.9 及以下內核版本。此配置與 Calico 配置對比最具有參照性。
- Calico eBPF:Calico 版本為 3.17.3,同時使用了開啟 kube-proxy 替換、連接跟蹤繞過以及 eBPF FIB 查詢的 eBPF 數據路徑。此配置需要操作系統內核版本為 5.3 或以上。此配置與 Cilium eBPF 配置對比最具有參照性。
- Calico: Calico 版本為 3.17.3,使用標准 kube-proxy,支持較低版本的操作系統內核。此配置與 Cilium eBPF(傳統主機路由)配置對比最具有參照性。
復現測試結果
測試所用的全部腳本都已經上傳到 GitHub 倉庫 cilium/cilium-perf-networking 中,可用於復現測試結果。
下一步
我們在性能調優方面已經取得了不少結果,但我們還有許多其他的想法並將進一步優化 Cilium 各方面的性能。
-
可觀察性基准測試:單純的網絡基准測試是必要的,但是實現可觀察性所需資源的消耗才是真正區分系統高下的領域。無論是對系統安全還是對故障排除來說,可觀察性都是基礎設施的關鍵特性,並且不同系統的可視化資源消耗有很大不同。eBPF 是實現可觀察性的優秀工具,並且 Cilium 的 Hubble 組件也可以從中受益。在本文的基准測試中,我們禁用了 Hubble 以便測試結果可以與 Calico 對比。在后續的文章中,我們將對 Hubble 進行基准測試,以驗證 Hubble 的 CPU 需求並將 Hubble 與其他類似的系統對比。
-
Service 和 NetworkPolicy 基准測試:當前的基准測試結果並不涉及任何 Service 和 NetworkPolicy。我們沒有對二者進行測試以控制本文的內容范圍。我們將進一步對使用 NetworkPolicy 的用例進行測試,除此之外還將對東西向(east-west)和南北向(north-south)的 Service 進行測試。如果您已經等不及了,Cilium 1.8 的發布博客已經公布了一些基准測試結果,並且展示了 XDP 和 eBPF 對性能的顯著提升。
目前,我們仍然對 NetworkPolicy 在 CIDR 規則方面的性能不太滿意。我們當前的架構針對少量復雜的 CIDR 進行了優化,但並沒有覆蓋使用 LPM 來實現的一些特例。一些用戶可能希望對單獨 IP 地址的大型放行和阻止列表進行基准測試。我們會把這個用例放在優先事項中,並且提供基於哈希表的實現。
-
內存優化:我們將繼續優化 Cilium 的內存占用。Cilium 主要的內存占用來自於 eBPF 的 Map 分配。這些是網絡處理所需要的內核級數據結構。為了提高效率,eBPF Map 的大小是預先設定的,以便根據配置所需的內存量最小。我們目前對這方面並不是很滿意,這將是我們后續版本的重點工作。
-
打破更多的規則:更多地繞過 iptables:我們認為 iptables 應該完全繞過。容器命名空間和系統其他部分仍有優化潛力。我們還會繼續努力加快服務網格的數據路徑應用程序。目前已經有一個利用 Envoy 的 Socket 層重定向的初步版本。請期待這個方面的進展。
-
想法和建議:如果您有其他想法和建議,請告訴我們。例如,您希望我們進行哪些基准測試或改進?我們非常希望能得到反饋意見。您可以在 Cilium Slack 發表想法或者通過 Twitter 聯系我們。
更多信息
- 本文的所有結果數據都可以在 Cilium 文檔的 CNI 性能基准測試章節查閱。我們會持續更新這些數據。
- 調優指南提供了對 Cilium 進行調優的完整教程。
- 有關 Cilium 的更多信息,請參閱 Cilium 官方文檔。
- 有關 eBPF 的更多信息,請訪問 eBPF 官方網站。
KubeSphere 社區活動通知
為了跟社區新老朋友們零距離交流,我們將聯合 CNCF 和其他合作伙伴,從五月到七月,在上海、杭州、深圳、成都這四個城市分別為大家帶來技術的交流與碰撞。2021 年繼上海站首次 Meetup 火爆全場之后,我們將依舊延續 KubeSphere and Friends 的主題,於 5 月 29 日杭州為大家帶來 Kubernetes and Cloud Native Meetup。
我們特別定制了 KubeSphere 全套紀念周邊禮品:T恤、馬克杯、紀念徽章、帆布袋、口罩等。除此之外還有各種雲原生硬核書籍等你來拿!
怎么樣,心動了么?報名參與即將到來的杭州站即可獲得定制周邊紀念品!
本文由博客一文多發平台 OpenWrite 發布!