This project is inteded as an experiment to learn about network interface Bonding
in Ubuntu.
The aim of the experiment is to combine 4 network interfaces into a sigle link with a single IP address, using the examples found in the Ubuntu Documentation, and Netplan Documentation and to develop a set of Ansible
playbooks that automate this process as much as possible.
Vagrant
and VirtualBox
are used to setup a VM called testbed
running Ubuntu 22.04 that is configured with 5 network interfaces with static IP adresses. One of these is the service interface with IP 192.168.30.10
by which the VM can be acessed.
The commands below can be used to manage the testbed
:
# start
vagrant up
# connect with SSH
vagrant ssh
# suspend
vagrant suspend
# resume
vagrant resume
# stop and delete
vagrant destroy
To configure bonding with Ansible, a file called inventory
should contain the IP address
of the server, a username
with sudo permission and the path to the ssh private key
. After that, the set of ansible playbooks can be executed with the ansible-playbook
command.
This playbook is used check how the network is configured on the server and serves as a reference for the setup_bonding
playbook. It executes the ip
command with the appropiate arguments to print out network interfaces and IP information.
To execute playbook, run:
ansible-playbook playbooks/show_interfaces.yml -i inventory
This playbook needs to be provided with the folowing variables:
interfaces
: a comma separated list of interfacesbond_ip
: a static IP in the CIDR notationbond_gateway
: default gateway IP
It performs the following tasks:
-
Ensures kernel support for bonding in the OS
-
Binds the provided
interfaces
in a new interface calledbond0
Uses the template file
templates/netplan-config.j2
to create the/etc/netplan/01-bond-cfg.yaml
Netplan configuration file in the server.The template defines
bond0
with the folowing parametersmode: 802.3ad bond_lacp_rate: fast mii-monitor-interval: 1 transmit-hash-policy: layer2+3
and assigns it a static IP address with the provided
bond_ip
andbond_gateway
.This configuration uses a combination of Layer 2 (MAC address) and Layer 3 (IP address) information to determine which interface to send traffic over. This allows for a more even distribution of network traffic across all the interfaces in the bond, maximizing bandwidth.
It also provides fault tolerance by allowing the bond to continue functioning even if some of the interfaces fail or are disconnected. The remaining interfaces in the bond will continue to handle traffic, ensuring uninterrupted connectivity.
-
Applies the configuration by executing the
netplan apply
command
To execute playbook, run:
# replace the placholders with the intended values and run below to setup the bond
ansible-playbook playbooks/setup_bonding.yml \
-i inventory
-e interfaces="if_name_1,if_name_2,if_name_n" \
-e bond_ip="*.*.*.*/*" \
-e bond_gateway="*.*.*.*"
Example workflow to configure a 4 interface bond on the testbed:
-
Create a file called inventory and add the testbed access information to it
touch inventory echo "[testbed_server]" > inventory echo "192.168.30.10 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/testbed/virtualbox/private_key" >> inventory
-
Print out the network interfaces and ip information
ansible-playbook playbooks/show_interfaces.yml \ --ssh-extra-args="-o StrictHostKeyChecking=no" \ -i inventory
-
Configure a bond with the provided interfaces
ansible-playbook playbooks/setup_bonding.yml \ --ssh-extra-args="-o StrictHostKeyChecking=no" \ -i inventory \ -e interfaces="enp0s9,enp0s10,enp0s16,enp0s17" \ -e bond_ip="192.168.30.11/24" \ -e bond_gateway="192.168.30.1"
-
Print out the network interfaces and ip information again to verify the bond is correctly configured
ansible-playbook playbooks/show_interfaces.yml \ --ssh-extra-args="-o StrictHostKeyChecking=no" \ -i inventory