(轉)一文看懂 Kube-proxy


Kube-proxy 是 kubernetes 工作節點上的一個網絡代理組件,運行在每個節點上。

Kube-proxy維護節點上的網絡規則,實現了Kubernetes Service 概念的一部分 。它的作用是使發往 Service 的流量(通過ClusterIP和端口)負載均衡到正確的后端Pod。

工作原理

kube-proxy 監聽 API server 中 資源對象的變化情況,包括以下三種:

  • service
  • endpoint/endpointslices
  • node

然后根據監聽資源變化操作代理后端來為服務配置負載均衡。

如果你的 kubernetes 使用EndpointSlice,那么kube-proxy會監聽EndpointSlice,否則會監聽Endpoint。

如果你啟用了服務拓撲,那么 kube-proxy 也會監聽 node 信息 。服務拓撲(Service Topology)可以讓一個服務基於集群的 Node 拓撲進行流量路由。 例如,一個服務可以指定流量是被優先路由到一個和客戶端在同一個 Node 或者在同一可用區域的端點。

代理模式

目前 Kube-proxy 支持4中代理模式:

  • userspace
  • iptables
  • ipvs
  • kernelspace

其中 kernelspace 專用於windows,userspace 是早期版本的實現,本文我們不作過多闡述。

iptables(通過apiserver監聽svc和endpoints/endpointslices資源生成iptables規則——nat表)

iptables是一種Linux內核功能,旨在成為一種高效的防火牆,具有足夠的靈活性來處理各種常見的數據包操作和過濾需求。它允許將靈活的規則序列附加到內核的數據包處理管道中的各種鈎子上。

在iptables模式下,kube-proxy將規則附加到“ NAT預路由”鈎子上,以實現其NAT和負載均衡功能。這種方法很簡單,使用成熟的內核功能,並且可以與通過iptables實現網絡策略的組件“完美配合”。

默認的策略是,kube-proxy 在 iptables 模式下隨機選擇一個后端。

如果 kube-proxy 在 iptables 模式下運行,並且所選的第一個 Pod 沒有響應, 則連接失敗。 這與用戶空間模式不同:在這種情況下,kube-proxy 將檢測到與第一個 Pod 的連接已失敗, 並會自動使用其他后端 Pod 重試。

但是,kube-proxy對iptables規則進行編程的方式是一種O(n)復雜度的算法,其中n與集群大小(或更確切地說,服務的數量和每個服務背后的后端Pod的數量)成比例地增長)。

ipvs(通過apiserver監聽svc和endpoints/endpointslices資源生成ipvs和iptables規則)

IPVS是專門用於負載均衡的Linux內核功能。在IPVS模式下,kube-proxy可以對IPVS負載均衡器進行編程,而不是使用iptables。這非常有效,它還使用了成熟的內核功能,並且IPVS旨在均衡許多服務的負載。它具有優化的API和優化的查找例程,而不是一系列順序規則。 結果是IPVS模式下kube-proxy的連接處理的計算復雜度為O(1)。換句話說,在大多數情況下,其連接處理性能將保持恆定,而與集群大小無關。

與 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延遲要短,並且在同步代理規則時具有更好的性能。 與其他代理模式相比,IPVS 模式還支持更高的網絡流量吞吐量。

IPVS提供了更多選項來平衡后端Pod的流量。 這些是:

  • rr: round-robin
  • lc: least connection (smallest number of open connections)
  • dh: destination hashing
  • sh: source hashing
  • sed: shortest expected delay
  • nq: never queue

IPVS的一個潛在缺點是,與正常情況下的數據包相比,由IPVS處理的數據包通過iptables篩選器鈎子的路徑不同。如果打算將IPVS與其他使用iptables的程序一起使用,則需要研究它們是否可以一起正常工作。 不過Ipvs代理模式已經推出很久了,很多組件已經適配的很好了,比如Calico。

性能對比

TIGERA 公司 從響應時間CPU使用率兩個角度對兩種代理模式進行了對比。在專用節點上運行了一個“客戶端”微服務Pod,它每秒向Kubernetes服務生成1000個請求,該請求由集群中其他節點上運行的10個“服務器”微服務Pod承載。然后,在iptables和IPVS模式下,使用各種數量的Kubernetes服務(每個服務有10個Pod支持),最多10,000個服務(帶有100,000個服務后端)來測量客戶端節點上的性能。

Round-Trip 響應時間

  • 在超過1,000個服務(10,000個后端Pod)之前,iptables和IPVS之間的平均往返響應時間之間的差異微不足道。
  • 僅當不使用keepalive連接時,平均往返響應時間才有差異。

CPU消耗

  • iptables和IPVS之間的CPU使用率差異不明顯,直到超過1,000個服務(帶有10,000個后端Pod)為止。
  • 在10,000個服務(具有100,000個后端pod)的情況下,使用iptables的CPU的增加量約為內核的35%,而使用IPVS的CPU的增加量約為內核的8%。

總結

對於iptables和IPVS模式,kube-proxy的響應時間開銷與建立連接相關,而不是與在這些連接上發送的數據包或請求的數量有關。這是因為Linux使用的連接跟蹤(conntrack)能夠非常有效地將數據包與現有連接進行匹配。如果數據包在conntrack中匹配,則無需檢查kube-proxy的iptables或IPVS規則即可確定該如何處理。

在集群中不超過1000個服務的時候,iptables 和 ipvs 並無太大的差異。而且由於iptables 與網絡策略實現的良好兼容性,iptables 是個非常好的選擇。(通過與其他公司k8s運維人員交流,大部分都會選擇使用ipvs模式)

當你的集群服務超過1000個時,而且服務之間鏈接大多沒有開啟keepalive,IPVS模式可能是一個不錯的選擇。

發展趨勢

個人總結 kube-proxy 未來發展可能會朝着以下兩個方向:

  • 接口化,類似於cni。kube-proxy 只實現主體框架和接口規范,社區可以有iptables,ipvs,ebpf,nftables等具體實現。

Kubernetes以具備可擴展性而著名。截止到目前,Kube-proxy 幾乎是所有k8s組件里邊最沒有接口化的一個組件。如果想給 kube-proxy 增加一種代理模式,必須代碼侵入。所以社區有人想將 nftables 做為 kube-proxy 的一種后端,該 pr 至今沒有被merge。

nftables是一個新式的數據包過濾框架,旨在替代現用的iptables、ip6tables、arptables和ebtables的新的包過濾框架。
nftables旨在解決現有{ip/ip6}tables工具存在的諸多限制。相對於舊的iptables,nftables最引人注目的功能包括:改進性能、支持查詢表、事務型規則更新、所有規則自動應用等等。

踐行該觀點的容器網絡框架非cilium莫屬。

Cilium 正在通過 ebpf 實現 kube-proxy 提供的功能。不過由於 ebpf 對 os 內核版本要求比較高,所以一些低版本內核是無法支持的。

CNI chaining 允許cilium 和其他cni容器網絡組建結合使用。通過Cilium CNI chaining ,基本網絡連接和IP地址管理由非Cilium CNI插件管理,但是Cilium將eBPF程序附加到由非Cilium插件創建的網絡設備上,以提供L3 / L4 / L7網絡可見性和策略強制執行和其他高級功能,例如透明加密。

而且該趨勢已經被多家公有雲廠商認可和支持。比如阿里雲結合 terway CNI 和 Cilium,使用cilium提供Kubernetes的Service和NetworkPolicy實現。

轉自:https://zhuanlan.zhihu.com/p/337806843


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM