您好,登錄后才能下訂單哦!
本篇文章為大家展示了k8s-service中iptable cluster ip實現原理,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
在這里我們主要介紹集群內的負載均衡。對于k8s集群中的服務是需要相互訪問的,一般我們都會為之創建相應的service,對于集群內部的service類型我們一般設置成cluster ip。對于一個cluster ip后面會關聯多個endpoints,也就是實際的pod。對于cluster ip的訪問,也就是實現了對cluster ip關聯的多個endpoints訪問。關于cluster ip和endpoints的流量負載均衡,一般有iptable方式和ipvs方式,在以前文章里有所介紹。這里我們主要以實際例子來介紹iptable的實現方式。另外cluster ip是虛擬ip,言外之意就是這個ip沒有和任何device綁定,所以當你對這個ip進行例如ping或者traceroute命令的時候是不會得到應答的。
查看部署的nginx application的service,我們可以看到:
這個service為cluster ip類型
cluster ip為10.254.226.173
這個cluster ip關聯了2個endpoints:10.1.27.4:80和10.1.79.3:80
kubectl describe service service-nginx-app -n default
查看host network namespace iptable的nat表:
iptables -nvL -t nat
對于PREROUTING chain中,所有的流量都走到了KUBE-SERVICES這個target中。請注意PREROUTING chain是流量到達之后的第一個入口。試想我們在pod里運行命令curl http://10.254.226.173,根據以前文章里介紹的容器內部路由表,數據包應該是這樣的流動:
在pod中,根據路由表發現cluster ip(10.254.226)走默認路由,選擇了默認網關。
在pod中,默認網關的ip地址就是宿主netwok namespace的docker0的ip地址,并且默認網關為直連路由。
在pod中,根據路由表,使用eth0 device發送數據,根據以前文章,eth0本質是veth pair在pod network namespace的一端,另一端attach在宿主netwok namespace的docker0 bridge上。
根據以前文章介紹的veth pair,數據從pod network namespace的一端發出,進入到了attached到docker0 bridge上的另一端。
docker0 bridge收到數據之后,自然就來到了host network namesapce的PREROUTING chain。
查看KUBE-SERVICES target:
iptables -nvL -t nat | grep KUBE-SVC
在KUBE-SERVICES target中我們可以看到目標地址為cluster ip10.254.226.173的匹配target為KUBE-SVC-ETZVW7ENORYJBYB4。
查看KUBE-SVC-ETZVW7ENORYJBYB4 target:
iptables -nvL -t nat
在KUBE-SVC-ETZVW7ENORYJBYB4 target中我們可以看到:
有2個target,分別是KUBE-SEP-L6A5J2X5SCQGCA7Z和KUBE-SEP-U7JQ3R4SRIDMQ4UH
在KUBE-SEP-L6A5J2X5SCQGCA7Z中有statistic mode random probability 0.5
對于statistic mode random probability 0.5是利用了iptable內核隨機模塊,隨機比率為0.5,也就是50%。
所以對于上面的意思是有一半的隨機比率進入到KUBE-SEP-L6A5J2X5SCQGCA7Z target當中,那么自然另一個target的隨機比率也是一半了。
由此可見,是通過隨機模塊來均勻的實現負載均衡的。
查看KUBE-SEP-L6A5J2X5SCQGCA7Z和UBE-SEP-L6A5J2X5SCQGCA7Z target:
iptables -nvL -t nat
在這2個target中我們可以看到:
分別做了MASQ操作,當然這個應該是出站engress流量(限定了source ip),不是我們的入站ingress流量。
做了DNAT操作,把原來的cluster ip給DANT轉換成了pod的ip 10.1.27.4和10.1.79.3。把原來的port轉換成了80 port
經過這個一系列iptable的target我們的原始請求10.254.226.173:80就變成了10.1.27.4:80或者10.1.79.3:80,而且兩者轉變的機率各是50%。
根據iptable,經過PREROUTING chain發現DNAT之后的10.1.27.4或者10.1.79.3不是本地的ip(肯定不是,因為這兩個ip是pod的ip,當然不會在host的network namespace里)。所以就走到了Forwarding chain中,根據host network namespace的路由表來決定下一跳地址。
所以綜合上面的例子,對于ipable方式的k8s集群內cluster-ip類型的service總結為:
流量從pod network namespace中走到host netwok namespace的docker0中。
在host netwok namespace的PREROUTING chain中會經過一系列target。
在這些target里根據iptable內核隨機模塊來實現匹配endpoint target,隨機比率為均勻分配,實現均勻的負載均衡。
在endpoint target里實現了DNAT,也就是將目標地址cluster ip轉化為實際的pod的ip。
cluster ip是虛擬ip,不會和任何device綁定。
負載均衡為內核實現,使用均勻負載均衡,不可以有自定義的負載均衡算法。
需要host開啟路由轉發功能(net.ipv4.ip_forward = 1)。
數據包在host netwok namespace中經過轉換以及DNAT之后,由host network namespace的路由表來決定下一跳地址。
上述內容就是k8s-service中iptable cluster ip實現原理,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。