【问题标题】:Network calls fail during image build on corporate network在公司网络上构建映像期间网络调用失败
【发布时间】:2014-07-31 19:32:46
【问题描述】:

我在公司网络上构建 Docker 映像时遇到问题。我刚刚开始使用 Docker,所以我有以下 Dockerfile 用于 hello-world 类型的应用程序:

# DOCKER-VERSION 0.3.4
FROM    centos:6.4
# Enable EPEL for Node.js
RUN     rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
# Install Node.js and npm
RUN     yum install -y npm
# Bundle app source
ADD . /src
# Install app dependencies
RUN cd /src; npm install
EXPOSE  8080
CMD ["node", "/src/index.js"]

当我在家中的笔记本电脑上使用自己的无线网络构建它时,它运行良好。它会拉下必要的依赖项并正确构建映像。

但是,当我在公司网络上工作时,尝试从 download.fedoraproject.org 下载 RPM 时,同样的 docker 构建失败,并显示以下错误消息:

第 2 步:运行 rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm ---> 在 e0c26afe9ed5 中运行 curl:(5)无法解析代理“some.proxy.address” 错误:跳过http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm - 传输失败

在我的公司网络上,我可以通过笔记本电脑访问该 URL。但是一旦 Docker 试图构建容器,突然之间它就根本无法解决。这种行为对于各种外部资源(apt-get 等)都是一样的:它们都可以在我的公司网络上的笔记本电脑上正常解析,但 Docker 无法解析它们。

我没有网络知识来弄清楚这里发生了什么。有谁知道为什么在构建 Docker 容器时会出现这种奇怪的行为?

【问题讨论】:

标签: dns docker


【解决方案1】:

我能够找出问题所在。在 Ubuntu 上,Docker 将容器的 DNS 服务器设置为 Google 的服务器 8.8.8.x。据我了解,这是 Ubuntu 上的一种解决方法,因为 Ubuntu 将 /etc/resolv.conf 设置为 127.0.0.1。

无法从我们的防火墙后面访问那些 Google 服务器,这就是我们无法解析任何 URL 的原因。

解决方法是告诉 Docker 使用哪些 DNS 服务器。此修复取决于您安装 Docker 的方式:

Ubuntu 软件包

如果您安装了 Ubuntu 软件包,请编辑 /etc/default/docker 并添加以下行:

DOCKER_OPTS="--dns <your_dns_server_1> --dns <your_dns_server_2>"

您可以在此配置中添加任意数量的 DNS 服务器。编辑完此文件后,您需要重新启动 Docker 服务:

sudo service docker restart

二进制文件

如果您通过二进制方法安装了 Docker(即没有包),那么您在启动 Docker 守护程序时设置 DNS 服务器:

sudo docker -d -D --dns <your_dns_server_1> --dns <your_dns_server_2> &

【讨论】:

  • 如何将 'docker build' 命令与 Dockfiles 一起使用...在这些情况下它看起来不起作用: docker --dns=209.18.47.61 build 。 2>&1 | tee ./output.txt
  • 是的,这应该适用于 docker build。 docker build 命令本身没有 --dns 标志,但是如果您像这样在守护程序上设置它,那么它将在使用 docker build 时应用
  • 感谢您提供此解决方案。在我这边,问题是,docker 显然需要 IPv4 可用和启用。怎么回事?学习:IPv4 已死。仅 IPv4 的软件已严重损坏。
  • 我已经完成了这一步并再次开始出现错误。重新启动服务再次修复它。
  • 我在使用 docker 1.7 时遇到了这个问题,尽管我尝试使用 --dns 选项或将配置放入 /etc/default/docker 来运行它
【解决方案2】:

我建议更改 Docker 守护程序的 DNS 设置。您可以通过在 /etc/docker/daemon.json 中创建守护程序配置文件来设置 docker 守护程序的默认选项。根据您的主机设置 DNS 服务器,例如我的 DNS 服务器是 10.0.0.2:

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

然后你只需要重启 docker 服务:

sudo service docker restart

这里有分步说​​明Fix Docker's networking DNS config

【讨论】:

    【解决方案3】:

    以下步骤对我有用(适用于 docker build 和 docker run 命令)。我的 linux 版本是 Ubuntu 14.04。

    • 使用以下命令识别 DNS​​。
      纳米工具 | grep DNS

    这个结果 DNS:192.168.1.1 就我而言

    • 在 /etc/default/docker.io 中创建条目。我当前的条目如下所示
    DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 --dns 192.168.1.1"
    • 重启docker服务
     sudo 服务 docker.io 重启 

    【讨论】:

    • CentOS 的等价物是 /etc/sysconfig/docker 文件,我可以在其中添加 DOCKER_OPTS="--dns 8.8.8.8" 行并解决我的问题。
    • OpenSuSE 也有 /etc/sysconfig/docker 文件。
    【解决方案4】:

    对于使用 SystemD 的任何 Linux 发行版(Ubuntu 16、RHEL 7...),将使用以下命令显示路径:

    $ systemctl status docker
    ● docker.service - Docker Application Container Engine
       Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
       Active: active (running) since Wed 2016-06-29 08:10:33 PDT; 2min 34s ago
         Docs: https://docs.docker.com
     Main PID: 1169 (dockerd)
        Tasks: 19
       Memory: 85.0M
          CPU: 1.779s
       CGroup: /system.slice/docker.service
               ├─1169 /usr/bin/dockerd --dns 172.18.20.11 --dns 172.20.100.15 --dns 8.8.8.8 --dns 8.8.4.4 -H fd://
               └─1232 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --shim docker-containerd-shim --met
    

    路径为/lib/systemd/system/docker.service。在启动守护程序的行中添加DOCKER_OPTS 值,该值可以包含任何--dns

    cat /lib/systemd/system/docker.service | grep dns 
    ExecStart=/usr/bin/dockerd --dns 172.18.20.11 --dns 172.20.100.15 --dns 8.8.8.8 --dns 8.8.4.4  -H fd://
    

    【讨论】:

    • 谢谢!编辑docker.service 后,我不得不用sudo service docker stop 停止docker 服务,然后systemctl daemon-reload 最后sudo service docker start
    • 您最好在/etc/systemd/system/docker.service.d 中添加一个带有修改后配置的单元文件(systemd 有助于合并/覆盖系统配置),而不是更改系统版本。后者将在升级时丢失。
    【解决方案5】:

    Mac 和 Windows 上的 Docker(至少 >=1.13,可能更早)允许您在 Preferences -> Daemon -> Advanced 中配置 DNS:

    以下配置设置了两个公司 DNS 服务器(在此处使用您自己的值),并回退到 Google 公共 DNS 服务器。

    【讨论】:

    • 你拯救了我的一天 - 它在我的 Windows docker 桌面实例上运行良好。
    • 谢谢 Jason——如果这不起作用,请参阅我稍后的回答,了解在 UI 上设置 DNS 的新方法。
    【解决方案6】:

    将您的 DNS 指定给 Docker 守护进程。

    首先获取你的DNS地址

    $ nmcli dev show | grep 'IP4.DNS'
    IP4.DNS[1]:                             10.0.0.2
    

    通过启动强制使用此新 DNS 的 docker 容器来测试问题是否真的出在 DNS 上

    $ docker run --dns 10.0.0.2 <image_name> <command_name>
    

    如果这解决了问题,您可以通过以下方式将此修复应用于所有 docker 守护进程

    编辑或创建文件/etc/docker/daemon.json

    将以下行添加到该文件中

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

    重启泊坞窗

    $ sudo service docker restart
    

    可以在此处找到完成所有此过程的非常好的指南。

    https://development.robinwinslow.uk/2016/06/23/fix-docker-networking-dns/

    【讨论】:

    • 这是一个边界线link-only answer。您应该在此处扩展您的答案以包含尽可能多的信息,并使用该链接仅供参考。
    • 如果您通过 snap 安装 daemon.json 将位于 /var/snap/docker/&lt;id&gt;/config/daemon.json
    【解决方案7】:

    不重启Docker服务的解决方案

    可以通过在构建时覆盖 resolv.conf 来修改单个 Docker 映像的 DNS 设置而不影响其他 docker build 调用(并且无需重新启动 Docker 服务):

    FROM ubuntu:18.04
    
    RUN echo "nameserver 123.123.123.123" > /etc/resolv.conf && apt update
    

    将 IP 123.123.123.123 替换为您公司网络中使用的 IP(使用 nmcli dev show | grep 'IP4.DNS' 获取当前使用的 DNS 服务器)。

    缺点:

    • 这不会影响 Dockerfile 中的任何其他行。因此,如果它取决于 DNS 解析,您必须在每一行加上修复前缀

    【讨论】:

      【解决方案8】:

      在我的 Ubuntu 16.04 机器上,Google 的 DNS 有时无法用于构建 Docker 映像。

      cat /etc/docker/daemon.json
      {"dns": [""8.8.8.8"] }
      

      我必须使用以下命令手动查找我的服务提供商 DNS

      nmcli device show <interfacename> | grep IP4.DNS
      
      125.22.47.102
      

      并将其添加到我的daemon.json,如下所示

      cat /etc/docker/daemon.json 
      
      {"dns": ["125.22.47.102","8.8.8.8"] }
      
       restart docker
      
      sudo service docker restart
      

      (PS nm-tool 已从 Ubuntu 15.04 弃用)

      【讨论】:

        【解决方案9】:

        2021 年 9 月更新信息

        受到杰森回答的启发;在当前版本中,在 JSON 中设置 DNS 服务器对我不起作用,但现在有另一个地方可以设置它:

        当您打开切换开关时,8.8.8.8 已经存在,所以我就离开了它,它在我的开发环境中运行良好。我没有研究它,但如果需要,可能有一种添加列表的方法,可能用逗号/分号/空格等分隔。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-02
          • 2021-12-16
          • 1970-01-01
          • 2023-02-24
          • 1970-01-01
          • 1970-01-01
          • 2020-07-20
          相关资源
          最近更新 更多