Ubuntu

Docker 容器無法解析 Ubuntu 14.04 桌面主機上的 DNS

  • November 10, 2021

我在 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.confdocker 容器中執行。如果它有一個無效的 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 個選擇:

  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),它在 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 複製到容器中。

引用自:https://serverfault.com/questions/642981