實驗環境:calico版本:v0.23,kubernetes版本:1.35
kubernetes網絡使用calico,當namespace使用以下命令配置隔離policy的後:
kubectl annotate ns <namespace> "net.beta.kubernetes.io/network-policy={\"ingress\": {\"isolation\": \"DefaultDeny\"}}"
問題:跨主機node訪問pod被隔離了。但是kubernetes中外網訪問service需要node節點可以訪問所有pod。
通過分析calico創建的iptables,node跨主機訪問pod進過FORWARD鏈的時候被drop掉了。創建namespace的時候,calico默認會創建felix-p-_e9d3a9f50c6dd3a-i felix-p-k8s_ns.net1-sub1-i 這兩條鏈,第一條鏈會把非pod的流量給drop掉。
Chain felix-to-528799797b0 (1 references)
pkts bytes target prot opt in out source destination
0 0 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK and 0xfeffffff
0 0 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 /* Start of tier k8s-network-policy */ MARK and 0xfdffffff
0 0 felix-p-_e9d3a9f50c6dd3a-i all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x2000000
0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x1000000/0x1000000 /* Return if policy accepted */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0/0x2000000 /* Drop if no policy in tier passed */
0 0 felix-p-k8s_ns.net1-sub1-i all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x1000000/0x1000000 /* Profile accepted packet */
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 /* Packet did not match any profile (endpoint eth0) */
可以通過以下命令給k8s默認的ns的profile添加rule
./calicoctl profile k8s_ns.net1-sub1 rule add inbound --at=1 allow from cidr 10.10.102.0/24
查看iptables發現該rule被添加到了第二條鏈。
Chain felix-p-k8s_ns.net1-sub1-i (1 references)
pkts bytes target prot opt in out source destination
0 0 MARK all -- * * 10.10.102.0/24 0.0.0.0/0 MARK or 0x1000000
0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x1000000/0x1000000
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
通過手動刪除第一條鏈發現跨主機的node流量可以訪問pod。