-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
复制代码
我们这个 nginx-service 的 cluster IP 是 10.101.57.97, 所以会走 KUBE-SVC-V2OKYYMBY3REGZOG 链:
这个的意思是到10.101.57.97:80 的 tcp 欣赏会使用 rr(轮询)的方式转发到 10.244.0.27:80,10.244.0.28:80,10.244.0.30:80 这三个 pod 上。Masq:指示 "Masquerading",表现通过 NAT 来处理网络流量。
所以 ipvs 的模式比 iptables 性能高的多,第一因为 ipvs 是轮询选,iptables 是逐条百分比匹配的,这个还是可以担当的。更要命的是第二条,当 pod 频仍变更的时候 service 对应的 endpoint 的 ENDPOINTS 就会增加或者是减少。那么 iptables 对应 service 的全部规则的百分比都会变化,就会导致一个 service 的规则全部要重刷,当 pod 变化太频仍时,会吃掉大量的 CPU。
不是说开启了 ipvs 就不会有 iptables 了,还必要 iptables 的 SNAT 规则来处理返回的数据包。
-A POSTROUTING -m comment --comment "kubernetes postrouting rules" -j KUBE-POSTROUTING
-A KUBE-POSTROUTING -m comment --comment "Kubernetes endpoints dst ip:port, source ip for solving hairpin purpose" -m set --match-set KUBE-LOOP-BACK dst,dst,src -j MASQUERADE
复制代码
-m set --match-set KUBE-LOOP-BACK dst,dst,src 的意思是匹配 KUBE-LOOP-BACK 这个 set,这个 set 里面存放的是 pod 的 ip,这个规则的作用是将数据包的源地址替换为本机的地址,以便数据包可以或许正确返回到客户端。
为什么是 pod ip 而不是 service cluster ip 呢?因为已经通过 ipvs DNAT 过了,所以这里是 pod ip。
root@minikube:/etc/apt# ipset -L|grep -A 15 KUBE-LOOP-BACK
很显着我们的三个 pod 都在这个 set 里面。
-A KUBE-POSTROUTING -m comment --comment "Kubernetes endpoints dst ip:port, source ip for solving hairpin purpose" -m set --match-set KUBE-LOOP-BACK dst,dst,src -j MASQUERADE
这条规则的作用是将数据包的源地址替换为本机的地址,以便数据包可以或许正确返回到客户端。现在我们使用 curl 发出的包目的 ip 是 pod ip了,源 ip 是 node ip。等到数据包返回的时候,kernel 会根据 链路追踪 中的数据记载,会把包的源ip 的pod ip 替换为 serice cluster ip, 目的 ip 从 node ip 替换为我发起哀求的 ip。这样包就能正确返回到客户端了。
References