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
哇,我在 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
如果是 DNS 解析器問題,解決方法如下:
首先要檢查的是
cat /etc/resolv.conf
在docker 容器中執行。如果它有一個無效的 DNS 伺服器,例如nameserver 127.0.x.x
,那麼容器將無法將域名解析為 ip 地址,因此ping google.com
會失敗。要檢查的第二件事是
cat /etc/resolv.conf
在主機上執行。Docker 基本上/etc/resolv.conf
每次啟動容器時都會將主機複製到容器中。因此,如果主機/etc/resolv.conf
錯了,那麼 docker 容器也會錯。如果您發現主機
/etc/resolv.conf
錯誤,那麼您有 2 個選擇:
- 在 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
實際上是一個符號連結 (ls -l /etc/resolv.conf
),它在 Ubuntu 18.04 中預設指向/run/systemd/resolve/stub-resolv.conf
(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 複製到容器中。