docker.io DNS无法正常工作,正在尝试使用8.8.8.8


33

我安装了新的Ubuntu 14.04,并希望使用Docker运行需要12.04的旧文件。Docker内部的DNS无法正常工作。

我的笔记本电脑的resolv.conf看起来像:

nameserver 127.0.0.1

显然,这不适用于Docker。因此,它将尝试将名称服务器设置为8.8.8.8和8.8.4.4。当我做

$ sudo docker run -i -t ubuntu /bin/bash

它说:

WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]

可以肯定的是,在Docker实例中,resolv.conf看起来像:

nameserver 8.8.8.8
nameserver 8.8.4.4

我可以从Docker实例中成功ping通这两个。但是,没有DNS(例如,ping google.com失败)。

Docker内部的ifconfig输出:

eth0      Link encap:Ethernet  HWaddr aa:e9:9f:83:9d:92  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a8e9:9fff:fe83:9d92/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:738 (738.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:1500  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)

怎么办?

Answers:


23

当Ubuntu Docker软件包更新为使用systemd时,它放弃了对/etc/default/docker配置文件的支持,因此robotman10404建议的初始解决方案将不再起作用(禁用dnsmasq仍然有效,但是不利之处在于阻止Ubuntu自动更新DNS服务器) 。

修复新的 daemon.json配置文件

查找您网络的DNS服务器:

$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]:                             10.0.0.2

打开或创建(如果不存在),/etc/docker/daemon.json然后将DNS设置添加到该ExecStart行:

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

重新启动Docker守护程序:

$ sudo service docker restart

我写了一篇深入的博客文章,还提出了一个错误如果您需要更多详细信息有关此问题。

(最初,我通过打开/lib/systemd/system/docker.service并将DNS设置添加到ExecStart行中来解决该问题,但这很糟糕-我们不应该直接编辑systemd文件。)


感谢您的解决方案-在我使用解决方案的过程中这很有帮助-我认为这对于我自己的情况以及在Ubuntu(或其他使用NetworkManager + dnsmasq的其他桌面发行版)上运行Docker的特殊性来说是一个稍微更好的匹配。
阿德里安

16

我自己不使用docker,因此通常我不会在这里讨论docker问题,但是我只是偶然在阅读有关它的内容,偶然发现了一些docker文档,似乎可以解决这个确切的问题。总结一下...

该文档提出了一些解决方法。首先是通过将以下行添加到,来指定docker守护程序要用于容器的DNS服务器/etc/default/docker

docker_OPTS="--dns 8.8.8.8"

其中提供的DNS可以是本地DNS服务器,例如192.168.1.1(网关)。然后,重新启动

sudo restart docker

一种替代解决方案包括通过注释掉配置,在NetworkManager中禁用dnsmasq,/etc/NetworkManager/NetworkManager.conf如下所示:

#dns=dnsmasq

然后,重新启动

sudo restart network-manager
sudo restart docker

3
禁用dnsmasq对我有用。
妮2015年

2
后一种方法当然意味着网络管理员无法控制dnsmasq,这意味着,例如,当您更改网络(包括切换到VPN)时,它无法更改dns服务器。前一种方法对我来说似乎更好,但我希望dnsmasq也可以监听Docker IP(172.17.0.1),因此我可以将Docker主机指向该地址。
mc0e

1
由于Ubuntu切换为使用sytemd设置Docker,/etc/default/docker因此不再起作用。请参阅我的解决方案,以了解如何在post-init.d / upstart世界中解决此问题。
罗宾·温斯洛

/etc/NetworkManager/NetworkManager.conf在Ubuntu 18.04 LTS上不存在。:/
XtraSimplicity '18

请注意,对于某些Ubuntu 18.04设置(例如,Amazon上的最小映像)systemd-resolved,默认情况下它充当缓存DNS服务器,并且会引发WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.问题(Ubuntu 16.04设置在默认情况下似乎并未启用它)。解决方法是在启动容器时禁用systemd-resolved或使用该--dns选项,如主要答案中所述。
Anon

9

我在遇到这种情况时遇到了这种情况

  • 在我的本地开发机器上运行Docker容器
  • 哪个连接到VPN
  • 我们的某些容器构建脚本执行的操作类似于npm install从容器内VPN上的自定义存储库运行。
    • 它无法通过CI管道运行,但不能通过我们的开发人员计算机运行,因为npm无法成功进行DNS查找
    • 我们还遇到了容器的问题,需要进行查找才能调用外部REST API

默认情况下,Ubuntu使用dnsmasq由NetworkManager启动的设备来缓存DNS请求,并配置/etc/resolv.conf为指向以下实例127.0.1.1

  • 我们使用的VPN客户端与NetworkManager不兼容,并强制使用自己的VPN客户端,该客户端/etc/resolv.conf将覆盖NetworkManager配置
  • 这将为VPN配置DNS服务器
  • Docker /etc/resolv.conf默认将您的影子隐藏在容器中
    • 通常在Ubuntu上,它将Google DNS服务器传递到容器(因为它知道这种dnsmasq情况)。
    • 但是很高兴将VPN DNS服务器配置传递给容器
    • docker0网桥上的容器到VPN tap0适配器之间没有DNS服务器的路由。
  • 抱歉,容器中的所有DNS查找均失败,因为它无法访问所提供的唯一DNS服务器
  • 此外,某些网络会阻止对Google DNS服务器的请求,因为它们希望能够监听您的所有DNS查找

解决方案 :

使用NetworkManager及其dnsmasq设计实例的俘获实例似乎更为优雅。

  1. 告诉Docker将您的dnsmasq实例用于DNS

    • 添加或编辑文件/etc/docker/daemon.json以告知Docker使用docker0网桥适配器进行DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. 还配置NM dnsmasq实例以侦听Docker桥,因为默认情况下它仅侦听127.0.1.1-创建文件/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. 我不喜欢该VPN客户端的粗鲁行为,我只想在VPN端使用DNS进行VPN查找(如果您有一个使用正确配置的NetworkManager的礼貌VPN客户端,则不必这样做)

    • 关闭VPN客户端中的DNS功能(它会resolv.conf在连接时停止覆盖,现在所有DNS dnsmasq再次通过)
    • 添加一个配置文件以告诉dnsmasq您正确地为您的域定向DNS请求-添加文件`/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • (可选)为您的域添加搜索域,以便您可以使用短名称

      • 我刚刚将本地域添加到默认网络连接中的搜索列表中
  4. 重新启动NetworkManager和Docker

    sudo service network-manager restart
    sudo service docker restart
    

此时nslookup,对于VPN内部和外部的域,当您使用VPN时,您的Docker容器应该能够毫无问题地运行。


1
一个不涉及对docker0桥IP进行硬编码的小调整,是使用interface而不是listen-address指令:interface = docker0
siwyd

很棒的解释和说明。+1是当之无愧的。
ereOn

干杯@simonwydooghe-我已采纳您的建议-您也可以在该字段中使用通配符,因此我为非默认网络使用的所有网桥名称添加了一种模式(至少与docker-compose所使用的一样)。
阿德里安

1
看来daemon.json中的dns值必须是一个数组,否则我得到一个错误:cannot unmarshal string into Go value of type []string重新启动docker服务时。
Slaven Rezic

Bionic的更新:18.04不再使用由NetworkManager for DNS管理的dnsmasq的强制实例,而是使用systemd-resolved;这带来了自己的问题,因为无法将其配置为侦听docker0桥。我不得不禁用它,然后重新安装NetworkManager dnsmasq并正确配置它。
阿德里安

2

这是我在无头运行的Ubuntu 14.04服务器上设置docker的方法。

我正在运行Ubuntu Server 14.04,安装了以下Docker版本。

#docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1

文件/etc/init/docker.io.conf和脚本包含以下行:

# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
    DOCKER=/usr/bin/$UPSTART_JOB
    DOCKER_OPTS=

上面的答案帮助我找到了上面的文件。

我在/etc/default/docker.io中取消注释以下内容,并添加了本地DNS服务器:

# Use DOCKER_OPTS to modify the daemon startup options.  
DOCKER_OPTS="--dns 192.168.X.X"

通过以下方式重新启动服务:

sudo service docker.io restart

docker run <image> /bin/bash

启动容器时没有dns消息。

启动一个新的容器,安装了dnsutils。

然挖,并且服务器消息是正确的本地DNS服务器。


0

我有一个类似的问题,报告给StackOverflow。看来我无法查询8.8.8.8Docker默认Ubuntu安装中指定的名称服务器;但是,我可以ping它。在这种情况下,请使用可以实际查询的DNS服务器。测试

nslookup - dns.server.name

然后通过启动容器

docker run --dns=ip.addr.of.dns

我尚未找到一种方法来https://askubuntu.com/q/607172/30266来导出自动解决方案。


我的答案可能足以满足您的需求……
阿德里安

0

如果dnsmasq您的Docker容器位于用户定义的网络上,则可以使用主机的本地DNS解析器(例如)。在这种情况下,容器/etc/resolv.conf将具有名称服务器127.0.0.11(又名Docker的嵌入式DNS服务器),该名称服务器可以将DNS请求正确转发到主机的环回地址。

$ cat /etc/resolv.conf
nameserver 127.0.0.1
$ docker run --rm alpine cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ docker network create demo
557079c79ddf6be7d6def935fa0c1c3c8290a0db4649c4679b84f6363e3dd9a0
$ docker run --rm --net demo alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0    

如果使用docker-compose,它将自动为您的容器设置一个自定义网络(文件格式为v2 +)。但是请注意,虽然docker-compose在用户定义的网络中运行容器,但仍会在默认网络中构建容器。要将自定义网络用于构建,可以network构建配置中指定参数(需要文件格式v3.4 +)。

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.