在新daemon.json配置文件中修复

在新daemon.json配置文件中修复

2020 年编辑:这是一个六年前的问题。我当时从未弄清楚如何解决这个特定问题,但 Docker 和其他相关内容都在继续发展。SE 不允许我删除我的问题,但它不再相关。

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

怎么办?

答案1

当 Ubuntu Docker 软件包更新为使用 systemd 时,它不再支持/etc/default/docker配置文件,因此最初的解决方案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 服务器:

# /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 文件

答案2

我自己不使用docker,所以我通常不会在这里插话讨论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

我在我的处境中遇到了这个问题,具体来说

  • 在我的本地开发机器上运行 Docker 容器
  • 已连接到 VPN
  • 我们的一些容器构建脚本会执行npm install从自定义存储库运行等操作在 VPN 上,在容器内。
    • 这在 CI 管道中是可行的,但在开发人员的机器上却行不通,因为npm无法成功进行 DNS 查找
    • 我们还遇到了需要查找以调用外部 REST API 的容器问题

Ubuntu 默认使用dnsmasqNetworkManager 启动的缓存 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 适配器上的 DNS 服务器的路由tap0
  • 因此,容器中的所有 DNS 查找都会失败,因为它无法访问其唯一提供的 DNS 服务器
  • 此外,一些网络会阻止对 Google DNS 服务器的请求,因为他们希望能够窥探您的所有 DNS 查找

解决方案 :

dnsmasq按照设计的方式使用 NetworkManager 和它的绑定实例似乎更加优雅。

  1. 告诉 Docker 使用你的dnsmasq实例进行 DNS

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

      {
        "dns": ["172.17.0.1"]
      }
      
  2. 配置 NMdnsmasq实例以监听 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 时,您的 Docker 容器应该能够nslookup毫无问题地运行,无论是 VPN 内部还是外部的域。

答案4

我遇到了类似的问题,将其报告给 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得出一个自动化的解决方案。

相关内容