[](#understanding-cilium-network-performance)git
原文連接:https://cilium.io/blog/2021/0...github
做者:Thomas Graf
譯者:羅煜、張亮,均來自KubeSphere 團隊
Thomas Graf 是 Cilium 的聯合創始人,同時也是 Cilium 母公司 Isovalent 的 CTO 和聯合創始人。此前 Thomas 曾前後在 Linux 內核的網絡、安全和 eBPF 領域從事了 15 年的開發工做。
注:本文已取得做者本人的翻譯受權編程
你們好!👋安全
隨着愈來愈多的關鍵負載被遷移到 Kubernetes 上,網絡性能基準測試正在成爲選擇 Kubernetes 網絡方案的重要參考。在這篇文章中,咱們將基於過去幾周進行的大量基準測試的結果探討 Cilium 的性能特色。應廣大用戶的要求,咱們也將展現 Calico 的測試結果,以便進行直接對比。服務器
除了展現測試的結果數據外,咱們還將對容器網絡基準測試這一課題進行更深刻的研究,並探討如下幾個方面的問題:網絡
在詳細分析基準測試及其數據以前,咱們先展現彙總的測試結論。若是您但願直接瞭解測試細節並得出本身的結論,也能夠跳過這一節的內容。數據結構
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
測試結果的差別。socket
整體而言,從基準測試結果來看,eBPF 無疑是解決雲原生需求挑戰的最佳技術。tcp
對比 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 實現的吞吐量甚至略高於節點到節點的吞吐量。這使人很是意外。一般廣泛認爲,相較於節點到節點的網絡,容器網絡會帶來額外的開銷。咱們暫時先把這個疑惑擱置一旁,進一步研究以後再來分析這個問題。
TCP_STREAM
基準測試的結果已經暗示了哪些配置能夠最有效地實現高傳輸速率,但咱們仍是看一下運行基準測試時系統總體的 CPU 消耗。
上圖顯示了達到 100 Gbit/s 吞吐量整個系統所需的 CPU 使用率。請注意,這不一樣於前一個圖中吞吐量對應的 CPU 消耗。在上圖中,全部的 CPU 使用率都已折算爲傳輸速率穩定在 100 Gbit/s 時的數值以即可以直接對比。上圖中的條形圖越短,對應的配置在 100 Gbit/s 傳輸速率時的效率越高。
注意:TCP 流的性能一般受到接收端的限制,由於發送端能夠同時使用 TSO 大包。這能夠從上述測試中服務器側增長的 CPU 開銷中觀察到。
雖然大多數用戶不太可能常常遇到上述的吞吐量水平,但這樣的基準測試對特定類型的應用程序有重要意義:
在本文後面的章節,咱們將繼續深刻討論測量延遲:每秒請求數和新鏈接處理速率,以更好地展現典型微服務工做負載的性能特色。
在第一個基準測試的分析中咱們提到,與節點網絡相比,容器網絡會帶來一些額外開銷。這是爲何呢?讓咱們從架構的角度來對比這兩種網絡模型。
上圖代表容器網絡也須要執行節點到節點網絡的全部處理流程,而且這些流程都發生在容器的網絡命名空間中(深藍色部分)。
因爲節點網絡的處理工做也須要在容器網絡命名空間內進行,在容器網絡命名空間以外的任何工做本質上都是額外開銷。上圖顯示了使用 Veth 設備時,Linux 路由的網絡路徑。若是您使用 Linux 網橋或 OVS,網絡模型可能略有不一樣,但它們基本的開銷點是相同的。
在上面的基準測試中,您也許會疑惑 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)能夠帶來極大的性能提高。
在上文中,咱們分析了只涉及一個 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 的性能基本相同。這是由於它們使用了相同的數據路徑嗎?並非。並不存在預約義的 eBPF 數據路徑。eBPF 是一種編程語言和運行時引擎,它容許構建數據路徑特性和許多其餘特性。Cilium 和 Calico eBPF 數據路徑差別很大。事實上,Cilium 提供了不少 Calico eBPF 不支持的特性。但即便是在與 Linux 網絡棧的交互上,二者也有顯著的差別。咱們能夠經過兩者的 CPU 火焰圖來來進一步分析。
Cilium 的 eBPF 主機路由提供了很好的免上下文切換的數據傳送途徑(從網卡到應用程序的套接字)。這就是爲何在上面的火焰圖中整個接收端路徑可以很好地匹配到一張火焰圖中。火焰圖也顯示了 eBPF、TCP/IP 和套接字的處理塊。
Calico eBPF 接收端看起來卻不太同樣。雖然有着相同的 eBPF 處理塊執行 eBPF 程序,但 Calico eBPF 接收路徑穿過了額外的 Veth,這在 Cilium eBPF 數據路徑接收端並不須要。
上圖中的處理仍然在主機的上下文中執行。下面的這火焰圖顯示了 Pod 中被 process_backlog
恢復執行的工做。雖然這與 Cilium 場景下的工做同樣(都是 TCP/IP+套接字數據傳送),但由於穿過了 Veth 從而須要額外的上下文切換。
若是您但願本身進行更進一步的研究,能夠點擊如下連接打開交互式的火焰圖 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 在不一樣的最大傳輸單元(MTU)下的性能。
不一樣的配置之間有一些差別。值得注意的是,Cilium 與 kube-proxy 的組合比單獨 Cilium 的性能更好。然而,這個性能差別相對較小而且基本能夠經過優化 MTU 彌補。
如下是 CPU 資源的消耗:
上述結果代表在 MTU 相同的狀況下,不一樣配置之間的 CPU 使用率差別很小,於是能夠經過優化 MTU 配置得到最佳性能。咱們還對每秒請求數進行了測試,獲得的結果也相同。感興趣的讀者能夠參閱 Cilium 文檔的 CNI 性能基準測試章節。
對 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 消耗方面的差別,延遲方面的差別更爲顯著。
如下是咱們使用的裸機配置。咱們搭建了兩套徹底同樣的互相直連的系統。
CONFIG_PREEMPT_NONE
)除非特別說明,全部測試都使用了標準的 1500 字節 MTU。雖然 MTU 的值越高,測試結果的絕對數值會越好,但本文的基準測試的目的在於比較相對差別,而不是測試最高或最低性能的絕對數值。
應廣大用戶的要求,咱們展現了 Calico 的測試結果以便進行對比。爲了儘量清晰地進行對比,咱們使用瞭如下配置類型進行測試:
netperf
。一般狀況下此配置的性能最優。測試所用的所有腳本都已經上傳到 GitHub 倉庫 cilium/cilium-perf-networking 中,可用於復現測試結果。
咱們在性能調優方面已經取得了很多結果,但咱們還有許多其餘的想法並將進一步優化 Cilium 各方面的性能。
Service 和 NetworkPolicy 基準測試:當前的基準測試結果並不涉及任何 Service 和 NetworkPolicy。咱們沒有對兩者進行測試以控制本文的內容範圍。咱們將進一步對使用 NetworkPolicy 的用例進行測試,除此以外還將對東西向(east-west)和南北向(north-south)的 Service 進行測試。若是您已經等不及了,Cilium 1.8 的發佈博客已經公佈了一些基準測試結果,而且展現了 XDP 和 eBPF 對性能的顯著提高。
目前,咱們仍然對 NetworkPolicy 在 CIDR 規則方面的性能不太滿意。咱們當前的架構針對少許複雜的 CIDR 進行了優化,但並無覆蓋使用 LPM 來實現的一些特例。一些用戶可能但願對單獨 IP 地址的大型放行和阻止列表進行基準測試。咱們會把這個用例放在優先事項中,而且提供基於哈希表的實現。
爲了跟社區新老朋友們零距離交流,咱們將聯合 CNCF 和其餘合做夥伴,從五月到七月,在上海、杭州、深圳、成都這四個城市分別爲你們帶來技術的交流與碰撞。2021 年繼上海站首次 Meetup 火爆全場以後,咱們將依舊延續 KubeSphere and Friends 的主題,於 5 月 29 日杭州爲你們帶來 Kubernetes and Cloud Native Meetup。
咱們特別定製了 KubeSphere 全套記念周邊禮品:T恤、馬克杯、記念徽章、帆布袋、口罩等。除此以外還有各類雲原生硬核書籍等你來拿!
怎麼樣,心動了麼?報名參與即將到來的杭州站便可得到定製周邊記念品!
本文由博客一文多發平臺 OpenWrite 發佈!