无法从一个Docker容器ping到另一个

时间:2019-12-11 01:16:30

标签: docker networking ssh ping docker-swarm

我们一直遇到一个长期的网络问题。简而言之,一个容器无法ping(或ssh)另一个容器。有人有多余的时间和我一起思考吗?

我们的设置

  • Docker CE 18.06.03(在尝试解决此问题时,我们已从17.03升级,但没有帮助)
  • Swarm Classic(独立版)1.2.9
  • 将Consul作为Swarm后端,在五个节点上与成员一起运行
  • 总共七个节点,其中六个为宿主容器
  • 每个容器在启动时都已连接到覆盖网络

到目前为止,我们已经尝试过:

这个问题在很大程度上困扰了我们。我们已经花了很多时间,并完成了许多基本的故障排除和一些更高级的故障排除(很高兴进行详细介绍)。 (但是我不希望我已经穷尽了我们的选择,所以请不要犹豫地提出任何您认为可行的建议。) 它是不一致的(发生在不同的图像,不同的节点上),断断续续的并且是长期存在的(几个月)。我们进行了两项更改,其中一项是MAC地址分配的解决方法(在此处解释:https://github.com/docker/libnetwork/pull/2380;实际解决方法:https://github.com/systemd/systemd/issues/3374#issuecomment-452718898),确实改善了这种情况,包括消除了MAC地址分配错误从日志中。我们还升级了此修补程序(https://github.com/docker/libnetwork/pull/1935),该修补程序处理IP重用。这也减少了问题(当时,没有容器可以通信)。我还使用netshoot容器进行了一些基本测试(如果您需要更多信息,请告诉我)。

对于给定的容器,我们有一个解决方法:我们删除该容器的Consul数据,然后停止并重新启动它。据我所知,Consul数据本身似乎不是问题,而是来自Docker / Swarm在启动容器时重置了几个网络配置(我可以说更多,如果这似乎引发任何人的想法)阅读)。然后,该容器可以经常ping其他容器,但不总是如此。

具体问题:

似乎在一段时间内,情况可能会更糟。它不一定要同时启动多个容器,但是有一个明确的模式:在某些时间段内,容器的配置不正确,无法相互通信。 您会想到哪些故障排除步骤?

以下内容是尝试从其他两个容器ping一个容器(82afb0dccbcc)的输出。首先,它失败了,但是随后成功了。

我第一次尝试在2019-12-10T23:57:52+00:00上ping容器:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82afb0dccbcc: user___92397089 crccheck/hello-world
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PING 82afb0dccbcc (172.24.0.165) 56(84) bytes of data.^M
^M
--- 82afb0dccbcc ping statistics ---^M
4 packets transmitted, 0 received, 100% packet loss, time 3033ms^M
^M
PING 82afb0dccbcc (172.24.0.165) 56(84) bytes of data.^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=2 ttl=64 time=0.083 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=3 ttl=64 time=0.072 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=4 ttl=64 time=0.073 ms^M
^M
--- 82afb0dccbcc ping statistics ---^M
4 packets transmitted, 3 received, 25% packet loss, time 3023ms^M
rtt min/avg/max/mdev = 0.072/0.076/0.083/0.005 ms^M
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

在上面的第一次ping测试中,我们注意到来自第一个容器的数据包丢失为100%,而来自第二个容器的数据包丢失为25%。

几分钟后(2019-12-10T23:57:52+00:00),82afb0dccbcc可以从两个容器成功ping通:

82afb0dccbcc: user___92397089 crccheck/hello-world
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ping from ansible-provisioner:
PING 82afb0dccbcc (172.24.0.165) 56(84) bytes of data.^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=1 ttl=64 time=0.056 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=2 ttl=64 time=0.073 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=3 ttl=64 time=0.077 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=4 ttl=64 time=0.087 ms^M
^M
--- 82afb0dccbcc ping statistics ---^M
4 packets transmitted, 4 received, 0% packet loss, time 3063ms^M
rtt min/avg/max/mdev = 0.056/0.073/0.087/0.012 ms^M
ping from ansible_container:
PING 82afb0dccbcc (172.24.0.165) 56(84) bytes of data.^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=1 ttl=64 time=0.055 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=2 ttl=64 time=0.055 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=3 ttl=64 time=0.060 ms^M
64 bytes from user___92397089.wharf (172.24.0.165): icmp_seq=4 ttl=64 time=0.085 ms^M
^M
--- 82afb0dccbcc ping statistics ---^M
4 packets transmitted, 4 received, 0% packet loss, time 3062ms^M
rtt min/avg/max/mdev = 0.055/0.063/0.085/0.015 ms^M
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3 个答案:

答案 0 :(得分:0)

您需要创建一个网络并将两个容器都连接到该网络。

Docker嵌入式DNS服务器为连接到给定网络的容器启用名称解析。这意味着任何连接的容器都可以通过其容器名称对同一网络上的另一个容器执行ping操作。

在container1内,您可以按名称ping容器2。因此,显式指定容器的名称很重要,否则将无法正常工作。

创建两个容器:

docker run -d --name container1 -p 8001:80 test/apache-php
docker run -d --name container2 -p 8002:80 test/apache-php

现在创建一个网络:

docker network create myNetwork

之后,将您的容器连接到网络:

docker network connect myNetwork container1
docker network connect myNetwork container2

检查您的容器是否是新网络的一部分:

docker network inspect myNetwork

现在测试连接,您将能够从container1 ping容器2:

docker exec -ti container1 ping container2

答案 1 :(得分:0)

我实际上是随机遇到此问题的,但是在我的情况下,两个容器已经在同一网络上,所以让我感到困惑的是,为什么一个容器无法对另一个容器执行ping操作。

直到我运行docker network inspect myNetwork并随机注意到,由于某些原因,两个容器都被分配了相同的mac地址……不知道为什么发生甚至如何发生。显然,这将阻止ping操作,因为在LAN上,交换逻辑使用mac地址来路由流量。

我不得不停下来并删除容器,然后重新创建它以更改mac地址。

答案 2 :(得分:0)

如果有任何 web 应用程序正在您的任何一个容器上运行,并且您想从另一个容器 ping/调用任何端点并想使用响应,那么您可以按照下面提到的步骤进行操作 -

首先使用docker网络建立容器间通信

1. docker network create dockerContainerCommunication

现在将容器连接到网络 dockerContainerCommunication

2. docker network connect dockerContainerCommunication container1
3. docker network connect dockerContainerCommunication container2

现在启动你的容器(如果没有启动)

4. docker start container1
5. docker start container2
  1. 检查您的网络。在这里您还可以找到容器的 IP 地址。 docker network inspect dockerContainerCommunication

  2. 现在附加到您要使用 Web 应用程序的任何一个容器,然后使用您在第 6 步中找到的 curl + IP 地址 ping 其他容器。

docker attach container1 

docker attach container2

然后运行 ​​curl 命令

curl http://IP_ADDRESS:PORT_ON_WHICH_APP_IS_RUNNING/api/endpointPath

希望能帮到你。