After I’ve had time to run my home lab for a while, I’ve started switching to a more up to date Linux distribution (instead of RancherOS.) I’m currently testing Ubuntu Server which leverages Systemd. Systemd-networkd is responsible for managing the network interface configuration and it differs in behavior compared to NetworkManager enough that we need to update the Home Lab Bridge CNI to handle it.
Previously the CNI was creating a bridge network adapter when the first container started up, but this causes problems with systemd because resolved (the DNS resolver component) was eventually failing to make DNS queries and networkd was duplicating IP addresses on both eth0 (the actual uplink adapter) and on cni0 because we were copying it over.
Prior to identifying this fix, I was experiencing issues where containers would work for a brief time, but then something would go wrong on the node host and it stopped being able to pull images and network traffic wasn’t routing between containers correctly.
After some digging, it looked like systemd was trying to use eth0 even though it had become enslaved to the cni0 bridge and the cni0 bridge interface effectively replaced it. The resolvectl command showed that cni0 had no configuration and only eth0 was configured.
|
|
The Fix
Instead of trying to create the bridge using my CNI, I instead changed cni0 to be created and managed by systemd. I created the following files.
This file changes eth0 to be bridged to cni0 and disables DHCP on this interface.
Note: This file name needs to be the same name as returned in networkctl status eth0 above, but is located in a different folder. Systemd uses this to know that the new file overrides the previous file.
/run/systemd/network/10-netplan-eth0.network -> /etc/systemd/network/10-netplan-eth0.network
|
|
This next file tells networkd that it needs to create the cni0 bridge. The MACAddress is the same MAC address as eth0 and I copied it from the networkctl status eth0 output. Interestingly, bridge interfaces usually take the MAC address of the first interface in the bridge (in this case, it should be eth0). Systemd should be doing the same thing as per this GitHub issue, however this was not working for me, so I explicitly added this option to ensure it does.
|
|
This final file tells networkd that it should enable DHCP and IPv6 autoconfig. If you need to disable IPv6, remove the IPv6AcceptRA line.
|
|
Then after rebooting, the host should come back up and should now work correctly. Networkctl should now show eth0 is enslaved to cni0.
|
|
resolvectl should now show that cni0 is being used for DNS queries instead of eth0.
|
|