【问题标题】:How can you make the Docker container use the host machine's '/etc/hosts' file?如何让 Docker 容器使用主机的“/etc/hosts”文件?
【发布时间】:2015-11-11 19:12:44
【问题描述】:

我想让我启动的 Docker 容器使用与我运行的主机相同的 /etc/hosts 设置。有没有办法做到这一点?

我知道docker run 有一个--add-host 选项,但这并不是我想要的,因为主机的/etc/hosts 文件在不同的机器上可能不同,所以硬编码确切的IP 地址对我来说不是很好/主机与--add-host

【问题讨论】:

  • 我敢建议,也许您更愿意设置容器的 DNS 以(间接)考虑主机的 /etc/hosts。我遇到了同样的情况,我的解决方案是编辑 /etc/docker/daemon.json 以指向一个简单的 DNS 代理,它读取为 /etc/hosts
  • 有点晚了,但是......这里他们说 /etc/hosts 的守护进程将被使用:docs.docker.com/config/containers/container-networking/… 不幸的是,这在我的情况下不起作用......

标签: docker


【解决方案1】:

将此添加到您的运行命令中:

-v /etc/hosts:/etc/hosts

【讨论】:

  • 从一开始看起来这应该可以工作,但是 Docker 容器的 /etc/hosts 文件是为容器量身定制的,因此替换文件会产生后果。
  • 它对我有用。但是,当外部/etc/hosts 更改时,它不会在容器内自动更新。它需要重新启动才能更新。
  • 是的,它的工作,但它不是一个好主意......真的很冒险
【解决方案2】:

docker run 命令中使用--network=host。这告诉 Docker 让容器使用主机的网络堆栈。你可以了解更多here

【讨论】:

  • 这在没有 host 网络的 Mac 或 Windows 上如何工作?
  • 主机网络在许多情况下(堆栈、群...)根本不是一种选择。
  • 虽然 --network=host 显然有助于解决这个问题,但每个人都应该意识到其他后果,例如一个简单的例子,它会映射和将 Dockerfile 中提到的所有端口打开到互联网
  • 强调来自@OndraŽižka 的评论,“主机网络驱动程序仅适用于 Linux 主机,并且在 Docker Desktop for Mac、Docker Desktop for Windows 或 Docker EE for Windows Server 上不受支持。”
【解决方案3】:

如果您正在运行用于运行 Docker 容器的虚拟机,如果您希望容器了解主机(VM 等),具体取决于您使用的 VM 软件,您必须确保是您希望容器能够解析的任何机器的主机(托管 VM)上的条目。

这是因为 VM 及其容器将在其 resolv.conf 文件中包含主机(VM)的 IP 地址。

【讨论】:

    【解决方案4】:

    添加一个标准的hosts file -

    docker run -it ubuntu cat /etc/hosts
    

    为服务器 'foo' 添加一个映射 -

    docker run -it --add-host foo:10.0.0.3 ubuntu cat /etc/hosts
    

    为多个服务器添加映射

    docker run -it --add-host foo:10.0.0.3 --add-host bar:10.7.3.21 ubuntu cat /etc/hosts
    

    参考 - Docker Now Supports Adding Host Mappings

    【讨论】:

    【解决方案5】:

    IMO,在运行 Docker 时传递 --network=host 选项是 d3ming 建议的更好选择,而不是其他答案建议的其他选项:

    1. 主机的 /etc/hosts 文件中的任何更改都可以立即用于容器,如果您一开始就有这样的要求,这可能就是您想要的。
    2. 使用 -v 选项挂载主机的 /etc/hosts 文件可能不是一个好主意,因为容器的任何意外更改都会破坏主机的配置。

    【讨论】:

    • 正如 Clerenz 在对已接受答案的评论中提到的那样,这仅在您仍然可以选择使用的网络类型的极少数情况下才有可能。
    【解决方案6】:

    如果你使用docker-compose.yml,对应的属性是:

    services:
      xxx:
        network_mode: "host"
    

    Source

    【讨论】:

      【解决方案7】:

      如果受信任的用户启动您的容器,您可以使用 shell 函数轻松“复制”您需要的 /etc/hosts 条目:

      add_host_opt() { awk "/\\<${1}\\>/ {print \"--add-host $1:\" \$1}" /etc/hosts; }
      

      你可以这样做:

      docker run $(add_host_opt host.name) ubuntu cat /etc/hosts
      

      这样您就不必对 IP 地址进行硬编码。

      【讨论】:

        【解决方案8】:

        主机的/etc/hosts 文件无法挂载到容器中。但是您可以将文件夹挂载到容器中。你需要一个 dnsmasq 容器。

        1. 主机上的新文件夹

           mkdir -p ~/new_hosts/
          
           ln  /etc/hosts ~/new_hosts/hosts
          
        2. 将 ~/new_hosts/ 挂载到容器中

           docker run -it -v ~/new_hosts/:/new_hosts centos /bin/bash
          
        3. 配置dnsmasq使用/new_hosts/hosts解析名称。

        4. 更改容器的 DNS 服务器。使用 dnsmasq 容器的 IP 地址。

        如果您更改主机上的/etc/hosts 文件,dnsmasq 容器的/new_hosts/hosts 将更改。

        我发现了一个问题:

        dnsmasq 容器/new_hosts/hosts 中的文件可以更改。但是新主机无法解决。因为dnsmasq 使用inotify 监听更改事件。当您修改主机上的文件时。 dnsmasq 无法接收信号,因此不会更新配置。因此,您可能需要编写一个守护进程来每次将/new_hosts/hosts 文件内容读取到另一个文件中。并更改dnsmasq 配置以使用新文件。

        【讨论】:

        • 你实际上可以从主机挂载/etc/hosts,而且你可以只读方式挂载它:-v /etc/hosts:/etc/hosts:ro
        【解决方案9】:

        extra_hosts(在 docker-compose.yml 中)

        https://docs.docker.com/compose/compose-file/

        添加主机名映射。使用与 docker 客户端 --add-host 参数相同的值。

        extra_hosts:
         - "somehost:162.242.195.82"
         - "otherhost:50.31.209.229"
        

        【讨论】:

          【解决方案10】:

          您也可以通过以下命令将 dnsmasq 安装到主机:

          sudo apt-get install dnsmasq
          

          然后你需要添加文件 /etc/docker/daemon.json 的内容:

          {
              "dns": ["host_ip_address", "8.8.8.8"],
          }
          

          之后需要通过命令sudo service docker restart重启Docker服务

          此选项强制为每个 Docker 容器使用主机 DNS 选项。 或者你可以将它用于单个容器,命令行选项由this link 解释。还支持 docker-compose 选项(您可以通过 this link 阅读它)。

          【讨论】:

          • 被低估的评论。这是一个更好的解决方案。
          • 不错。但是 Docker 部分不适用于 Rancher 和 Kubernetes。
          • 很好的答案。请记住将“host_ip_address”替换为您主机的真实IP地址?
          【解决方案11】:

          我遇到了同样的问题,发现这很可能与容器化概念相反!但是我通过将每个 (ip host) 对从 /etc/hosts 添加到 existing running 容器中来解决我的问题:

          1. docker stop 你的容器名
          2. systemctl 停止泊坞窗
          3. vi /var/lib/docker/containers/*your-container-ID*/hostconfig.json

          在文本中找到 ExtraHosts 并添加或替换 null"ExtraHosts":["your.domain-name.com":"it.s.ip.addr"]

          1. systemctl 启动泊坞窗
          2. docker 启动 你的容器名称

          如果您可以停止容器并重新运行它,情况会更好,所以就这样做吧。但是,如果您不想像我一样破坏您的容器,那将是一个很好的解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-03-26
            • 2017-11-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多