当前位置: 首页 > 面试题库 >

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

东门胤
2023-03-14
问题内容

症状是:主机具有适当的网络访问权限,但是在容器中运行的程序无法解析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。要检查是否是这种情况:
    • ps -e | grep dnsmasq在主机上运行。如果输出为空,则说明您没有在运行dnsmasq。
    • 检查主机的resolv.conf,它可能包含类似的条目nameserver 127.0.1.1。如果包含nameserver 127.0.0.53,您可能正在运行systemd-resolved而不是dnsmasq。如果是这样,您将无法使用该解决方案将DNS请求散布到dnsmasq(使用的那个listen-address=172.17.0.1)。systemd-resolved硬编码一个事实,即它仅在“ lo”接口上侦听,因此没有简单的方法来适应此解决方案。以下其他答案将与systemd-resolved一起使用。
  • Google的公共DNS已被过滤。运行host www.example.com 8.8.8.8。如果失败或超时,则说明您处于这种情况。

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


问题答案:

一个干净的解决方案是配置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


 类似资料:
  • 这只适用于许多配置,但当主机运行在谷歌的公共DNS被一些防火墙规则过滤的网络上时,显然就不适用了。 发生这种情况的原因是: Docker首先尝试在主机上和容器内配置相同的DNS服务器。 主机运行dnsmasq,这是一种DNS缓存服务。dnsmasq充当DNS请求的代理,因此主机中明显的DNS服务器是,即localhost. 主机的dnsmasq只侦听来自本地主机的请求,并阻止来自docker容器的

  • 问题内容: 我在组成2.9(在yml版本2.1中)的“自定义”桥网络中的“ Ubuntu 16.10服务器”上运行多个容器。我的大多数容器在内部都使用相同的端口,因此我无法使用“主机”网络驱动程序。我的容器都是通过专用属性链接在一起的。 但是,我还需要访问容器外部公开的服务。这些服务具有专用URL,其名称已在我公司的DNS服务器中注册。虽然我可以使用公共DNS并从容器中访问任何公共服务没有问题,但

  • 问题内容: 我在Mac上运行boot2docker。OSX版本10.9.3 boot2docker版本4.3.12 Docker版本0.12.0 boot2docker映像是一个使用virtualbox的无聊的盒子。我尝试了许多无用的盒子(例如stigkj / boot2docker)。他们都表现出这个问题。 如果我将ssh放入boot2docker映像并查看/etc/resolv.conf,则它

  • 让dhcp服务器收集到的主机名 加入 dns服务中? 尝试过dnsmasq这个集成了 dhcp和dns服务器的软件,但是在网上搜索时,没发现这样的用法. 尝试把 建立一个ddns服务,然后让每台电脑 进行 动态域名注册 ,但是这样每台电脑都需要配置,感觉有点麻烦 最终期望

  • 我在Centos7机器上安装了Docker,DNS不能在容器中工作。 因此,如果我在主机上运行,它将正确解析。但是,如果我执行,我会得到: 更新:这不仅发生在busybox上,在其他平台上也是如此。我的主要问题是无法运行从以下DockerFile构建的映像容器: docker-compose.yml: 这项服务运行良好,并在我的个人机器上运行最新的Ubuntu进行了测试

  • 稳定性: 2 - 稳定的 dns 模块包含两类函数: 1) 第一类函数,使用底层操作系统工具进行域名解析,且无需进行网络通信。 这类函数只有一个:dns.lookup()。例子,查找 iana.org: const dns = require('dns'); dns.lookup('iana.org', (err, address, family) => { console.log('IP