systemd-resolved 和 docker 应该如何交互?

yak*_*kom 10 networking linux dns systemd docker

节指定 Docker 容器获取主机的/etc/resolv.conf. 然而,当我在 Fedora 34 上运行一个简单的容器时,我得到了不同的结果:

$ cat /etc/resolv.conf
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.

...

nameserver 127.0.0.53
options edns0 trust-ad
search .
Run Code Online (Sandbox Code Playgroud)
$ docker run --rm -it alpine /bin/sh

/ # cat /etc/resolv.conf 
# This is /run/systemd/resolve/resolv.conf managed by man:systemd-resolved(8).
# Do not edit.

...

nameserver 192.168.0.1
nameserver 192.168.0.2
search .
Run Code Online (Sandbox Code Playgroud)

docker 容器获得了我的主接口的名称服务器,由以下人员维护systemd-resolved

$ resolvectl dns enp1s0
Link 2 (enp1s0): 192.168.0.1 192.168.0.2
Run Code Online (Sandbox Code Playgroud)

当我想访问互联网时这有效。但这是否意味着 Docker 以某种方式与 集成systemd-resolved

此外,我发现运行需要我的公司 VPN 连接的容器存在问题。据我了解,DNS 请求直接发送到我的路由器 (192.168.0.*),而不是发送到 VPN 设置的虚拟接口。--dns 127.0.0.53 --network host我通过向命令添加标志来人为地解决了这个问题docker run

仅使用标志是行不通的--dns为什么需要主机组网模式?毕竟,192.168.0.1 和 192.168.0.2 也不在容器的网络中,它们还能工作吗?

最后,我发现这个存储库似乎可以解决问题,但我不太明白它是如何工作的。有人可以更广泛地描述这个问题吗?

Dan*_*l B 10

是的,Docker 确实将 \xe2\x80\x9cintegrate\xe2\x80\x9d 与systemd-resolved结合起来:通过检测127.0.0.53然后不使用它。您可以在这里查看相关代码

\n
        if len(ns) == 1 && ns[0] == "127.0.0.53" {\n            pathAfterSystemdDetection = alternatePath\n            logrus.Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)\n        }\n
Run Code Online (Sandbox Code Playgroud)\n

然后,Docker 使用/run/systemd/resolve/resolv.conf ,这是systemd-resolved管理的非存根解析器文件。如果您的 DNS 客户端与systemd-resolved正确集成,则其 DNS 服务器也应该显示在此文件中,但仅在连接处于活动状态时才显示。

\n
\n

为什么没有它就不起作用--network host因为127.0.0.0/8内的地址只能在同一主机(或更准确地说:网络命名空间)上访问。这是一项重要的安全功能。在不同的网络命名空间内,127.0.0.0/8仅指该命名空间中的本地主机。使用 Docker\xe2\x80\x99s 默认 NAT 网络可以像平常一样访问不同的主机。

\n
\n

简单来说,您找到的项目是一个 DNS 解析器。所以基本上与systemd-resolved相同,除了它\xe2\x80\x99s 被编程为在 Docker 默认桥上侦听。请求被委托给systemd-resolved。事实上,它还做了更多的事情,比如解析容器名称等等。

\n