本文共 6318 字,大约阅读时间需要 21 分钟。
在容器服务的集群中,默认情况下的flannel会对POD访问到非POD的网段做SNAT,以确保POD到集群外部的资源访问,但在某些情况下,比如在容器服务的VPC集群中,POD到集群外部的资源是直接可以访问的,这时我们就可以自己定义节点上的SNAT规则,而达到直接用容器IP访问VPC内其他服务。
我们使用kubernetes 官方项目中的 组件来实现对某些网段不做SNAT的需求,部署方式如下:
curl -L -O http://acs-public.oss-cn-hangzhou.aliyuncs.com/kubernetes/network/ip-masq-agent.yaml # 下载ip-masq-agent的配置文件vim ip-masq-agent.yaml # 修改其中的nonMasqueradeCIDRs的配置增加或者删除不需要做SNAT的网段,并保存kubectl apply -f ip-masq-agent.yaml # 使配置生效
然后我们使用如下命令判断ip-masq-agent
都已正常运行:
# kubectl get pod -n kube-system -o wide | grep ip-masq-agentip-masq-agent-557qt 1/1 Running 0 30mip-masq-agent-dtzds 1/1 Running 0 30mip-masq-agent-f6kb6 1/1 Running 0 30mip-masq-agent-qmkgl 1/1 Running 0 30mip-masq-agent-rtkv8 1/1 Running 0 30m
在配置好ip-masq-agent组件后,还是没有起到作用的,因为默认情况下容器服务使用flannel
的网络插件,我们下面也将说明如何配置关闭掉flannel
的SNAT
的功能:
1. 修改CNI的配置:
kubectl edit configmap kube-flannel-cfg -n kube-system
打开修改编辑器后,修改其中的cni-config.json的内容,在其中添加两处"ipMasq: false"的配置,修改如下:
cni-conf.json: | { "name": "cb0", "type": "flannel", "ipMasq": false, "delegate": { "ipMasq": false, "isDefaultGateway": true } }
然后保存修改退出编辑器。
2. 修改flannel daemonset的配置:
# kubectl edit ds kube-flannel-ds -n kube-system
打开修改编辑器后,修改flannel daemonset中kube-flannel容器的配置中的command,删除掉其中的--ip-masq
,然后保存,修改后如下:
containers: - command: - /opt/bin/flanneld - --kube-subnet-mgr
然后保存修改退出编辑器。
3. 使修改生效:
因为kubernetes的daemonset配置后不会自动重新创建,需要手动重新创建flannel的pod,通过kubectl
手动删除掉每个节点上的flannel-ds
的pod使其重新创建:
# kubectl get pod -o wide -n kube-system | grep kube-flannel-dskube-flannel-ds-5tbjt 2/2 Running 4 6d 192.168.193.159 cn-hangzhou.i-bp1e5terjg0bgppqy6j3kube-flannel-ds-6mgjm 2/2 Running 13 6d 192.168.193.156 cn-hangzhou.i-bp1im9citpwp20zebrcrkube-flannel-ds-df9l9 2/2 Running 9 6d 192.168.193.155 cn-hangzhou.i-bp1j1j7011icxiaz0miukube-flannel-ds-qdjhz 2/2 Running 6 6d 192.168.193.158 cn-hangzhou.i-bp1e5terjg0bgppqy6j4kube-flannel-ds-xdkpv 2/2 Running 20 6d 192.168.193.157 cn-hangzhou.i-bp1d7nsqol0apr1thvb7# kubectl get pod -o wide -n kube-system | grep kube-flannel-ds | awk '{print $1}' |xargs kubectl delete -n kube-system podpod "kube-flannel-ds-5tbjt" deletedpod "kube-flannel-ds-6mgjm" deletedpod "kube-flannel-ds-df9l9" deletedpod "kube-flannel-ds-qdjhz" deletedpod "kube-flannel-ds-xdkpv" deleted# kubectl get pod -o wide -n kube-system | grep kube-flannel-ds # 等待kube-flannel-ds重建完成kubectl get pod -o wide -n kube-system | grep kube-flannel-dskube-flannel-ds-c2pvx 2/2 Running 0 40s 192.168.193.156 cn-hangzhou.i-bp1im9citpwp20zebrcrkube-flannel-ds-htkmt 2/2 Running 0 30s 192.168.193.157 cn-hangzhou.i-bp1d7nsqol0apr1thvb7kube-flannel-ds-k6pfq 2/2 Running 0 20s 192.168.193.155 cn-hangzhou.i-bp1j1j7011icxiaz0miukube-flannel-ds-p6tzx 2/2 Running 0 36s 192.168.193.158 cn-hangzhou.i-bp1e5terjg0bgppqy6j4kube-flannel-ds-sz5zg 2/2 Running 0 8s 192.168.193.159 cn-hangzhou.i-bp1e5terjg0bgppqy6j3
这样flannel就被配置为了不会创建SNAT的规则了。
4. 到每个节点上清理之前flannel创建的SNAT的规则:
# iptables -t nat --line-numbers -vnL POSTROUTING # 查看flannel创建的SNAT规则Chain POSTROUTING (policy ACCEPT 4 packets, 240 bytes)num pkts bytes target prot opt in out source destination1 14M 814M KUBE-POSTROUTING all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */2 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/03 5468K 328M RETURN all -- * * 172.16.0.0/16 172.16.0.0/164 209 12540 MASQUERADE all -- * * 172.16.0.0/16 !224.0.0.0/45 0 0 RETURN all -- * * !172.16.0.0/16 172.16.2.0/246 4364K 262M MASQUERADE all -- * * !172.16.0.0/16 172.16.0.0/167 481 29926 IP-MASQ-AGENT all -- * * 0.0.0.0/0 0.0.0.0/0 /* ip-masq-agent: ensure nat POSTROUTING directs all non-LOCAL destination traffic to our custom IP-MASQ-AGENT chain */ ADDRTYPE match dst-type !LOCAL
在上面这个命令中可以看到我们部署的ip-masq-agent
的规则已经加到最后了,然后我们需要移除掉flannel
添加的集群网段的4条规则,我们这个集群中的集群POD网段是172.16.0.0/16
,这个需要根据您的集群选择的网段进行判断,所以我们这个集群中的flannel
添加的规则是序号3~6这4条。
在机器重启时会重新生成iptables,我们可以重启下需要生效的节点,就会清理掉之前的iptables了,如果不希望影响运行中的服务,也可以通过iptables命令手动删除掉这4条多余的iptables规则:
# iptables -t nat -D POSTROUTING 6# iptables -t nat -D POSTROUTING 5# iptables -t nat -D POSTROUTING 4# iptables -t nat -D POSTROUTING 3
通过kubectl run启动一个测试容器,并指定我们修改好的一个节点:
# kubectl run -it --rm --image registry.aliyuncs.com/wangbs/netdia --overrides='{ "apiVersion": "extensions/v1beta1", "spec": { "nodeName": "cn-hangzhou.i-bp1e5terjg0bgppqy6j4"}}' test/ # ping 192.168.200.253
然后通过抓包查看POD ping的包就不会再做SNAT了:
# tcpdump -i eth0 -nn -vv host 192.168.200.253tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes18:54:54.430700 IP (tos 0x0, ttl 63, id 33571, offset 0, flags [DF], proto ICMP (1), length 84) 172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 10, length 6418:54:55.430828 IP (tos 0x0, ttl 63, id 33740, offset 0, flags [DF], proto ICMP (1), length 84) 172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 11, length 6418:54:56.430947 IP (tos 0x0, ttl 63, id 33890, offset 0, flags [DF], proto ICMP (1), length 84) 172.16.4.11 > 192.168.200.253: ICMP echo request, id 4096, seq 12, length 64
转载地址:http://yzrnl.baihongyu.com/