I'm trying to launch a container with systemd-nspawn (from the systemd-container package, version 241), but the container is not able to resolve host names. The host environment is PureOS 9.0, which is Debian-like and based on Ubuntu.
The container image was created using debootstrap and has systemd-container installed:
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
I'm launching the container from the image directory:
systemd-nspawn -qbD /var/lib/machines/bionic
From inside the container, I can access the host network:
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
But DNS resolution is failing:
root@bionic:~# ping google.com
ping: google.com: Temporary failure in name resolution
The container resolv.conf is what I would expect; it looks like a pretty standard local DNS resolver, which should be provided by the host systemd-resolved.
nameserver 127.0.0.53
I see the DNS resolver listening on the host:
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)
This is similar to a setup I was using before on Ubuntu without problem. I don't have any reason to believe this shouldn't work on PureOS or on my version of systemd. I'm guessing something is different in the host networking configuration, but I'm not sure what to check.
I found that my host was not running systemd-resolved or systemd-networkd by default. I started those services manually with no change in behavior. I also stopped NetworkManager, thinking it might be interfering, but no luck there either.
I had this issue while trying to use a commercial VPN on Linux. I was using a Systemd container with Debootstrap like you. I did some research and found out that Systemd containers have a lot of issues with DNS for two big reasons, writing code without writing documentation. Deploying something without testing on a network.
I also read some articles that were very telling by searching Google for “systemd container and vpn dns issues”. It turns out there are several things you should examine, but there is a right way of doing everything and that right way works. Check out some of my reading...
In this article the author views the DNS cache entry and finds an update has changed the symbolic link for
resolv.conf
.How to view DNS cache entries with the new systemd-resolved resolver
In this article they talk about the issue and how it is caused in the scenario of split DNS.
systemd-resolved: introduction to split DNS
How to fix it on Kubernetes 1.10 and earlier.
Solving Kubernetes DNS issues on systemd servers
An even easier solution is to remove Systemd or use a Linux distro without Systemd, but creating a Chroot or container other than a Systemd container is no easy way out. Of course, all the other considerations apply, but the real point of failure comes connecting and disconnecting to the nameserver. Systemd will use its own nameserver in
resolv.conf
. The real solution in my case of using a VPN was to create a kill switch that ensures if the connection to the DNS nameserver is lost, it is no longer trying to resolve DNS.What is a VPN Killswitch and How Does it Work?
This sort of problematic behavior is not exclusively related to Systemd containers, but occurs also in WSL2 in a similar fashion...
Fix DNS resolution in WSL2
Another worthy read!