当前位置: 首页>>技术教程>>正文


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

, , ,

问题描述

我安装了新的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)

怎么办?

最佳办法

当Ubuntu Docker软件包更新为使用systemd时,它放弃了对/etc/default/docker配置文件的支持,因此初始解决方案suggested by rocketman10404将不再起作用(禁用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

如果您需要更多详细信息,我也写了an in-depth blog postfiled a bug

(最初,我通过打开/lib/systemd/system/docker.service并将其添加到ExecStart行中来解决该问题,但这很糟糕-我们shouldn’t edit systemd files directly。)

次佳办法

我自己不使用docker,因此通常不会在docker问题上使用butt-in,但是我只是偶然在阅读有关内容,偶然发现了一些出现在address this exact problem的docker文档。到sum-up …

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

docker_OPTS="--dns 8.8.8.8"

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

sudo restart docker

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

#dns=dnsmasq

然后,重新启动

sudo restart network-manager
sudo restart docker

第三种办法

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

  • 在我的本地开发机器上运行Docker容器

  • 哪个连接到VPN

  • 我们的某些容器构建脚本执行的操作类似于从容器内VPN上的自定义存储库运行npm install

    • 此操作通过CI管道进行,但不适用于我们的开发人员计算机,因为npm无法成功进行DNS查找

    • 我们还遇到了容器的问题,需要进行查找才能调用外部REST API


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

  • 我们正在使用的VPN客户端与NetworkManager不兼容,并强制使用其自己的/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": ["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
    

此时,对于您的VPN内外域,在使用VPN时,您的Docker容器应该能够执行nslookup,而不会出现问题。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/7975.html,未经允许,请勿转载。