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

systemd-resolved 和 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 .
$ 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 .

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

$ resolvectl dns enp1s0
Link 2 (enp1s0): 192.168.0.1 192.168.0.2

当我想访问互联网时,这个功能就起作用了。但这是否意味着 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 也不在容器的网络中,它们能正常工作吗?

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

答案1

是的,Docker 确实与systemd-已解决:通过检测127.0.0.53然后不使用它。你可以看到相关代码在这里

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

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


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


您找到的项目简单来说就是 DNS 解析器。因此基本上与systemd-已解决,但它被编程为监听 Docker 默认网桥。请求被委托给systemd-已解决。实际上,它还做了更多的事情,比如解析容器名称等等。

答案2

添加文件 /etc/systemd/resolved.conf.d/docker.conf 并包含以下数据:

[Resolve]
DNSStubListenerExtra=172.17.0.1

然后重新启动已解析的守护进程:

service systemd-resolved restart

现在 systemd-resolved 正在默认 docker 桥接网络上运行 DNS 服务器。

docker run --dns=172.17.0.1 ...

DNS 查找将通过您的 systemd-resolved 配置进行。

相关内容