连接到VPN后docker DNS配置未更新

Gér*_*aud 7 dns vpn auto-update docker

我在 Ubuntu 18.04 上使用 docker 19.03.9;docker 守护进程配置为自动启动。当我连接到我的雇主 VPN 时,docker DNS 配置不会更新,除非我重新启动 docker 守护进程。

有没有办法在主机 DNS 配置更改时自动更新 docker DNS 配置?

调查

我的场景:我想从家里ping 公司网络内的服务器(比如server.mycompany.com)。我正在尝试从我的主机(运行 Ubuntu 的笔记本电脑)ping 它,然后从我主机上的容器内

注意:以下示例中所有 IP 地址都被屏蔽了

我创建了一个小的 docker 镜像来测试我的场景:

FROM ubuntu:18.04

RUN apt-get update \
    && apt-get install -yqq iputils-ping

CMD cat /etc/resolv.conf \
    && echo \
    && ping -c 2 server.mycompany.com
Run Code Online (Sandbox Code Playgroud)

然后我建立了这个形象: docker build -t test_dns .

1- 没有 VPN 连接的测试

在我的 Ubuntu 笔记本电脑的终端中,我执行以下 3 个命令:

    $ 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    # run "systemd-resolve --status" to see details about the actual nameservers.

    nameserver 127.0.0.53
    search home

    $ ping server.mycompany.com
    ping: server.mycompany.com: Name or service not known

    $ docker run test_dns
    # This file is managed by man:systemd-resolved(8). Do not edit.
    #
    # This is a dynamic resolv.conf file for connecting local clients directly to
    # all known uplink DNS servers. This file lists all configured search domains.
    #
    # Third party programs must not access this file directly, but only through the
    # symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
    # replace this symlink by a static file or a different symlink.
    #
    # See man:systemd-resolved.service(8) for details about the supported modes of
    # operation for /etc/resolv.conf.

    nameserver 192.168.xxx.xxx
    nameserver 198.235.yyy.yyy
    search home

    ping: server.mycompany.com: Name or service not known
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,server.mycompany.com 无法解析并且无法访问(既不能从我的主机也不能从容器访问)

注意:

  • 192.168.xxx.xxx 是我的wifi路由器IP地址
  • 198.235.yyy.yyy是我的ISP DNS服务器地址

2- 连接到我公司的 VPN 后

连接到 mycompany VPN 后,我执行 3 个相同的命令:

    $ 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 10.xxx.xxx.xxx
    nameserver 10.yyy.yyy.yyy
    nameserver 10.zzz.zzz.zzz
    nameserver 127.0.0.53

    search mycompany.com mycompany-other-domain.com home

    $ ping -c 2 server.mycompany.com
    PING server.mycompany.com (10.sss.sss.sss) 56(84) bytes of data.
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=1 ttl=120 time=15.6 ms
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=2 ttl=120 time=16.4 ms

    --- server.mycompany.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1000ms
    rtt min/avg/max/mdev = 15.681/16.058/16.435/0.377 ms

    $ docker run test_dns
    # This file is managed by man:systemd-resolved(8). Do not edit.
    #
    # This is a dynamic resolv.conf file for connecting local clients directly to
    # all known uplink DNS servers. This file lists all configured search domains.
    #
    # Third party programs must not access this file directly, but only through the
    # symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
    # replace this symlink by a static file or a different symlink.
    #
    # See man:systemd-resolved.service(8) for details about the supported modes of
    # operation for /etc/resolv.conf.

    nameserver 192.168.xxx.xxx
    nameserver 198.235.yyy.yyy
    search home

    ping: server.mycompany.com: Name or service not known
Run Code Online (Sandbox Code Playgroud)
  • 在我的主机上:

    连接到 mycompany VPN 已更新 DNS 配置:我们可以看到mycompany 3 个私有 DNS 服务器(10.xxx.xxx.xxx、10.yyy.yyy.yyy 和 10.zzz.zzz.zzz)

    正如预期的那样,server.mycompany.com 已通过我的 ping 请求解析并到达

  • 在容器中:

    Docker 仍在使用以前的 DNS 配置。它没有随主机 DNS 更改而更新(连接到 VPN 时)。

    有没有办法让 docker 自动更新其 DNS 配置(当它在主机上更改时)?

3- 重新启动 docker 守护进程(仍然连接到我公司的 VPN)

我重新启动 docker 守护进程: sudo service docker restart

然后我再次执行 3 个相同的命令:

    $ 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 10.xxx.xxx.xxx
    nameserver 10.yyy.yyy.yyy
    nameserver 10.zzz.zzz.zzz
    nameserver 127.0.0.53

    search mycompany.com mycompany-other-domain.com home

    $ ping -c 2 server.mycompany.com
    PING server.mycompany.com (10.sss.sss.sss) 56(84) bytes of data.
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=1 ttl=120 time=23.3 ms
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=2 ttl=120 time=11.7 ms

    --- server.mycompany.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 999ms
    rtt min/avg/max/mdev = 11.786/17.551/23.317/5.767 ms

    $ docker run test_dns
    # 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 10.xxx.xxx.xxx
    nameserver 10.yyy.yyy.yyy
    nameserver 10.zzz.zzz.zzz
    search mycompany.com mycompany-other-domain.com home

    PING server.mycompany.com (10.sss.sss.sss) 56(84) bytes of data.
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=1 ttl=119 time=11.5 ms
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=2 ttl=119 time=10.7 ms

    --- server.mycompany.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 10.750/11.159/11.569/0.422 ms
Run Code Online (Sandbox Code Playgroud)
  • 在我的主机上:仍然完美运行:server.mycompany.com 仍然可以解析并且可以访问

  • 在容器中:docker DNS 配置现在使用 mycompany VPN 设置;server.mycompany.com 现在可以通过我在任何 docker 容器内的 ping 请求来解析和访问。

4- 与我公司的 VPN 断开连接

我断开与 mycompany VPN 的连接,并再次执行 3 个相同的命令:

    $ 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 127.0.0.53

    search home

    $ ping -c 2 server.mycompany.com
    ping: server.mycompany.com: Name or service not known

    $ docker run test_dns
    # 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    search home

    nameserver 8.8.8.8
    nameserver 8.8.4.4

    ping: server.mycompany.com: Name or service not known
Run Code Online (Sandbox Code Playgroud)
  • 在我的主机上:与第 1 步完全相同的行为:我在 mycompany 网络之外,因此既无法解析也无法访问 server.mycompany.com

  • 在容器中:这次,DNS 配置已自动更新为使用 Google 公共 DNS 服务器。server.mycompany.com 既无法解析也无法访问(如预期)

5- 再次连接到我公司的 VPN

我再次连接到 mycompany VPN,并再次执行 3 个相同的命令:

    $ 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 10.xxx.xxx.xxx
    nameserver 10.yyy.yyy.yyy
    nameserver 10.zzz.zzz.zzz
    nameserver 127.0.0.53

    search mycompany.com mycompany-other-domain.com home

    $ ping -c 2 server.mycompany.com
    PING server.mycompany.com (10.sss.sss.sss) 56(84) bytes of data.
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=1 ttl=120 time=20.5 ms
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=2 ttl=120 time=12.3 ms

    --- server.mycompany.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 12.308/16.442/20.577/4.136 ms

    $ docker run test_dns
    # 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
    # 127.0.0.53 is the systemd-resolved stub resolver.
    nameserver 10.xxx.xxx.xxx
    nameserver 10.yyy.yyy.yyy
    nameserver 10.zzz.zzz.zzz
    search mycompany.com mycompany-other-domain.com home

    PING server.mycompany.com (10.sss.sss.sss) 56(84) bytes of data.
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=1 ttl=119 time=13.2 ms
    64 bytes from 10.sss.sss.sss (10.sss.sss.sss): icmp_seq=2 ttl=119 time=14.3 ms

    --- server.mycompany.com ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 13.257/13.791/14.325/0.534 ms
Run Code Online (Sandbox Code Playgroud)
  • 在我的主机上:再次连接到 VPN 时 DNS 配置已更改;因此可以解析并再次访问 server.mycompany.com

  • 在容器中:这次,DNS 配置已自动更新为使用 mycompany DNS 服务器!!可以解析和访问 server.mycompany.com。

6- 结论和问题:

  • 为什么 docker 在第 2 步和第 5 步中表现不同?这些步骤有何不同?
  • 有没有办法让 docker 在步骤 2 中自动更新其 DNS 配置?
  • 这是 docker 守护进程中的错误吗?

toi*_*ine 3

  1. 停止 docker 服务:(sudo systemctl stop docker或者如果您通过 snap 安装了 docker sudo snap stop docker:)
  2. 重启systemd解决:sudo service systemd-resolved restart
  3. 再次启动 docker 服务:(sudo systemctl start docker或 snap sudo snap start docker:)。

我在 Ubuntu 20.04 上尝试了一切(从添加 docker dns 参数到DOCKER_OPTS删除docker0网络接口并重新创建),但最终解决的还是上述步骤

之后,只能在我连接的 VPN 后面解析的主机名在运行的 docker 容器内以及在 docker 构建步骤期间进行解析。