In high-availability enterprise servers and virtualization hosts running KVM or LXC containers, network interfaces must deliver redundant failover and shared Layer 2 connectivity. While traditional desktop Ubuntu systems use NetworkManager, modern server installations rely on systemd-networkd. Providing lightweight daemon performance and deep systemd integration, systemd-networkd enables administrators to construct hardware link aggregations (LACP 802.3ad bonding) and virtual switch bridges using declarative configuration files.
Understanding Virtual Network Devices: NetDev vs Network Files
systemd-networkd separates device definition from IP assignment using two file types located in /etc/systemd/network/:
- .netdev files: Define virtual network devices (such as bonds, VLANs, and software bridges) and specify kernel-level parameters like hashing algorithms and bridge forwarding delays.
- .network files: Match physical or virtual interfaces and apply Layer 3 configurations, including static IP addresses, DHCP parameters, routing tables, and master enslavement rules.
Enabling and Transitioning to systemd-networkd
Ensure systemd-networkd is enabled and operational:
sudo systemctl enable --now systemd-networkd
sudo systemctl enable --now systemd-resolved
Inspect active network interfaces using networkctl:
networkctl status
The command lists all network links along with their operational states (such as routable, carrier, or unmanaged).
Creating a High-Throughput 802.3ad Network Bond
Network bonding combines multiple physical NICs (e.g., eth0 and eth1) into a single virtual pipe. Assume we want an active-backup or LACP 802.3ad trunk.
Create the virtual bond netdev definition:
sudo nano /etc/systemd/network/10-bond0.netdev
Add the following configuration specifying 802.3ad dynamic link aggregation with Layer 3+4 hash balancing:
[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=802.3ad
TransmitHashPolicy=layer3+4
MIIMonitorSec=100ms
LACPTransmitRate=fast
Enslave the physical interfaces to the bond:
sudo nano /etc/systemd/network/20-bond-slave.network
[Match]
Name=eth0 eth1
[Network]
Bond=bond0
Creating a Virtual Software Bridge for Hypervisors and Containers
To enable virtual machines and containers to share the physical bond directly on the local subnet, construct a software bridge (br0):
Create the bridge netdev definition:
sudo nano /etc/systemd/network/30-br0.netdev
[NetDev]
Name=br0
Kind=bridge
[Bridge]
DefaultPVID=none
STP=yes
Attach the bond0 aggregated interface as a member of br0:
sudo nano /etc/systemd/network/40-bond-to-bridge.network
[Match]
Name=bond0
[Network]
Bridge=br0
Assigning Static IP Addressing to the Bridge Interface
Because the physical interfaces and the bond are enslaved to the bridge, assign the server’s static IP address directly to br0:
sudo nano /etc/systemd/network/50-br0.network
[Match]
Name=br0
[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=1.1.1.1 9.9.9.9
Applying Configuration and Validating Links
Reload and restart systemd-networkd to apply the new network hierarchy:
sudo networkctl reload
sudo systemctl restart systemd-networkd
Validate the operational status of all links:
networkctl list
Confirm that eth0 and eth1 display master bond0, that bond0 displays master br0, and that br0 reports status routable with your assigned static IP address.