摘要:當通過訪問應用時,流量經由表中的規則鏈處理后,跳轉到子鏈,而此鏈包含了對具體處理的規則。再次防火墻規則,發現經由的模塊,以方式均衡的分發流量,也即負載均衡模式為輪訓。
前言
? 在K8S集群內部,應用常使用Service互訪,那么,了解Service技術優缺點將有利于應用規劃與部署,鑒于此,本文將通過簡單案例以探索Cluster-Ip類型Service服務的利弊。
? 為便于講解,我們先創建如下應用及Service服務:
# kubectl run --image=nginx nginx-web-1 --image-pull-policy="IfNotPresent" # kubectl expose deployment nginx-web-1 --port=80 --target-port=80Service探索
? 作者的K8S環境是1.9版本,其Service內部服務由Kube-Proxy1提供,且默認用iptables技術實現,故本文探索K8S集群Service技術,即研究iptables在K8S上的技術實現。
Service Route(服務路由)? 如下可知,通過nginx-web-1服務可實際訪問到后端pod:
# nginx pod ip地址: # kubectl describe pod nginx-web-1-fb8d45f5f-dcbtt | grep "IP" IP: 10.129.1.22 # Service服務,通過172.30.132.253:80則實際訪問到10.129.1.22:80 # kubectl describe svc nginx-web-1 ... Type: ClusterIP IP: 172.30.132.253 Port:80/TCP TargetPort: 80/TCP Endpoints: 10.129.1.22:80 Session Affinity: None ... # 重置nginx web頁面: # kubectl exec -it nginx-web-1-fb8d45f5f-dcbtt -- sh -c "echo hello>/usr/share/nginx/html/index.html" # curl 10.129.1.22 hello # curl 172.30.132.253 hello
? Service服務分配的CLUSTER-IP以及監聽的端口均虛擬的,即在K8S集群節點上執行ip a與netstat -an命令均無法找到,其實際上,IP與Port是由iptables配置在每K8S節點上的。在節點上執行如下命令可找到此Service相關的iptables配置,簡析如下:
當通過Service服務IP:172.30.132.253:80訪問時,匹配第3條規則鏈(KUBE-SERVICES)后,跳轉到第4條子鏈(KUBE-SVC-...)上;
第4條子鏈做簡單注釋后,繼而跳轉到第1、2規則鏈(KUBE-SEP-...)上;
當源Pod通過Service訪問自身時,匹配第1條規則,繼而跳轉到KUBE-MARK-MASQ鏈中;
匹配到第2條規則,此時通過DNAT被重定向到后端Pod:108.29.1.22:80。
# iptables-save | grep nginx-web-1 -A KUBE-SEP-UWNFTKZFYWNNNTK7 -s 10.129.1.22/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-UWNFTKZFYWNNNTK7 -p tcp -m comment --comment "demo/nginx-web-1:" -m tcp -j DNAT --to-destination 10.129.1.22:80 -A KUBE-SERVICES -d 172.30.132.253/32 -p tcp -m comment --comment "demo/nginx-web-1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-SNP24T7IBBNZDJ76 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -j KUBE-SEP-UWNFTKZFYWNNNTK7
? 詳細分析iptables規則,執行iptables-save命令可發現nat的PREROUTING與OUTPUT鏈中均有KUBE-SERVICES規則鏈,且處于第一順位。
*nat -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES -A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
當通過Service訪問應用時,流量經由nat表中的PREROUTING規則鏈處理后,跳轉到KUBE-SERVICES子鏈,而此鏈包含了對具體Service處理的規則。如下所示,訪問172.30.132.253:80將被跳轉到KUBE-SEP-...子規則鏈中。
-A KUBE-SERVICES -d 172.30.132.253/32 -p tcp -m comment --comment "demo/nginx-web-1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-SNP24T7IBBNZDJ76 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -j KUBE-SEP-UWNFTKZFYWNNNTK7
? 如下所示,KUBE-SEP-...子鏈存在兩條規則:
第1條規則:Pod通過Service訪問自身時匹配,此規則僅作標記(MARK)處理;
第2條規則:通過DNAT重定向到后端Pod實例上,至此,通過Service最終將流量導向到后端實例上;
-A KUBE-SEP-UWNFTKZFYWNNNTK7 -s 10.129.1.22/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-UWNFTKZFYWNNNTK7 -p tcp -m comment --comment "demo/nginx-web-1:" -m tcp -j DNAT --to-destination 10.129.1.22:80 -A KUBE-MARK-MASQ -j MARK --set-xmark 0x1/0x1Loadbalance(負載均衡)
? 執行如下命令將Deployment擴展為3個Pod后,繼而再觀察Service負載均衡方面的技術或問題。
# kubectl scale deploy/nginx-web-1 --replicas=3
? 再次dump防火墻規則,發現Service經由iptables的statistic模塊,以random方式均衡的分發流量,也即負載均衡模式為輪訓。
存在3條DNAT與KUBE-MARK-MASQ規則,分別對應3個后端Pod實地址;
KUBE-SERVICES鏈中存在3條子鏈,除最后一條KUBE-SVC-...子鏈外,其余子鏈使用模塊statistic的random模式做流量分割或負載均衡:第1條KUBE-SVC-...應用33%流量,第2條KUBE-SVC-...規則應用剩余的50%流量,第3條KUBE-SVC-...規則應用最后的流量。
# iptables-save | grep nginx-web-1 -A KUBE-SEP-BI762VOIAZZWU5S7 -s 10.129.1.27/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-BI762VOIAZZWU5S7 -p tcp -m comment --comment "demo/nginx-web-1:" -m tcp -j DNAT --to-destination 10.129.1.27:80 -A KUBE-SEP-CDQIKEVSTA766BRK -s 10.129.1.28/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-CDQIKEVSTA766BRK -p tcp -m comment --comment "demo/nginx-web-1:" -m tcp -j DNAT --to-destination 10.129.1.28:80 -A KUBE-SEP-W5HTO42ZVNHJQWBG -s 10.129.3.57/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-W5HTO42ZVNHJQWBG -p tcp -m comment --comment "demo/nginx-web-1:" -m tcp -j DNAT --to-destination 10.129.3.57:80 -A KUBE-SERVICES -d 172.30.132.253/32 -p tcp -m comment --comment "demo/nginx-web-1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-SNP24T7IBBNZDJ76 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-BI762VOIAZZWU5S7 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-CDQIKEVSTA766BRK -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -j KUBE-SEP-W5HTO42ZVNHJQWBGSession Affinity(會話保持)
? 如下所示,調整Service服務,打開會話保持功能,并設置會話保持期限為3小時(PS:若不設置,則默認是3小時):
# kubectl edit svc nginx-web-1 ... sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 10800 ...
? 繼續觀察iptables實現,發現在原有基礎上,iptables規則中添加了recent模塊,此模塊被用于會話保持功能,故kube-proxy通過在iptables中結合statistic與recent模塊,實現了Service的輪訓負載均衡與會話保持功能。
通過Service服務訪問應用,封包進入KUBE-SERVICES規則鏈,并跳轉到KUBE-SVC-...子鏈中;
在KUBE-SVC-SNP...子鏈中,recent位于statistic模塊前,故而,有如下情況出現:
當客戶端第一次訪問Service時,KUBE-SVC-...子鏈中的規則(-m recent --rcheck --seconds 10800 --reap ...--rsource)池中未記錄客戶端地址,故封包匹配失敗,從而封包被后續的statistic模塊規則處理后,均衡分發到KUBE-SEP-...子鏈中,此鏈中使用recent模塊的--set參數將客戶源地址記錄到規則池后,DNAT到實際后端實例上;
KUBE-SVC-...子鏈中recent模塊配置了源地址記錄期限,若客戶端3(--seconds 10800 --reap)小時內未訪問服務,則recent規則池中的客戶端記錄將被移除,此時客戶端再次訪問Service就如同第一次訪問Service一樣;
當客戶端在3小時內再次訪問Service時,匹配KUBE-SVC-...子鏈中的recent模塊規則后,跳轉到KUBE-SEP子鏈,其規則中recent模塊--set參數將更新規則池中的Record TTL,而后DNAT到實際后端實例上;
# iptables-save | grep nginx-web-1 -A KUBE-SEP-BI762VOIAZZWU5S7 -s 10.129.1.27/32 -m comment --comment "demo/nginx-web-1:" -j KUBE-MARK-MASQ -A KUBE-SEP-BI762VOIAZZWU5S7 -p tcp -m comment --comment "demo/nginx-web-1:" -m recent --set --name KUBE-SEP-BI762VOIAZZWU5S7 --mask 255.255.255.255 --rsource -m tcp -j DNAT --to-destination 10.129.1.27:80 # 省略2條類似的KUBE-SEP規則 ... -A KUBE-SERVICES -d 172.30.132.253/32 -p tcp -m comment --comment "demo/nginx-web-1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-SNP24T7IBBNZDJ76 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -m recent --rcheck --seconds 10800 --reap --name KUBE-SEP-BI762VOIAZZWU5S7 --mask 255.255.255.255 --rsource -j KUBE-SEP-BI762VOIAZZWU5S7 # 省略2條類似的KUBE-SVC規則 ... -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-BI762VOIAZZWU5S7 -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-CDQIKEVSTA766BRK -A KUBE-SVC-SNP24T7IBBNZDJ76 -m comment --comment "demo/nginx-web-1:" -j KUBE-SEP-W5HTO42ZVNHJQWBG總結
? K8S中的Service服務可提供負載均衡及會話保持功能,其通過Linux內核netfilter模塊來配置iptables實現,網絡封包在內核中流轉,且規則匹配很少,故效率非常高;而Service負載均衡分發比較薄弱,其通過statistic的random規則實現輪訓分發,無法實現復雜的如最小鏈接分發方式,鑒于此,K8S 1.9后續版本調整了kube-proxy服務,其可通過ipvs實現Service負載均衡功能。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/33005.html
摘要:當通過訪問應用時,流量經由表中的規則鏈處理后,跳轉到子鏈,而此鏈包含了對具體處理的規則。再次防火墻規則,發現經由的模塊,以方式均衡的分發流量,也即負載均衡模式為輪訓。 前言 ? 在K8S集群內部,應用常使用Service互訪,那么,了解Service技術優缺點將有利于應用規劃與部署,鑒于此,本文將通過簡單案例以探索Cluster-Ip類型Service服務的利弊。 ? 為便...
摘要:后端代理之前的文章部署最后的測試部分,創建了一組及服務來驗證業務,繼續以這個例子來說明集群中已經有如下一組都帶有標簽,對外暴露端口,訪問路徑會返回主機名。請求代理轉發是一個虛擬的地址,并不是某張網卡的真實地址。 為什么需要service Kubernetes可以方便的為容器應用提供了一個持續運行且方便擴展的環境,但是,應用最終是要被用戶或其他應用訪問、調用的。要訪問應用pod,就會有以...
摘要:中暴露服務訪問自己實現了一個,它本質上是包裝了,在真正創建負載均衡器上它會調用來創建自身的。 Kubernetes概述 最近的一年,kubernetes的發展如此閃耀,正被越來越多的公司采納用于生產環境的實踐。同時,我們可以在最著名的開發者問答社區StackOverflow上看到k8s的問題數量的增長曲線(2015.5-2016.5),開發者是用腳投票的,從這一點看也無疑證明了k8s的...
摘要:中暴露服務訪問自己實現了一個,它本質上是包裝了,在真正創建負載均衡器上它會調用來創建自身的。 Kubernetes概述 最近的一年,kubernetes的發展如此閃耀,正被越來越多的公司采納用于生產環境的實踐。同時,我們可以在最著名的開發者問答社區StackOverflow上看到k8s的問題數量的增長曲線(2015.5-2016.5),開發者是用腳投票的,從這一點看也無疑證明了k8s的...
閱讀 3570·2023-04-25 14:20
閱讀 1186·2021-09-10 10:51
閱讀 1149·2019-08-30 15:53
閱讀 454·2019-08-30 15:43
閱讀 2312·2019-08-30 14:13
閱讀 2790·2019-08-30 12:45
閱讀 1202·2019-08-29 16:18
閱讀 1159·2019-08-29 16:12