天天看點

Kubernetes學習筆記之kube-proxy service實作原理

Kubernetes學習筆記之kube-proxy service實作原理

我們生産k8s對外暴露服務有多種方式,其中一種使用external-ips clusterip service ClusterIP Service方式對外暴露服務,kube-proxy使用iptables mode。這樣external ips可以指定固定幾台worker節點的IP位址(worker節點服務已經被驅逐,作為流量轉發節點不作為計算節點),并作為lvs vip下的rs來負載均衡。根據vip:port來通路服務,并且根據port不同來區分業務。相比于NodePort Service那樣可以通過所有worker節點的node_ip:port來通路更高效,也更容易落地生産。但是,traffic packet是怎麼根據叢集外worker節點的node_ip:port或者叢集内cluster_ip:port通路方式找到pod ip的?

并且,我們生産k8s使用calico來作為cni插件,采用 Peered with TOR (Top of Rack) routers方式部署,每一個worker node和其置頂交換機建立bgp peer配對,置頂交換機會繼續和上層核心交換機建立bgp peer配對,這樣可以保證pod ip在公司内網可以直接被通路。

但是,traffic packet知道了pod ip,又是怎麼跳到pod的呢?

以上問題可以歸并為一個問題:資料包是怎麼一步步跳轉到pod的?很長時間以來,一直在思考這些問題。

實際上答案很簡單:通路業務服務vip:port或者說node_ip:port,當packet到達node_ip所在機器如worker A節點時,會根據iptable rules一步步找到pod ip;找到了pod ip後,由于使用calico bgp部署方式,核心交換機和置頂交換機都有該pod ip所在的ip段的路由,packet最後會跳轉到某一個worker節點比如worker B,而worker B上有calico早就寫好的路由規則route和虛拟網卡virtual interface,再根據veth pair進而由host network namespace跳轉到pod network namespace,進而跳轉到對應的pod。

首先可以本地部署個k8s叢集模拟測試下,這裡使用 install minikube with calico :

然後部署個業務pod,這裡使用nginx為例,副本數為2,并建立ClusterIP Service with ExternalIPs和NodePort Service:

部署完成後,就可以通過 ExternalIP ClusterIP Service或者NodePort Service兩種方式通路業務服務:

當資料包通過node_ip:port或者cluster_ip:port通路服務時,會在目前worker節點被核心DNAT(Destination Network Address Translation)為pod ip,反向packet又會被SNAT(Source Network Address Translation)。這裡借用calico官網的非常生動的兩張圖說明About Kubernetes Services :

cluster-ip service 通路流程:

Kubernetes學習筆記之kube-proxy service實作原理

node-port service 通路流程:

Kubernetes學習筆記之kube-proxy service實作原理

由于我們生産k8s的kube-proxy使用iptables mode,是以這些snat/dnat規則是kube-proxy程序通過調用iptables指令來實作的。iptables使用各種chain來管理大量的iptable rules,主要是五鍊四表,五鍊包括:prerouting/input/output/forward/postrouting chain,四表包括:

raw/mangle/nat/filter table,同時也可以使用者自定義chain。資料包packet進過核心時經過五鍊四表流程圖如下:

Kubernetes學習筆記之kube-proxy service實作原理

而kube-proxy程序會在nat table内自定義KUBE-SERVICES chain,并在PREROUTING内生效,可以通過指令檢視,然後在檢視KUBE-SERVICES chain中的規則:

可以看到,如果在叢集内通過cluster_ip:port即10.196.52.1:8088,或者在叢集外通過external_ip:port即192.168.64.57:8088方式通路服務,都會在核心裡比對到 KUBE-SVC-JKOCBQALQGD3X3RT chain的規則,這個對應nginx-demo-1 service;如果是在叢集内通過cluster_ip:port即10.196.89.31:8089,或者叢集外通過nodeport_ip:port即192.168.64.57:31755方式通路服務,會比對到 KUBE-SVC-6JCCLZMUQSW27LLD chain的規則,這個對應nginx-demo-2 service:

Kubernetes學習筆記之kube-proxy service實作原理

然後繼續查找 KUBE-SVC-JKOCBQALQGD3X3RT chain和 KUBE-SVC-6JCCLZMUQSW27LLD chain的規則,發現每一個 KUBE-SVC-xxx 都會跳轉到 KUBE-SEP-xxx chain上,并且因為pod副本數是2,這裡就會有兩個 KUBE-SEP-xxx chain,并且以50\%機率跳轉到任何一個 KUBE-SEP-xxx chain,即rr(round robin)負載均衡算法,這裡kube-proxy使用iptables statistic module來設定的,最後就會跳轉到pod ip 10.217.120.72:80(這裡假設通路這個pod)。總之,經過kube-proxy調用iptables指令,根據service/endpoint設定對應的chain,最終一步步跳轉到pod ip,進而資料包packet下一跳是該pod ip:

Kubernetes學習筆記之kube-proxy service實作原理

總之,不管是通過cluster_ip:port、external_ip:port還是node_ip:port方式通路業務服務,packet通過kube-proxy程序自定義的各種chain找到了下一跳pod ip位址。

但是,packet如何知道這個pod ip在哪個節點呢?

上文已經說過,我們部署calico方式可以保證pod ip在叢集外是可以被路由的,這是因為交換機上會有node level的路由規則,在交換機上執行 dis bgp routing-table會有類似如下路由規則。表示如果通路 10.20.30.40/26 pod網段下一跳是worker B的IP位址。這些路由規則是部署在每一個worker節點的bird程序(bgp client)分發的,交換機通過BGP學習來的:

是以,packet在知道了pod ip 10.217.120.72:80 後(這裡假設通路了pod nginx-demo-1-7f67f8bdd8-fxptt),很容易找到了worker B節點,本文章示例即是minikube節點。檢視該節點的路由表和網卡,找到了在host network namespace這一側是網卡 cali1087c975dd9,編号是13,這個編号很重要,可以通過編号知道這個veth pair的另一端在哪個pod network namespace。發現 pod nginx-demo-1-7f67f8bdd8-fxptt 的網卡eth0就是veth pair的另一端,并且編号也是13:

Kubernetes學習筆記之kube-proxy service實作原理

以上路由表規則和虛拟網卡是calico cni的calico network plugin建立的,而pod ip以及每一個node的pod ip cidr網段都是由calico ipam plugin建立管理的,并且這些資料會寫入calico datastore内。至于calico network plugin和calico ipam plugin具體是如何做的,後續有時間再記錄學習。

5. 總結

不管叢集内cluster_ip:port,還是叢集外external_ip:port或node_ip:port方式通路服務,都是會通過kube-proxy程序設定的各種iptables rules後跳轉到對應的pod ip,然後借助于calico bgp部署方式跳轉到目标pod所在worker節點,并通過該節點的路由表和虛拟網卡,找到對應的那個pod,packet由host network namespace再跳轉到pod network namespace。一直以來的有關service和calico疑問也算是搞明白了。

https://docs.projectcalico.org/about/about-kubernetes-service

https://mp.weixin.qq.com/s/bYZJ1ipx7iBPw6JXiZ3Qu

https://mp.weixin.qq.com/s/oaW87xLnlUYYrwVjBnqee

https://mp.weixin.qq.com/s/RziLRPYqNoQEQuncm47rHg

文章轉載:360雲計算

(版權歸原作者所有,侵删)