疑问:现有两个svc分别是svcA和svcB,各对应一个实例pod,分别是podA和podB,现在podA中访问svcB,podA发出的包的src_ip是podA_ip,dst_ip是svcB_ip,按道理来说podB收到的包的src_ip应该是cni0的ip(抓包看到确实是)
k8s会在两个地方设置mark标记,这两个地方设置的标记在包最后离开主机时会进行一次SNAT把源ip换成节点上的cni0的ip(对应KUBE-POSTROUTING CHAIN中唯一的一条规则
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -m mark --mark 0x4000/0x4000 -j MASQUERADE)
###1.每个svc对应的KUBE-SERVICES CHAN中:如果源地址不是整个pod的网段(包括cni0)就打标记,对应的场景是集群外部client以NodePort的形式访问节点A以访问svc时,节点A上可能并没有目标svc的pod,包从节点A路由到目标pod所在节点时需要做SNAT
###把源ip NAT成cni0的ip,可以防止pod收到包时认为自己是直接访问client,从而tcp握手失败
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.111.118.122/32 -p tcp -m comment --comment "app/sample-metrics-app:web cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.111.118.122/32 -p tcp -m comment --comment "app/sample-metrics-app:web cluster IP" -m tcp --dport 80 -j KUBE-SVC-ZUAJYEXOSE7G7O7F
###2.每个pod对应的KUBE-SEP CHAN中:如果源地址是pod自己的ip就打标记,防止:pod访问自己的svc,经过DNAT后srcip和dstip都是pod ip,pod会觉得是自己访问自己,从而tcp握手失败
-A KUBE-SEP-IG6GZJQ244FAYVBS -s 10.244.0.186/32 -m comment --comment "kube-system/kube-dns:dns" -j KUBE-MARK-MASQ
-A KUBE-SEP-IG6GZJQ244FAYVBS -p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination 10.244.0.186:53