小编典典

当主机使用dnsmasq并且Google的DNS服务器受到防火墙保护时,DNS无法在docker容器中工作?

docker

症状是:主机具有适当的网络访问权限,但是在容器中运行的程序无法解析DNS名称(在进行更多调查之前,它似乎是“无法访问网络”)。

$ sudo docker run -ti mmoy/ubuntu-netutils /bin/bash
root@082bd4ead733:/# ping www.example.com
... nothing happens (timeout) ... ^C
root@082bd4ead733:/# host www.example.com
... nothing happens (timeout) ... ^C

docker映像mmoy / ubuntu-
netutils
是基于Ubuntu
pinghost附带的简单映像,在此很方便,因为网络断开了,我们无法使用apt install这些工具)

问题来自于以下事实:Docker自动将Google的公共DNS配置为容器内的DNS服务器:

root@082bd4ead733:/# cat /etc/resolv.conf 
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 8.8.8.8
nameserver 8.8.4.4

这仅适用于许多配置,但是当主机运行在某些防火墙规则过滤了Google的公共DNS的网络上时,显然不起作用。

发生这种情况的原因是:

  • Docker首先尝试在主机上和容器内配置相同的DNS服务器。
  • 主机运行dnsmasq(DNS缓存服务)。dnsmasq充当DNS请求的代理,因此主机中明显的DNS服务器/etc/resolve.confnameserver 127.0.1.1,即localhost。
  • 主机的dnsmasq仅侦听来自localhost的请求,并阻止来自Docker容器的请求。
  • 由于127.0.1.1在docker中无法使用,因此docker会退回到Google的公共DNS,而后者也不起作用。

DNS在Docker容器中损坏的原因可能有多种。这个问题(和答案)涵盖以下情况:

  • 使用dnsmasq。要检查是否是这种情况:
  • Google的公共DNS已被过滤。运行host www.example.com 8.8.8.8。如果失败或超时,则说明您处于这种情况。

在此配置中获得正确的DNS配置的解决方案是什么?


阅读 281

收藏
2020-06-17

共1个答案

小编典典

一个干净的解决方案是配置docker + dnsmasq,以便将来自docker容器的DNS请求转发到主机上运行的dnsmasq守护程序。

为此,您需要通过添加一个文件来配置dnsmasq来监听docker使用的网络接口/etc/NetworkManager/dnsmasq.d/docker- bridge.conf

$ cat /etc/NetworkManager/dnsmasq.d/docker-bridge.conf
listen-address=172.17.0.1

然后重新启动网络管理器以考虑配置文件:

sudo service network-manager restart

完成此操作后,您可以将172.17.0.1docker中的主机IP地址(即Docker中的主机IP地址)添加到DNS服务器列表中。可以使用以下命令行来完成:

$ sudo docker run -ti --dns 172.17.0.1 mmoy/ubuntu-netutils bash
root@7805c7d153cc:/# ping www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=86.6 ms

…或通过docker的配置文件/etc/docker/daemon.json(如果不存在则创建它):

$ cat /etc/docker/daemon.json                      
{
  "dns": [
    "172.17.0.1",
        "8.8.8.8",
        "8.8.4.4"
  ]
}

(如果dnsmasq失败,它将退回到Google的公共DNS)

您需要重新启动Docker才能将配置文件考虑在内:

sudo service docker restart

然后,您可以照常使用docker:

$ sudo docker run -ti mmoy/ubuntu-netutils bash
root@344a983908cb:/# ping www.example.com
PING www.example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=86.3 ms
2020-06-17