Kubernetes服務發現之ClusterIP
在ofollow,noindex">《Flannel網路以及在阿里雲下的實現解析》 中說過在Kubernetes中網路中,主要包含兩種IP,分別是Pod IP和Cluster IP。 Pod IP是實際存在於網絡卡之上(如VETH的虛擬網絡卡),而Cluster IP則是一個虛擬的IP地址,該虛擬機器IP由kube-proxy進行維護,kube-proxy目前提供了兩種實現方式,包括預設的ip tables實現以及在K8S 1.8之後開始支援的ipvs實現。文章中以阿里雲Kubernetes叢集為例,從Pod IP的角度介紹了Pod和Pod之間是如何通訊的。這篇文章,筆者將解釋基於ClusterIP的服務發現是個什麼鬼。
基於ClusterIP的服務發現
Kubernetes中服務發現主要通過每個主機上的kube-proxy元件實現,其作用是通過控制iptables將對Service ClusterIP的請求,轉發到後端Endpoints中,剩下就交給容器網路。
以default名稱空間下的nginx svc為例:
$ kubectl get svc --selector app=nginx NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginxClusterIP172.19.0.166<none>80/TCP1m
檢視Service詳情:
$ kubectl describe svc nginx Name:nginx Namespace:default Labels:app=nginx Annotations:<none> Selector:app=nginx Type:ClusterIP IP:172.19.0.166 Port:<unset>80/TCP TargetPort:80/TCP Endpoints:172.16.2.125:80,172.16.2.229:80 Session Affinity:None Events:<none>
上述資訊中可以看出該svc的ClusterIP為172.19.0.166,後端代理了2個Pod例項:172.16.2.125:80,172.16.2.229:80
在任意Node節點中找到flannel例項,檢視iptables資訊:
$ k -n kube-system exec -it kube-flannel-ds-hjlb4 -c kube-flannel -- iptables -S -t nat # 省略輸出 -A KUBE-SERVICES -d 39.96.133.156/32 -p tcp -m comment --comment "default/wrinkled-crocodile-selenium-hub:hub loadbalancer IP" -m tcp --dport 4444 -j KUBE-FW-SI6MMWWVN6LUBWIY -A KUBE-SERVICES ! -s 172.16.0.0/16 -d 172.19.15.240/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ -A KUBE-SERVICES -d 172.19.15.240/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-SVC-4N57TFCL4MD7ZTDA # 省略出書
根據路由轉發規則,從Pod訪問ClusterIP 172.19.0.166的80埠的請求,匹配到轉發規則:
-A KUBE-SERVICES ! -s 172.16.0.0/16 -d 172.19.0.166/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ -A KUBE-SERVICES -d 172.19.0.166/32 -p tcp -m comment --comment "default/nginx: cluster IP" -m tcp --dport 80 -j KUBE-SVC-4N57TFCL4MD7ZTDA
直接跳轉到KUBE-SVC-4N57TFCL4MD7ZTDA:
-A KUBE-SVC-4N57TFCL4MD7ZTDA -m comment --comment "default/nginx:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-ZWDBLNQ3XRBMUP33 -A KUBE-SVC-4N57TFCL4MD7ZTDA -m comment --comment "default/nginx:" -j KUBE-SEP-H2XFNPZ6MLIHFOVM
通過iptables的–probability的特性,使連線有50%的概率進入到KUBE-SEP-ZWDBLNQ3XRBMUP33,KUBE-SEP-H2XFNPZ6MLIHFOVM的作用是把請求轉發到172.16.2.125:80:
-A KUBE-SEP-ZWDBLNQ3XRBMUP33 -s 172.16.2.125/32 -m comment --comment "default/nginx:" -j KUBE-MARK-MASQ -A KUBE-SEP-ZWDBLNQ3XRBMUP33 -p tcp -m comment --comment "default/nginx:" -m tcp -j DNAT --to-destination 172.16.2.125:80
另外50%的請求,則可能進入到KUBE-SEP-QKRDMLY5MWSFYSJG,同理,該規則的作用是把請求轉發到172.16.2.229:80:
-A KUBE-SEP-H2XFNPZ6MLIHFOVM -s 172.16.2.229/32 -m comment --comment "default/nginx:" -j KUBE-MARK-MASQ -A KUBE-SEP-H2XFNPZ6MLIHFOVM -p tcp -m comment --comment "default/nginx:" -m tcp -j DNAT --to-destination 172.16.2.229:80
Kubernetes通過iptables規則,將對ClusterIP的訪問,負載到後端的PodID,剩下的事情,就是在文章《Flannel網路以及在阿里雲下的實現解析》 介紹的部分了