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

Tho*_* V. 61 networking domain-name-system ubuntu lxc docker

我在 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.
Run Code Online (Sandbox Code Playgroud)

容器 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
Run Code Online (Sandbox Code Playgroud)

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

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  
Run Code Online (Sandbox Code Playgroud)

Tho*_* V. 77

哇,我在 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
Run Code Online (Sandbox Code Playgroud)

  • 在 arch linux 上,我需要“ip link set down docker0”而不是“ifconfig docker0 down”和“systemctl restart docker”而不是“service docker start”。要删除所有图像,我做了`docker rmi $(docker images -q)` (3认同)
  • 只需重新启动 Docker 守护进程即可为我工作 (2认同)

wis*_*cky 23

如果是 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"]
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 重新启动 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实际上是一个符号链接 ( ls -l /etc/resolv.conf),它/run/systemd/resolve/stub-resolv.conf在 Ubuntu 18.04 中默认指向(127.0.0.53)。

  • 只需将符号链接更改为指向/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 复制到容器中。


小智 13

试图为我也遇到的一个问题增加额外的价值;有一个替代答案:

我的网络与办公室相关并且 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
Run Code Online (Sandbox Code Playgroud)

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

不幸的是,根据docker 手册, docker 在构建容器的 resolv.conf 时会过滤掉任何本地主机 IP 地址,并将它们替换为 Google 的 DNS IP。在我的情况下,这导致域名被禁止使用。

我不得不:

  • 将 my 重置/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

  • 这实际上对我有用。我是公司内联网的幕后推手 (3认同)

小智 8

你的错误在这里:

 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]
Run Code Online (Sandbox Code Playgroud)

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

您应该通过安装 miredo来解决这个问题,或者重试直到遇到 IPv4 镜像。

同样,这里要意识到的重要一点是 DNS 不是罪魁祸首,正如您通过自己的 ping 测试所看到的。


小智 8

Docker 官方文档提供了配置 DNS 服务器以供 Docker 使用的工具

  1. 打开/etc/default/docker文件进行编辑:

    sudo nano /etc/default/docker
    
    Run Code Online (Sandbox Code Playgroud)
  2. 为 Docker 添加一个设置:

    DOCKER_OPTS="--dns 8.8.8.8"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 替换8.8.8.8为本地 DNS 服务器,例如192.168.1.1. 您还可以指定多个 DNS 服务器。用空格隔开,例如:

    --dns 8.8.8.8 --dns 192.168.1.1
    
    Run Code Online (Sandbox Code Playgroud)

    警告:如果您在连接到各种网络的笔记本电脑上执行此操作,请确保选择公共 DNS 服务器。

    PS:nm-tool可以用来查看本地主机的DNS服务器

  4. 保存并关闭文件。

  5. 重新启动 Docker 守护进程。

    sudo service docker restart
    
    Run Code Online (Sandbox Code Playgroud)