背景
在一次测试中,发现某个依赖外部网络的容器服务存在异常,于是开始定位具体根因
当然首先要保证其宿主机的连通性能符合自身的要求,首先验证一下宿主机
1 2
| dig www.baidu.com ping www.baidu.com
|
排查过程
1、验证容器到宿主机连通性,查看所在docker网络中ipam划分的网络信息,ping测试到本容器网段网关、宿主机IP连通性,验证可达。
1 2 3 4
| docker inspect my_network docker exec -it my_container bash ping my_gateway_ip ping my_host_ip
|
2、查看容器网络分配情况,关注ipam有无冲突,查看 自身容器IP 与 自身容器网络id前12 在iptables中的策略放行情况。
1 2
| iptables-save | grep my_container_ip iptables-save | grep my_network_ip_slice12
|
发现不在当前iptabels策略中,于是重启对应容器
为什么是网络ID的前12项:docker开发时的命名设计如此,在创建bridge后获取到bridge id,slice出前12并且append到br-就组成了iptables、iplink的命名项。
例如:👇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| # 查看网络ID [root@vme50 ~]# docker inspect my_network [ { "Name": "adam_default", "Id": "a89835dc6a34d6ab612170947c7d46a54022a6fb58fcbc138fd8698047da026b", ... } ]
# 查看docker是否将容器网络id(br-a89835dc6a34)添加至iptables规则 [root@vme50 ~]# docker restart my_container [root@vme50 ~]# iptables-save | grep br-a89835dc6a34 -A POSTROUTING -s 23.254.0.32/28 ! -o br-a89835dc6a34 -j MASQUERADE -A DOCKER -i br-a89835dc6a34 -j RETURN -A DOCKER ! -i br-a89835dc6a34 -p tcp -m tcp --dport 9998 -j DNAT --to-destination 23.254.0.34:9998 -A DOCKER ! -i br-a89835dc6a34 -p tcp -m tcp --dport 9999 -j DNAT --to-destination 23.254.0.35:9999 -A FORWARD -o br-a89835dc6a34 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o br-a89835dc6a34 -j DOCKER -A FORWARD -i br-a89835dc6a34 ! -o br-a89835dc6a34 -j ACCEPT -A FORWARD -i br-a89835dc6a34 -o br-a89835dc6a34 -j ACCEPT -A DOCKER -d 23.254.0.34/32 ! -i br-a89835dc6a34 -o br-a89835dc6a34 -p tcp -m tcp --dport 9998 -j ACCEPT -A DOCKER -d 23.254.0.35/32 ! -i br-a89835dc6a34 -o br-a89835dc6a34 -p tcp -m tcp --dport 9999 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i br-a89835dc6a34 ! -o br-a89835dc6a34 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-2 -o br-a89835dc6a34 -j DROP
|
虽然重启后发现策略已添加至iptables,但容器仍无法联通外部网络。
3、更改容器网络类型为host,放弃bridge,发现连通性正常,可连接外部网络,确认为bridge类型的网络问题。
1 2 3
| ... network_mode: host ...
|
4、恢复到此前的bridge网络,再次验证发现连通性依旧异常。发现内核参数ipv4转发项为0,即未开启转发,发现与其他测试环境中的配置不一致。
在宿主机中,使用sysctl修改该参数为1,表示启用该参数,重启容器,发现连通性正常。
1 2 3 4 5
| cat /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
sysctl -p
|