【问题标题】:Can't resolve set hostname from another docker container in same network无法从同一网络中的另一个 docker 容器解析设置的主机名
【发布时间】:2018-11-17 23:21:58
【问题描述】:

我有 db 和 server 容器,它们都在同一个网络中运行。可以通过容器 id ping db 主机没有问题。 当我手动为 db 容器设置主机名(-h myname)时,它产生了效果($ hostname 返回设置主机),但我无法从同一网络中的另一个容器 ping 该主机名。容器 id 仍然可以 ping 通。 虽然它在 docker compose 中没有问题。 我错过了什么?

【问题讨论】:

    标签: docker


    【解决方案1】:

    docker 的内置 DNS 服务不使用主机名。这是一个违反直觉的例外,但由于主机名可以在 docker 的控制之外更改,所以这是有道理的。 Docker 的 DNS 将解析:

    • 容器 ID
    • 容器名称
    • 您为该网络上的容器定义的任何网络别名

    这些选项中最简单的是最后一个选项,它在运行带有 compose 文件的容器时自动配置。服务名称本身就是一个网络别名。这使您无需重新配置其他容器即可扩展和执行滚动更新。

    您需要在用户创建的网络上,而不是在禁用 DNS 的默认网桥上。这是在使用 compose 文件运行容器时默认完成的。

    避免使用链接,因为它们已被弃用。而且我只建议为不在任何 DNS 中的外部静态主机添加主机条目,用于容器到容器,或访问 docker 之外的其他主机,首选 DNS。

    【讨论】:

    • 在第一个容器上设置 --network-alias 并在尝试从第二个容器连接到它时引用此名称对我来说很有帮助。
    • 我在--network-alias 上苦苦挣扎,不知道它不适用于默认桥接网络。 docs.docker.com/network/bridge/…
    【解决方案2】:

    我发现,使用--add-host option 可以在没有网络的情况下解决该问题。容器的IP可以获取using inspect command

    但是当容器在同一个网络中时,它们可以通过它的名字相互访问。

    【讨论】:

      【解决方案3】:

      in the docker docs 所述,如果您在默认桥接网络 上启动容器,添加-h myname 会将此信息添加到

      • /etc/hosts
      • /etc/resolv.conf
      • 和 bash 提示符

      刚刚启动的容器。

      但是,这不会对其他独立容器产生任何影响。 (您可以使用--link 将此信息添加到其他容器的/etc/hosts。但是,不推荐使用--link。)

      另一方面,当您创建用户定义的桥接网络时,docker 提供了一个嵌入式 DNS 服务器,使该网络上的容器之间的名称查找成为可能,请参阅Embedded DNS server in user-defined networks。名称解析采用--name 定义的容器名称。 (你 不会通过使用其--hostname 值找到另一个容器。)

      它与 docker-compose 一起使用的原因是,docker-compose 会为您创建一个自定义网络并自动命名容器。


      当您自己没有为容器指定名称时,情况似乎有点不同。 run reference

      如果您不使用 --name 选项指定容器名称,则守护程序会为您生成一个随机字符串名称。 [...] 如果您指定一个名称,您可以在 Docker 网络中引用容器时使用它。

      与您的发现一致,这应理解为:如果您未指定自定义 --name,则无法使用自动生成的名称来查找同一网络上的其他容器。

      【讨论】:

      • 感谢您的回答。 > 你可以使用 --link Docker 文档说它的遗留功能 (docs.docker.com/network/links),不确定使用它是否正确。 > docker-compose 为你创建一个自定义网络我已经在 docker-compose config 中指定了与 external 相同的网络并使用它,因此网络应该与手动运行相同。另外,我发现,当手动设置容器名称时,名称会在其他容器中解析(在同一个网络中)。但自动生成的名称无法解析。
      • 是的,--link 已被弃用,这就是我把它放在括号中的原因,也许我应该明确地说出来。要评论您在使用外部网络时的具体问题,您能否发布更多信息,例如你实际的 docker-compose.yml?
      • 这很容易展示:- 创建一个网络:$ docker network create test; - 运行第一个容器:$ docker run -itd --network test --name database alpine; - 运行第二个容器:$ docker run -it --network test alpine; - 并 ping 第一个:$ ping database。但是如果我们在没有指定名称的情况下第一次运行,我们无法从第二个运行它的名称(但可以 ping 它的 id)。
      • 关于stackoverflow的一般评论:您应该将此信息添加到初始问题中,以便其他人可以更轻松地从问题中受益。回到主题:我不能效仿你的例子。如果你启动容器而不给它们名字,你用什么名字来ping它?
      • 我会考虑的。启动时没有给出名称,使用 docker 生成的默认名称。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多