Docker容器无法在Ubuntu 14.04 Desktop Host上解析DNS


48

我在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无法正常工作,但是当我对apt-get无法解析的相同更新服务器执行ping操作时,仍然会收到响应。

我没有代理服务器,我使用的是非常标准的本地网络,并且此版本的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更新失败:

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  

对我来说,它在重新启动后仍然有效。
ssi-anik

Answers:


63

oo,我在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

1
您无需重新制作图像。每当您运行新容器时,都会生成resolv.conf。因此您需要删除旧容器并启动另一个容器。昨天我被这个问题困扰。同样,如果您在公司Intranet中,则可以在--dns --dns标志附近的DOCKER_OPTS env变量中的/ etc / default / docker中,将--dns-search = your.company.domain传递给docker守护进程。
Alexander.Iljushkin

这也解决了我的docker问题。
BobMcGee

3
在Arch Linux的,我需要ip link set down docker0的,而不是ifconfig docker0 downsystemctl restart docker代替service docker start。要删除所有图像,我做了docker rmi $(docker images -q)
网状网2015年

这对我来说是第一次。然后我重新启动,问题再次出现:重现这些步骤并不能再次解决问题。我不知道这是怎么回事。
user626921

1
刚刚看到我的docker0界面已关闭,我执行了该任务,/etc/init.d/docker restart然后又恢复了工作
lolesque

14

如果是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实际上是一个符号链接(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复制到容器中。


谢谢,真的让我很费解,试图了解docker容器和18.04解析VPN上IP的情况。修复18.04的/etc/resolv.conf对我有用!
乔治·帕帕斯

选项B对我
有用。.– codeSetter

当然2B不会在systemd软件包更新中幸免...
Auspex

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

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

不幸的是,根据docker手册, docker在构建容器的resolv.conf时会过滤掉所有localhost 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
这实际上为我工作。我在公司内部网后面
Daniel AndreiMincă16

1
该解决方案非常适用于Ubuntu 16.04及更早版本。对于Ubuntu 18.04和更高版本,请参阅serverfault.com/a/918568
wisbucky

谢谢!这行得通,而被接受的答案却没有。:)
Devolus

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]

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

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

再次要意识到的重要一点是,DNS不应该受到指责,就像您通过自己的ping测试所看到的那样。


1
感谢您的快速回复,并澄清说这实际上不是DNS问题,对此我表示赞赏。我安装了miredo-不行。值得注意的是,当我运行apt-get update -o Acquire :: ForceIPv4 = true apt-get update仍然失败时,我已经用该回复更新了原始帖子。我曾尝试禁用UFW,也许情况就是如此,但仍然没有运气。
Thomas V.

很奇怪-因为ping成功,所以您可以看到具有IPv4连接。但是无论您是否建议您遇到一些奇怪的路由/网络问题(我想这就是您在这里发布的原因),您都无法连接到镜像

8

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

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

    sudo nano /etc/default/docker
    
  2. 为Docker添加一个设置:

    DOCKER_OPTS="--dns 8.8.8.8"
    
  3. 替换8.8.8.8为本地DNS服务器,例如192.168.1.1。您还可以指定多个DNS服务器。用空格分隔它们,例如:

    --dns 8.8.8.8 --dns 192.168.1.1
    

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

    PS:nm-tool可用于检查本地主机DNS服务器

  4. 保存并关闭文件。

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

    sudo service docker restart
    

请注意,这是Docker Upstart和SysVinit的旧配置文件。systemd的当前方法(自Ubuntu 16.04起)是/etc/docker/daemon.json用于docker守护程序设置(例如dns)。
wisbucky

0

对于使用boot2docker时来到这里的其他读者,这是我的解决方法。实际上,以上答案为我指明了正确的方向。

基本上,由于某种原因,boot2docker内部的容器无法解析主机名。

因此,我只是重新启动了boot2docker并启动了容器。现在,主机名可以再次正确解析。

我想问题是在主机上的网络连接时启动了boot2docker,这导致boot2docker启动并进入非工作状态。


0

我在Windows上遇到了同样的问题。这个命令对我有用:docker-machine restart


0

在Debian9上重新启动Docker守护程序

service docker restart

连接和网络正常


-1

发生了类似的问题,但是在用户定义的网络内的容器之间解析名称似乎有些困难。有些人无法解决您这样的问题。

问题是移动的/ var / lib / docker。由于空间原因,它是通过nfs安装的。添加本地文件系统并将文件移动到那里可以解决此问题。


如果您认为某个问题可以由类似问题的答案回答,请将该问题标记为该问题的重复项。如果您无法执行此操作,则应留下评论,而不要单独回答。
珍妮D说恢复莫妮卡的时间
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.