docker.io DNS 不起作用,它正在尝试使用 8.8.8.8

Rem*_*ich 35 networking dns 14.04 docker

2020 年编辑:这是一个 6 年前的问题。那时我从来没有想过如何解决这个特定的问题,但 Docker 和其他所有相关的东西都在继续前进。SE 不允许我删除我的问题,但它不再相关。

我有一个新的 Ubuntu 14.04 安装,并且想使用 Docker 来运行我需要 12.04 的旧东西。Docker 内部的 DNS 不起作用。

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

nameserver 127.0.0.1
Run Code Online (Sandbox Code Playgroud)

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

$ sudo docker run -i -t ubuntu /bin/bash
Run Code Online (Sandbox Code Playgroud)

它说:

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]
Run Code Online (Sandbox Code Playgroud)

果然,在 Docker 实例中,resolv.conf 看起来像:

nameserver 8.8.8.8
nameserver 8.8.4.4
Run Code Online (Sandbox Code Playgroud)

我可以从 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)
Run Code Online (Sandbox Code Playgroud)

怎么办?

Rob*_*low 26

当 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
Run Code Online (Sandbox Code Playgroud)

如果不存在,请打开或创建,/etc/docker/daemon.json然后添加要使用的 DNS 服务器:

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}
Run Code Online (Sandbox Code Playgroud)

重启 docker 守护进程:

$ sudo service docker restart
Run Code Online (Sandbox Code Playgroud)

我写了一篇深入的博客文章,如果您想了解更多详细信息,还提交了有关此问题的错误

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


小智 16

我自己不使用 docker,所以我通常不会在这里讨论 docker 问题,但我碰巧正在阅读它并偶然发现了一些似乎解决这个确切问题的docker 文档。总结...

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

docker_OPTS="--dns 8.8.8.8"
Run Code Online (Sandbox Code Playgroud)

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

sudo restart docker
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是通过/etc/NetworkManager/NetworkManager.conf像这样注释掉配置来禁用 NetworkManager 中的 dnsmasq :

#dns=dnsmasq
Run Code Online (Sandbox Code Playgroud)

然后,重新启动两者

sudo restart network-manager
sudo restart docker
Run Code Online (Sandbox Code Playgroud)

  • 禁用 dnsmasq 对我有用。 (3认同)
  • 后一种方法当然意味着网络管理器无法控制 dnsmasq,这意味着例如,当您更改网络(包括切换到 VPN)时,它无法更改您的 dns 服务器。前一种方法对我来说似乎更好,但我希望能够让 dnsmasq 也监听 docker IP (172.17.0.1),这样我就可以指向 docker 主机。 (2认同)

Adr*_*ian 9

我在我的情况下遇到了这个,特别是

  • 在我的本地开发机器上运行 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 服务器
  • /etc/resolv.conf默认情况下,Docker 会将您的影子映射到容器
    • 通常在 Ubuntu 上,它会将 Google DNS 服务器传递给容器(因为它知道dnsmasq情况。
    • 但是很高兴将 VPN DNS 服务器配置传递给容器
    • 没有从docker0网桥上的容器到 VPNtap0适配器上的 DNS 服务器的路由。
  • 因此,容器中的所有 DNS 查找都失败了,因为它无法访问它提供的唯一 DNS 服务器
  • 此外,某些网络会阻止对 Google DNS 服务器的请求,因为它们希望能够窥探您的所有 DNS 查找

解决方案 :

使用 NetworkManager 似乎更优雅,并且它的dnsmasq设计方式是俘虏实例。

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

  2. 将 NMdnsmasq实例也配置为侦听 Docker 网桥,因为默认情况下它只侦听 127.0.1.1 - 创建文件/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我不喜欢那个 VPN 客户端的粗鲁行为,我宁愿只在 VPN 端使用 DNS 进行 VPN 查找(如果你有一个礼貌的 VPN 客户端,它使用正确配置的 NetworkManager,你就不必这样做)

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

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

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

    sudo service network-manager restart
    sudo service docker restart
    
    Run Code Online (Sandbox Code Playgroud)

此时,nslookup当您在 VPN 上时,您的 Docker 容器应该能够正常工作,无论是在 VPN 内部还是外部域。