我正在尝试使用 systemd-nspawn(来自 systemd-container 包,版本 241)启动容器,但容器无法解析主机名。主机环境是 PureOS 9.0,它类似于 Debian 并基于 Ubuntu。
该容器镜像是使用 debootstrap 创建的,并且安装了 systemd-container:
debootstrap \
--components main,restricted,universe \
--include systemd-container \
bionic /var/lib/machines/bionic http://archive.ubuntu.com/ubuntu/
echo bionic > /var/lib/machines/bionic/etc/hostname
我正在从图像目录启动容器:
systemd-nspawn -qbD /var/lib/machines/bionic
从容器内部,我可以访问主机网络:
root@bionic:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=114 time=130 ms
但 DNS 解析失败:
root@bionic:~# ping google.com
ping: google.com: Temporary failure in name resolution
容器 resolv.conf 正是我所期望的;它看起来像一个相当标准的本地 DNS 解析器,应该由主机 systemd-resolved 提供。
nameserver 127.0.0.53
我看到 DNS 解析器正在主机上监听:
root@host:~$ lsof -i -Pn | grep LISTEN | grep 53
systemd-r 6957 systemd-network 13u IPv4 5300137 0t0 TCP 127.0.0.53:53 (LISTEN)
systemd-r 7252 systemd-resolve 12u IPv4 5313025 0t0 TCP *:5355 (LISTEN)
systemd-r 7252 systemd-resolve 14u IPv6 5313028 0t0 TCP *:5355 (LISTEN)
这与我之前在 Ubuntu 上使用的设置类似,没有问题。我没有任何理由相信这在 PureOS 或我的 systemd 版本上不起作用。我猜主机网络配置有些不同,但我不确定要检查什么。
我发现我的主机默认没有运行 systemd-resolved 或 systemd-networkd。我手动启动了这些服务,但行为没有任何变化。我还停止了 NetworkManager,认为它可能会干扰,但也没有成功。
答案1
我在尝试在 Linux 上使用商业 VPN 时遇到了这个问题。我像您一样使用带有 Debootstrap 的 Systemd 容器。我做了一些研究,发现 Systemd 容器在 DNS 方面存在很多问题,主要有两个原因:编写代码而不编写文档。部署某些东西而不在网络上进行测试。
我还通过 Google 搜索“systemd 容器和 vpn dns 问题”阅读了一些非常有启发性的文章。事实证明,您应该检查几件事,但做每件事都有正确的方法,而且正确的方法有效。查看我的一些阅读材料...
在本文中,作者查看了 DNS 缓存条目,并发现更新已更改 的符号链接resolv.conf
。
如何使用新的 systemd-resolved 解析器查看 DNS 缓存条目
在本文中,他们讨论了这个问题以及在拆分 DNS 场景中它是如何引起的。
如何在 Kubernetes 1.10 及更早版本上修复此问题。
解决 systemd 服务器上的 Kubernetes DNS 问题
更简单的解决方案是删除 Systemd 或使用不带 Systemd 的 Linux 发行版,但创建 Systemd 容器以外的 Chroot 或容器并非易事。当然,所有其他考虑因素都适用,但真正的故障点在于连接和断开与名称服务器的连接。Systemd 将使用自己的名称服务器resolv.conf
。在我使用 VPN 的情况下,真正的解决方案是创建一个终止开关,以确保如果与 DNS 名称服务器的连接丢失,它不再尝试解析 DNS。
这种有问题的行为不仅仅与 Systemd 容器有关,而且在 WSL2 中也以类似的方式出现……
另一本值得一读的书!