我在 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.conf
是docker 容器。如果它有一个无效的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
有误,则您有两个选择:
在 daemon.json 中对 DNS 服务器进行硬编码。这很容易,但如果您预计 DNS 服务器会发生变化,则并不理想。
修复主机
/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 测试中看出。