排查docker容器ping不通外网问题

背景

客户在一台机器(IP: 10.18.1.33)上部署了我们的产品,但是服务始终无法启动。

注:“产品”可简单理解为一个docker容器(IP: 16.16.16.5),容器使用自定义bridge模式,网段为16.16.16.0/24。

排查

1. 直接原因

10.18.1.33机器上 - register request.(重复打印)

10.18.1.42机器上 - waiting register ack message time out.(重复打印)

与注册中心(IP: 10.18.1.42)进行服务注册时失败了,而且10.18.1.42机器日志已经显示了原因是“等待确认超时”。

结论:注册中心收到了注册请求,但是在等待注册确认时失败了。

2. 深入“注册失败”

尝试排查网络状态如下:

1
2
3
10.18.1.33 -> 10.18.1.42 (宿主机ping外网,正常)
16.16.16.5 -> 10.18.1.33 (容器ping宿主机,正常)
16.16.16.5 -> 10.18.1.42 (容器ping外网,不通)
1
2
3
4
5
6
7
8
9
10
# 当容器ping外网时,使用tcpdump在宿主机抓包如下
# 其中br-f26926691433是bridge名称

ks@ks-33:~ $ sudo tcpdump -i br-f26926691433 -n icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-f26926691433, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:11:35.820155 IP 16.16.16.5 > 10.18.1.42: ICMP echo request, id 17, seq 10, length 64
12:11:36.844132 IP 16.16.16.5 > 10.18.1.42: ICMP echo request, id 17, seq 11, length 64
12:11:37.868186 IP 16.16.16.5 > 10.18.1.42: ICMP echo request, id 17, seq 12, length 64
12:11:38.892092 IP 16.16.16.5 > 10.18.1.42: ICMP echo request, id 17, seq 13, length 64

结论:容器ping能通宿主机,但是ping不通外网(注册中心),ping不通的原因是没有reply报文。

3. 继续排查网络问题

在本地的虚拟机上找了几台机器,部署产品并未遇到上述问题。

3.1 排查宿主机路由(正常)

1
2
3
4
5
6
ks@ks-33:~ $ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.18.1.254 0.0.0.0 UG 100 0 0 ens3
10.18.1.0 0.0.0.0 255.255.255.0 U 100 0 0 ens3
16.16.16.0 0.0.0.0 255.255.255.0 U 0 0 0 br-f26926691433

3.2 排查容器内路由(正常)

1
2
3
4
5
root@b8a1a4750bff:/home/sder/go/bin# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 16.16.16.1 0.0.0.0 UG 0 0 0 eth0
16.16.16.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

3.3 排查宿主机ip_forward配置(正常)

1
2
ks@ks-33:~ $ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

3.4 排查宿主机iptables(异常)

发现客户机器上,不存在上述红框中的防火墙规则链。

4. 复现问题

在本地环境删除该规则链,复现该问题。

1
sudo iptables -t nat -D POSTROUTING -s 16.16.16.0/24 ! -o br-f26926691433 -j MASQUERADE

解决

手动添加上述规则链,该问题解决。

1
sudo iptables -t nat -I POSTROUTING -s 16.16.16.0/24 ! -o br-f26926691433 -j MASQUERADE
  • Copyrights © 2019-2024 Klusfq
  • Visitors: | Views: