Docker:容器在专用networking上找不到域
我试图找出相同的docker集装箱在不同的主机上运行的问题,其中一个容器可以在专用networking上find/ ping / nslookup域,另一个容器不能。 一个主机是OSX 10.11,另一个是Ubuntu 16.04。 两个运行docker1.12。 我正在使用docker-compose
来启动我的应用程序,并且我希望弄清楚正在发生什么事以及如何解决这个问题,或者我可以做出一些configuration更改,而不必诉诸硬编码域或IP地址,容器在两台主机上performance相同。
在我的OSX机器上,我有以下由我的域自动设置的DNS名称服务器:
osx:$ cat /etc/resolv.conf domain redacted.lan nameserver 172.16.20.19 nameserver 10.43.0.11
我知道,大多数OSX工具不使用resolv.conf
,但系统首选项>networking显示相同的设置。
我也有类似的设置在我的Ubuntu 16盒子(命令从https://askubuntu.com/questions/152593/command-line-to-list-dns-servers-used-by-my-system ):
ubu:$ cat /etc/resolv.conf nameserver 127.0.1.1 search redacted.lan ubu:$ nmcli device show eno1 | grep IP4.DNS IP4.DNS[1]: 172.16.20.19 IP4.DNS[2]: 10.43.0.11
然后,在OSX和Ubuntu上,我用这个开始我的容器:
$ docker run -it redacted_web bash
然后我运行这些命令来诊断我的问题:
$ apt-get update $ apt-get install -y dnsutils $ cat /etc/resolv.conf $ nslookup redacted.lan
在OSX上,最后2个命令的输出是:
root@d19f49322fda:/app# cat /etc/resolv.conf search local nameserver 192.168.65.1 root@d19f49322fda:/app# nslookup redacted.lan Server: 192.168.65.1 Address: 192.168.65.1#53 Name: redacted.lan Address: 172.18.0.23
在Ubuntu上,输出是:
root@91e82d652e07:/app# 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 search redacted.lan nameserver 8.8.8.8 nameserver 8.8.4.4 root@91e82d652e07:/app# nslookup redacted.lan Server: 8.8.8.8 Address: 8.8.8.8#53 ** server can't find redacted.lan: NXDOMAIN
我可以想到的可能的差异:
- 在OSX上有一个虚拟机运行docker,在Ubuntu上它是本地的
- 在Ubuntu上,docker使用
sudo
运行,可能会select不同的configuration设置
已更新答案(2017-06-20)
较新版本的Ubuntu(17.04+)不使用dnsmasq(它现在使用systemd-resolved)。 你会遇到与主机解决类似的问题,但原来的解决scheme在这里不再起作用。 事实上,Docker容器甚至不能与systemd-resolvd通信,因为它在一个容器内无法访问的位置运行自己的DNS。
在较新版本的Ubuntu上的一个好的解决scheme是把下面的configuration放在/etc/docker/daemon.json
(如果不存在,创build这个文件):
{ "dns": ["172.16.20.19", "10.43.0.11"], "dns-search": ["redacted.lan"] }
这使您可以configurationDNS服务器和search域。 上面的DNS IPs来自原始问题,但您也可以使用自己的自定义问题。 您可能想要匹配主机上的DNSconfiguration。 search域是可选的,你完全可以忽略该行(小心你的逗号!)。 再一次,你可能想要匹配你的主机。
本质上,这些daemon.json选项所做的是自动将DNSconfiguration和search域注入容器内的configuration文件中,以便在该守护程序上启动的任何容器。 这是必要的,因为由于systemd-resolved工作方式的限制,无法使用systemd-resolved从主机parsing容器内的DNS。 文档在这里和这里 。
原始答复
问题是主机正在使用dnsmasq来parsing私有IP,并且Docker没有在主机上使用dnsmasq。
简单的解决方法是closures主机上的dnsmasq 。
- 运行
sudo vi /etc/NetworkManager/NetworkManager.conf
- 注释掉这一行:
#dns=dnsmasq
- 运行
sudo service network-manager restart
现在,您应该能够使用泊坞窗容器,它将正确parsing您的私人DNS。
检查docker守护进程的启动脚本,它包括以下选项来调整创build容器时使用的DNS:
$ dockerd --help # ... --dns=[] DNS server to use --dns-opt=[] DNS options to use --dns-search=[] DNS search domains to use
在Ubuntu上,我相信这些设置在/etc/init.d/docker中读取的/ etc / default / docker中。 保留这些未设置应该默认为/etc/resolv.conf值。
更新: Docker的DNSnetworking文档有很多细节应该指向正确的方向。
如果容器的/etc/resolv.conf文件中没有其他名称服务器条目,则守护程序会将公有Google DNS名称服务器(8.8.8.8和8.8.4.4)添加到容器的DNSconfiguration中。
这看起来可能发生在你的情况。 filter正在寻找本地地址,我不认为这是发生在你的情况与172.16.0.0/12私人地址,但它是可能的。
您可能想知道主机的/etc/resolv.conf文件发生了什么变化。 docker守护进程有一个文件更改通知程序,它将监视主机DNSconfiguration的更改。
注意:文件更改通知程序依赖于Linux内核的inotifyfunction。 由于此function当前与覆盖文件系统驱动程序不兼容,因此使用“覆盖”的Docker守护程序将无法利用/etc/resolv.conf自动更新function。
如果发生这种情况,那么重新启动守护程序可能会解决这个问题,并且会显示您希望Docker在NetworkManager之后启动。
更新#2:查看这个github问题 ,他们也可能包括172.16.0.0/12,以避免与docker的桥接networking发生冲突。 如果你可以确保避免在Docker中使用同一个networking,那么在/ etc / defaults / docker中传递dns服务器可能会强制正确的行为。 这篇文章末尾还提到lxc会引起冲突,所以如果你已经安装了并且可以删除它,那么先试一试。