Network bonding and teaming both combine multiple physical network interfaces into a single logical link, providing redundancy, increased throughput, or both. On RHEL 8, NetworkManager is the recommended way to configure both technologies using the nmcli command-line tool — no manual edits to legacy ifcfg files required. This tutorial covers creating an active-backup bond with two slaves, bringing the bond online with a static IP, and then demonstrates the equivalent workflow using Network Teaming. A comparison of the two approaches at the end helps you choose the right tool for your environment.
Prerequisites
- RHEL 8 server with at least two network interfaces (e.g.,
ens3andens4) - Root or sudo access
- NetworkManager installed and running (
systemctl status NetworkManager) - The interfaces
ens3andens4must not be the interface currently used for SSH access, or you will lose connectivity during configuration — use a third management interface or perform this from console/iDRAC - A static IP address planned for the bond (example uses
192.168.1.10/24)
Step 1 — Create the Bond Master Interface
The nmcli con add type bond command creates a virtual bond master connection. The bond.options parameter sets the bonding mode (active-backup for failover) and the link monitoring interval in milliseconds (miimon=100 checks link state every 100 ms).
# Create bond master with active-backup mode and 100ms MII monitoring
nmcli con add type bond
ifname bond0
con-name bond0
bond.options "mode=active-backup,miimon=100"
# Verify the master connection was created
nmcli con show bond0
Step 2 — Add Slave Interfaces to the Bond
Each physical interface that should be part of the bond is added as a bond-slave connection pointing to the bond0 master. Repeat this for every interface you want to include. Any existing connections on these interfaces should be deleted first to avoid conflicts.
# Remove any existing connections on the slave interfaces
nmcli con delete ens3 2>/dev/null || true
nmcli con delete ens4 2>/dev/null || true
# Add ens3 as a slave of bond0
nmcli con add type bond-slave
ifname ens3
con-name bond0-slave-ens3
master bond0
# Add ens4 as a slave of bond0
nmcli con add type bond-slave
ifname ens4
con-name bond0-slave-ens4
master bond0
# List connections to confirm both slaves are registered
nmcli con show
Step 3 — Assign a Static IP to the Bond and Bring It Up
Configure IPv4 addressing on the bond master connection, then bring up the master. NetworkManager automatically activates the slave connections as well. Verify the bond is active and that the kernel bond driver reports the correct active interface.
# Set static IP, gateway, and DNS on the bond master
nmcli con mod bond0
ipv4.method manual
ipv4.addresses 192.168.1.10/24
ipv4.gateway 192.168.1.1
ipv4.dns "8.8.8.8 8.8.4.4"
# Bring the bond and its slaves online
nmcli con up bond0
# Confirm the bond interface has the IP
ip addr show bond0
# Check which slave is currently active
cat /proc/net/bonding/bond0
Step 4 — Create a Network Team (Alternative to Bonding)
Network Teaming is the modern kernel-space alternative to bonding on RHEL 8. The team driver uses a JSON runner configuration. The activebackup runner is functionally equivalent to bonding’s active-backup mode but uses the teamd userspace daemon for policy decisions.
# Create team master interface with activebackup runner
nmcli con add type team
ifname team0
con-name team0
team.config '{"runner":{"name":"activebackup"}}'
# Add ens3 as a team port (slave)
nmcli con add type team-slave
ifname ens3
con-name team0-port-ens3
master team0
# Add ens4 as a team port (slave)
nmcli con add type team-slave
ifname ens4
con-name team0-port-ens4
master team0
# Configure static IP on the team master
nmcli con mod team0
ipv4.method manual
ipv4.addresses 192.168.1.20/24
ipv4.gateway 192.168.1.1
# Bring the team interface online
nmcli con up team0
Step 5 — Inspect Team State with teamdctl
The teamdctl utility provides detailed visibility into the team daemon state, including which port is active, link status, and runner configuration. Use it to confirm the team is functioning correctly after bringing it online.
# Show overall team state in human-readable format
teamdctl team0 state
# Show state as JSON for scripting
teamdctl team0 state dump
# Show configuration currently applied by teamd
teamdctl team0 config dump
# Verify IP assignment
ip addr show team0
# Test failover by taking ens3 down and checking state
ip link set ens3 down
teamdctl team0 state
ip link set ens3 up
Step 6 — Compare Bonding vs Teaming
Both technologies achieve the same goals but differ in architecture. Use this quick reference to choose the right one for your workload.
# Bonding: in-kernel driver, no extra daemon, wide compatibility
# Modes: balance-rr, active-backup, balance-xor, broadcast,
# 802.3ad (LACP), balance-tlb, balance-alb
# Config: nmcli con add type bond bond.options "mode=..."
# Monitor: cat /proc/net/bonding/bond0
# Teaming: userspace teamd daemon + kernel module teamd_t
# Runners: broadcast, roundrobin, activebackup, loadbalance, lacp
# Config: nmcli con add type team team.config '{"runner":{...}}'
# Monitor: teamdctl team0 state
# Summary:
# Use bonding for: maximum kernel compatibility, no extra daemon,
# traditional environments, containers
# Use teaming for: flexible JSON policy, per-port config tuning,
# integration with teamd D-Bus API
Conclusion
You have configured network bonding in active-backup mode on RHEL 8 using nmcli, added two physical slave interfaces, assigned a static IP to the bond master, and verified failover through the /proc/net/bonding interface. You also built the equivalent team interface using the teamd runner framework and inspected its state with teamdctl. Both approaches integrate cleanly with NetworkManager and persist correctly across reboots without manual edits to network scripts.
Next steps: Configuring LACP (802.3ad) Bonding with a Managed Switch on RHEL 8, Setting Up VLAN Tagging on a Bond Interface, and Monitoring Network Interface Health with ethtool on RHEL 8.