1. 程式人生 > >k8s-kube-proxy執行機制分析

k8s-kube-proxy執行機制分析

在每個Node上都會執行一個kube-proxy服務程序,這個程序可以看做service的透明代理和負載均衡器。其核心功能是將某個service的訪問請求轉發到後端的某個Pod上。對每一個TCP型別的service,kube-proxy都會在本地Node上建立一個socketserver來負責接收請求,然後均勻傳送到後端某個Pod埠上。這個過程預設採用Round Robin負載均衡演算法。

此外,service的cluster IP和Nodeport概念是proxy通過Iptables的NAT轉換實現的。proxy在執行過程中動態創建於service相關的Iptables規則,這些規則實現了Cluster IP及NodePort的請求流量重定向到proxy程序上對應服務的代理埠的功能。

也就是說,訪問service的請求,都會被節點機的Iptables規則重定向到kube-proxy監聽service服務代理埠,那麼proxy如何選擇後端的pod呢?

目前proxy只支援round robin演算法,該演算法是輪詢查詢。

接下來深入分析proxy實現細節:

kube-proxy通過查詢和監聽API server中service和endpoint的變化。為每個service都建立了一個服務代理物件。並自動同步。服務代理物件是proxy程式內部的一種資料結構,它包括一個用於監聽此服務請求的socketserver,socketserver的埠是隨機選擇的一個本地空閒埠。此外,kube-proxy內部也建立了一個負載均衡器-LoadBalancer,LoadBalancer上儲存了service到對應的後端endpoint列表的動態轉發路由表。而具體的路由選擇則取決於Round Robin負載均衡演算法及service的session會話保持這兩個特性。

針對發生變化的service列表,proxy會逐個處理,下面是具體處理流程:

1.如果該service沒有設定Cluster IP,則不做任何處理,否則獲取該service的所有埠定義列表(spec.ports域)

2.逐個讀取服務埠定義列表中的埠資訊,根據埠名稱,service名稱和namespace判斷本地是否已經存在對應的服務代理物件,如果不存在則新建,若存在並且service埠被修改過,則先刪除Iptables中和該service埠相關的規則,關閉服務代理物件,然後走新建流程,也就是為該service埠分配服務代理物件併為建立相關的Iptables規則。

3.更新負載均衡器元件中對應service的轉發地址列表,對於新建的service,確定轉發時的會話保持策略。

4.對於已刪除的service則進行清理。

proxy在啟動時和堅挺到service或endpoint變化後,會在本機的Iptables的NAT表中新增4條規則鏈。

a,KUBE-PORTALS-CONTAINER:從容器中通過service Cluster IP和埠號訪問service的請求。

b,KUBE-PORTALS-HOST:從主機通過service Cluster IP和埠號訪問service的請求。

c,KUBE-NODEPORT-CONTAINER:從容器中通過service的NodePort埠號訪問service的請求。

d,KUBE-NODEPORT-HOST:從主機通過service的NodePort埠號訪問service的請求。

此外,kube-proxy在Iptables上為每個service建立由Cluster IP+service埠到kube-proxy所在主機IP+service代理服務所監聽的埠的轉發規則。


可以看到對“redis-master”service的6379埠的訪問將被轉發至物理機的42872埠。而42872埠就是proxy為這個service開啟的隨機本地埠。