Docker 容器无法解析 Ubuntu 14.04 桌面主机上的 DNS

Docker 容器无法解析 Ubuntu 14.04 桌面主机上的 DNS

我在 Ubuntu 14.04 LTS 上使用 Docker 容器时遇到了问题。Docker 运行了两天,然后突然我失去了容器内的所有网络连接。下面的错误输出最初让我相信这是因为 apt-get 正在尝试通过 IPv6 解析 DNS。

我禁用了主机上的 IPv6,并且删除了所有图像,拉取了基础 ubuntu,但仍然遇到问题。

我将 /etc/resolve.conf 名称服务器从本地 DNS 服务器更改为 Google 的公共 DNS 服务器(8.8.8.8 和 8.8.4.4),但仍然没有成功。我还在 /etc/default/docker 的 DOCKER_OPTS 中将 DNS 设置为 Google,然后重新启动 docker。

我也尝试拉取 coreos,但 yum 也无法解析 DNS。

这很奇怪,因为虽然 DNS 不起作用,但当我 ping apt-get 无法解析的相同更新服务器时,仍然会收到响应。

我没有使用代理,我在一个非常标准的本地网络上,这个版本的 Ubuntu 是最新的和新鲜的(我两天前安装的,以便更接近 docker)。

我已经通过 stackoverflow 和 github 问题上的其他帖子彻底研究了这个问题,但没有找到任何解决方案。我不知道如何解决这个问题,有人能帮忙吗?

错误信息

➜  arthouse git:(docker) ✗ docker build --no-cache .
Sending build context to Docker daemon 51.03 MB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:14.04
 ---> 5506de2b643b
Step 1 : RUN apt-get update
 ---> Running in 845ae6abd1e0
Err http://archive.ubuntu.com trusty InRelease
Err http://archive.ubuntu.com trusty-updates InRelease
Err http://archive.ubuntu.com trusty-security InRelease   
Err http://archive.ubuntu.com trusty-proposed InRelease  
Err http://archive.ubuntu.com trusty Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-updates Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-security Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Err http://archive.ubuntu.com trusty-proposed Release.gpg
  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
Reading package lists...
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-updates/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-security/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-proposed/InRelease  
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-updates/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-security/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty-proposed/Release.gpg  Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]
W: Some index files failed to download. They have been ignored, or old ones used instead.

容器 IFCONFIG/PING

➜  code  docker run -it ubuntu /bin/bash
root@7bc182bf87bb:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:04  
          inet addr:172.17.0.4  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:4/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:738 (738.0 B)  TX bytes:648 (648.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@7bc182bf87bb:/# ping google.com
PING google.com (74.125.226.0) 56(84) bytes of data.
64 bytes from lga15s42-in-f0.1e100.net (74.125.226.0): icmp_seq=1 ttl=56 time=12.3 ms
--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 12.367/12.367/12.367/0.000 ms
root@7bc182bf87bb:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=44 time=21.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=44 time=21.7 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=44 time=21.7 ms

此外,当我强制使用 IPv4 时,apt-get update 会失败:

root@6d925cdf84ad:/# sudo apt-get update -o Acquire::ForceIPv4=true
Err http://archive.ubuntu.com trusty InRelease

Err http://archive.ubuntu.com trusty-updates InRelease

Err http://archive.ubuntu.com trusty-security InRelease

Err http://archive.ubuntu.com trusty-proposed InRelease

Err http://archive.ubuntu.com trusty Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-updates Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-security Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Err http://archive.ubuntu.com trusty-proposed Release.gpg
  Unable to connect to archive.ubuntu.com:http: [IP: 91.189.88.153 80]
Reading package lists... Done
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/InRelease  

答案1

哇,我在 github 上找到了一篇解决我的问题的帖子。

在 Steve K. 指出这实际上不是 DNS 问题而是连接问题后,我能够找到github 上的一篇文章描述了如何解决这个问题。

显然 docker0 网桥挂断了。安装 bridge-utils 并运行以下命令使我的 Docker 正常运行:

apt-get install bridge-utils
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
service docker restart

答案2

如果是 DNS 解析器问题,解决方案如下:

首先要检查的cat /etc/resolv.confdocker 容器。如果它有一个无效的DNS服务器,例如nameserver 127.0.x.x,那么容器将无法将域名解析为IP地址,因此ping google.com将失败。

要检查的第二件事是cat /etc/resolv.conf主机/etc/resolv.conf每次启动容器时,Docker 基本上都会将主机的复制到容器中。因此,如果主机的/etc/resolv.conf错误,那么 docker 容器也会有错误。

如果您发现主机/etc/resolv.conf有误,则您有两个选择:

  1. 在 daemon.json 中对 DNS 服务器进行硬编码。这很容易,但如果您预计 DNS 服务器会发生变化,则并不理想。

  2. 修复主机/etc/resolv.conf。这有点棘手,但它是动态生成的,并且您没有对 DNS 服务器进行硬编码。


1. 在 docker daemon.json 中硬编码 DNS 服务器

  • 编辑/etc/docker/daemon.json

    {
        "dns": ["10.1.2.3", "8.8.8.8"]
    }
    
  • 重新启动 docker 守护进程以使这些更改生效:
    sudo systemctl restart docker

  • 现在,当您运行/启动容器时,docker 将/etc/resolv.conf使用来自的值进行填充daemon.json


2. 修复主机/etc/resolv.conf

A.Ubuntu 16.04 及更早版本

  • 对于 Ubuntu 16.04 及更早版本,/etc/resolv.conf由 NetworkManager 动态生成。

  • 注释掉以下行dns=dnsmasq(带有#/etc/NetworkManager/NetworkManager.conf

  • 重新启动 NetworkManager 以重新生成/etc/resolv.conf
    sudo systemctl restart network-manager

  • 在主机上验证:cat /etc/resolv.conf

B.Ubuntu 18.04 及更高版本

  • Ubuntu 18.04 改为使用systemd-resolved生成/etc/resolv.conf。现在它默认使用本地 DNS 缓存 127.0.0.53。这在容器内不起作用,因此 Docker 将默认使用 Google 的 8.8.8.8 DNS 服务器,这可能会让防火墙后面的人无法使用。

  • /etc/resolv.conf实际上是一个符号链接( ),在 Ubuntu 18.04 中默认ls -l /etc/resolv.conf指向(127.0.0.53)。/run/systemd/resolve/stub-resolv.conf

  • 只需将符号链接更改为指向/run/systemd/resolve/resolv.conf,其中列出了真正的 DNS 服务器:
    sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

  • 在主机上验证:cat /etc/resolv.conf

现在您应该/etc/resolv.conf在主机上拥有一个有效的文件以供docker复制到容器中。

答案3

为了尝试为我也遇到过的问题增加额外的价值,我给出了另一种答案:

我的网络与办公室相关,并且 Google DNS 设置被阻止,因此容器可以 ping IP 地址但不能 ping 域名。

我的主人/etc/resolv.conf原本的样子是;

#Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
search companyDomain.co.za

这是因为网络管理器对 DNS 服务器详细信息进行了某种屏蔽。

不幸的是,根据docker 手册docker 会在构建容器的 resolv.conf 时过滤掉任何本地主机 IP 地址,并将其替换为 Google 的 DNS IP。这在我的例子中导致域名无法访问。

我不得不:

  • 将我的重置/etc/default/docker为默认值,以便容器使用我的主机的 resolv.conf 内容。
  • 编辑/etc/NetworkManager/NetworManager.conf并注释掉该行dns=dnsmasq。这样 NM 就可以指定实际的 DNS IP 地址,而不是 127.0.0.1。
  • 使用 重新启动 NM sudo service network-manager restart
  • 使用 重新启动 docker 服务sudo service docker restart

apt-get update/upgrade例如,运行容器就可以让它执行下列操作。

答案4

你的错误在这里:

 Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8c01::19).
 connect (101: Network is unreachable) [IP: 2001:67c:1360:8c01::19 80]

这不是 DNS 错误,而是您的系统尝试连接到 IPv6 主机并失败。大概是因为您在主机上没有 IPv6 访问权限。实际查找 IPv6 地址成功。(ubuntu 镜像/存档可通过 IPv6 和 IPv4 访问。您只是不幸碰到了 IPv6 地址,因为您的系统认为它应该可以工作。)

你应该通过以下方式修复此问题安装 miredo,或者重试直到找到 IPv4 镜像。

再次强调,这里需要认识到的重要一点是,DNS 并不是罪魁祸首,这一点您可以从自己的 ping 测试中看出。

相关内容