Docker 码头工人:集装箱罐';无法在专用网络上找到域

Docker 码头工人:集装箱罐';无法在专用网络上找到域,docker,docker-compose,Docker,Docker Compose,我试图找出在不同主机上运行相同docker容器的问题,其中一个容器可以在专用网络上找到/ping/nslookup域,而另一个容器则不能。一台主机是OSX 10.11,另一台是Ubuntu 16.04。两者都运行docker 1.12。我正在使用docker compose来启动我的应用程序,我希望弄清楚发生了什么以及如何修复它,或者我可以进行一些配置更改,而不必求助于硬编码域或ip地址,这将使容器在两台主机上的行为相同 在我的OSX框中,我的域自动设置了以下dns名称服务器: osx:$ ca

我试图找出在不同主机上运行相同docker容器的问题,其中一个容器可以在专用网络上找到/ping/nslookup域,而另一个容器则不能。一台主机是OSX 10.11,另一台是Ubuntu 16.04。两者都运行docker 1.12。我正在使用
docker compose
来启动我的应用程序,我希望弄清楚发生了什么以及如何修复它,或者我可以进行一些配置更改,而不必求助于硬编码域或ip地址,这将使容器在两台主机上的行为相同

在我的OSX框中,我的域自动设置了以下dns名称服务器:

osx:$ cat /etc/resolv.conf
domain redacted.lan
nameserver 172.16.20.19
nameserver 10.43.0.11
我知道大多数OSX工具都不使用
resolv.conf
,但System Preferences>Network显示相同的设置

我在Ubuntu 16上也有类似的设置(命令来自):

然后,在OSX和Ubuntu上,我用以下内容启动容器:

$ docker run -it redacted_web bash
然后我运行以下命令来诊断我的问题:

$ apt-get update
$ apt-get install -y dnsutils
$ cat /etc/resolv.conf
$ nslookup redacted.lan
在OSX上,最后两个命令的输出为:

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的vm,而在ubuntu上它是本地的
  • 在Ubuntu上,docker使用
    sudo
    运行,可能会选择不同的配置设置

检查docker守护程序的启动脚本,它包括以下选项,用于调整创建容器时使用的DNS:

$ dockerd --help
# ...
  --dns=[]                                 DNS server to use
  --dns-opt=[]                             DNS options to use
  --dns-search=[]                          DNS search domains to use
在Ubuntu上,我相信这些设置在/etc/default/docker中,由/etc/init.d/docker读取。保留这些未设置值应默认为/etc/resolv.conf值


更新:文档中有很多细节,可以为您指明正确的方向

如果容器的/etc/resolv.conf文件中没有其他名称服务器条目,则守护进程会将公共Google DNS名称服务器(8.8.8.8和8.8.4.4)添加到容器的DNS配置中

这看起来像是在你的情况下发生的。过滤器正在寻找本地地址,我认为在您使用172.16.0.0/12私有地址的情况下不会发生这种情况,但这是可能的

您可能想知道当主机的/etc/resolv.conf 文件更改。docker守护程序有一个文件更改通知程序处于活动状态 它将监视主机DNS配置的更改

注意:文件更改通知程序依赖于Linux内核的inotify 特色。因为此功能当前与不兼容 覆盖文件系统驱动程序,使用“覆盖”的Docker守护程序将不会 能够利用/etc/resolv.conf自动更新功能

如果发生这种情况,则重新启动守护进程可能会解决此问题,并表明您希望Docker在NetworkManager之后启动


更新#2:仔细查看,它们可能还包括172.16.0.0/12,以避免与docker的桥接网络发生冲突。如果您可以确保避免在docker内部使用相同的网络,那么在/etc/defaults/docker中传递dns服务器可能会强制执行正确的行为。文章末尾还提到了lxc会导致冲突,因此,如果您安装了lxc并可以将其删除,请先尝试一下。

更新答案(2017-06-20)

更新版本的Ubuntu(17.04+)不使用dnsmasq(它现在使用systemd解析)。您将在主机解析方面遇到类似的问题,但此处的原始解决方案不再有效。事实上,Docker容器甚至无法与systemd resolvd通信,因为它在容器内无法访问的位置运行自己的DNS

在较新版本的Ubuntu上,一个好的解决方案是将以下配置放入
/etc/docker/daemon.json
(如果该文件不存在,则创建该文件):

这允许您配置DNS服务器和搜索域。上面的DNS IP来自原始问题,但您也可以使用自己的自定义IP。您可能希望匹配主机上的DNS配置。搜索域是可选的,您可以完全省略该行(小心逗号!)。同样,您可能希望匹配您的主机

本质上,这些daemon.json选项所做的是自动将DNS配置和搜索域插入容器内的配置文件中,以查找在该守护进程上启动的任何容器。这是必要的,因为由于systemd解析工作方式的限制,您无法使用主机解析的systemd来解析容器中的DNS。这些文件是和


原始答案

问题是主机正在使用dnsmasq来解析私有IP,而Docker在主机上没有使用dnsmasq

简单的解决方法是关闭主机上的dnsmasq

  • 运行sudo vi/etc/NetworkManager/NetworkManager.conf
  • 注释掉这一行:
    #dns=dnsmasq
  • 运行
    sudo服务网络管理器重新启动

  • 现在,您应该能够使用docker容器,它将正确解析您的私有DNS。

    默认设置中似乎没有应用任何设置:
    $cat/etc/default/docker#使用docker#选择修改守护程序启动选项#DOCKER_OPTS=“--dns 8.8.8.8--dns 8.8.4.4”
    所有设置都被注释掉。继续编辑:那么这可能是一个实际的DOCKER错误吗?我的Ubuntu安装是开箱即用的16.04,而且
    127.0.1.1
    nameserver似乎是一个
    dnsmasq
    实例,因此,如果添加到14到16之间,而DOCKER过滤掉<代码> 127。< /Cord>命名空间,这意味着Ubuntu 16的默认行为不适用于默认的DoCKER。我不知道他们是否会认为这是DOCKER的错误,可能是Ubuntu的DOCK包。应该容易操作
    $ dockerd --help
    # ...
      --dns=[]                                 DNS server to use
      --dns-opt=[]                             DNS options to use
      --dns-search=[]                          DNS search domains to use
    
    {
        "dns": ["172.16.20.19", "10.43.0.11"],
        "dns-search": ["redacted.lan"]
    }