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

标签 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 ) 的输出。它起初失败,但后来成功了。

    我第一次尝试 ping 容器时,在 2019-12-10T23:57:52+00:00 :
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    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
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    

    最佳答案

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

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

    从容器 1 中,您可以按名称 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
    

    现在测试连接,您将能够从容器 1 ping 容器 2:
    docker exec -ti container1 ping container2
    

    关于docker - 无法从一个 Docker 容器 ping 到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59277602/

    相关文章:

    linux - ssh 用户名@主机名到 ssh 主机名

    jenkins - 在 docker 中使用 gradle 和 jenkins 构建应用程序

    r - 为什么 R 代码可以在本地工作,但不能在 Docker 中运行?

    amazon-web-services - Localstack 在 Docker 中启动,但我无法访问

    amazon-web-services - 无法删除 AWS 互联网网关

    ssh - 如何在 vagrant 基础(基线)框中包含并引用自定义 ssh key ? (虚拟盒)

    docker - 使用不同的目录上下文构建 docker 镜像

    java - DatagramPacket getData 与 getLength

    c# - 使用 ASP.net C# 写入网络文件夹

    ssh - 单个 SSH session 中的多个 channel