我正在尝试让两个容器在服务器上进行通信,就像在我的计算机上工作一样。
问题是它们无法通信(尝试从容器 A ping 容器 B)
我首先创建了一个使用 Python 镜像的 Dockerfile。请注意,我使用--network=host
选项来构建此容器(如果没有,我将无法在互联网上获取软件包)
接下来,我有一个docker-compose
文件,它使用之前创建的图像创建两个容器。
NETWORK ID NAME DRIVER SCOPE
939d3e6af24e bridge bridge local
2d455afde6fc dcoflask_default bridge local
97f17b13840c host host local
0f40cabe1c02 none null local
通过检查我的两个容器所连接的网络:
"Containers": {
"2fe15640751ac7f6dd7bfa20e2e646e44cc2c53fbfa25e8f4df25dfbc08adb9f": {
"Name": "mssql",
"EndpointID": "39d1a5429f676d990c52932eed8a66376f76b9cbbff9bcd53b256e1720798bfd",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"50fc9a1f4a4743f2a4e9f80cd2d73515bad4fed748360fc4a26f289c06f8b245": {
"Name": "web-dco",
"EndpointID": "7d389570b1c80fa7a1fbb4a633dabbb4f7afd0063acb6cd41f12fc56a290650c",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
我们可以确认它们在同一个网络接口上。
通过发出 ping(来自容器 web-dco),我无法从另一个容器(mssql)获得响应
PING mssql (172.18.0.2) 56(84) bytes of data.
^C
--- mssql ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 125ms
通过对为容器网络创建的网络接口进行一些嗅探,我可以看到请求但没有响应:
legrand.g@my-server:~$ sudo tshark -i br-2d455afde6fc
Enter password for interactive MFA. Otherwise, enter password followed by 6 digit PingID code:
Running as user "root" and group "root". This could be dangerous.
Capturing on 'br-2d455afde6fc'
1 0.000000000 172.18.0.2 → 143.26.128.29 DNS 85 Standard query 0x54a6 A vortex.data.microsoft.com
2 4.001179175 172.18.0.2 → 192.44.120.10 DNS 85 Standard query 0x54a6 A vortex.data.microsoft.com
3 4.088081213 02:42:ac:12:00:02 → 02:42:40:e2:2c:15 ARP 42 Who has 172.18.0.1? Tell 172.18.0.2
4 4.088130713 02:42:40:e2:2c:15 → 02:42:ac:12:00:02 ARP 42 172.18.0.1 is at 02:42:40:e2:2c:15
5 5.003686924 172.18.0.2 → 143.26.128.29 DNS 85 Standard query 0x54a6 A vortex.data.microsoft.com
6 9.004492793 172.18.0.2 → 192.44.120.10 DNS 85 Standard query 0x54a6 A vortex.data.microsoft.com
^C6 packets captured
最后,从以前关于容器通信的帖子来看,我没有发现 iptables 有什么问题
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o br-2d455afde6fc -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-2d455afde6fc -j DOCKER
-A FORWARD -i br-2d455afde6fc ! -o br-2d455afde6fc -j ACCEPT
-A FORWARD -i br-2d455afde6fc -o br-2d455afde6fc -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
-A DOCKER -d 172.18.0.2/32 ! -i br-2d455afde6fc -o br-2d455afde6fc -p tcp -m tcp --dport 1433 -j ACCEPT
-A DOCKER -d 172.18.0.3/32 ! -i br-2d455afde6fc -o br-2d455afde6fc -p tcp -m tcp --dport 5000 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-2d455afde6fc ! -o br-2d455afde6fc -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o br-2d455afde6fc -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
我在我的计算机上和在服务器上运行这些容器之间看到的唯一区别是,在我的计算机上,我不需要使用该--network=host
选项构建 Dockerfile。
互联网也无法访问,但这是问题的另一部分,我首先想了解为什么两个简单的容器即使使用同一个网络也无法通信。
NB IP转发已启用:
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1