Keepalived and libvirt MACVTAP network interfaces
Keepalived is a routing software written in C that can be used to setup load balancing and high availiability for Linux machines.
NOTE: hypervisor is Debian 10 (Buster) with libvirt
and qemu/kvm
, virtual
machines also are Debian 10 (Buster).
Keepalived configuration
Install keepalived
:
$ apt install keepalived
Install nginx
, it will be use to check that keepalived is actually working:
$ apt install nginx
$ systemctl enable --now nginx
Configure keepalived
:
$ vi /etc/keepalived/keepalived.conf
---
global_defs {
enable_script_security # prevents tampering with the check script
script_user root # defines which user runs the check script
}
vrrp_script chk_nginx {
script "/opt/scripts/nginx-check.sh"
interval 2 # run script every 2 seconds
weight 2 # add 2 points if OK
}
vrrp_instance VI_1 {
interface enp2s0 # interface to monitor
virtual_router_id 51
priority 101 # MASTER 101, BACKUP 100
advert_int 1
nopreempt # comment to not have the VIP go back to MASTER
# -> when it comes back online
authentication {
auth_type PASS
auth_pass myPass # maximum 8 chars
}
virtual_ipaddress {
10.10.0.12/24 # VIP (Virtual IP Address)
}
track_script {
chk_nginx
}
}
Also add a script to check if nginx
is alive and well:
$ mkdir /opt/scripts
$ vi /opt/scripts/nginx-check.sh
---
#!/bin/sh
if [ -z "`pidof nginx`" ]; then
exit 1
fi
---
$ chmod 700 /opt/scripts/nginx-check.sh
$ chown root:root /opt/scripts/nginx-check.sh
Iptables configuration
VRRP as a protocol doesn’t provide much protection against session hijacking, to make it somewhat safer a bit of iptables love might help:
-A INPUT -i <interface_name> -s <ip_of_other_machine/subnet_cidr_prefix> -d 224.0.0.0/8 -p vrrp -j ACCEPT
-A OUTPUT -o <interface_name> -d 224.0.0.0/8 -p vrrp -j ACCEPT
libvirt and qemu/KVM caveats
In my case I have two virtual machine each configured with one MACVTAP virtual
network adapter.
Apparently libvirt MACVTAP network interfaces doesn’t actually pass all
traffic going from host to guests and vice versa.
This unfortunate behavior makes it impossible for keepalived to receive
packets, meaning that both machines will try to elavate themselves to MASTER
status.
To avoid this conflict, add trustGuestRxFilters='yes'
parameter to the
virtual network adapter config:
$ virsh edit <vm_name>
---
...
<interface type='direct' trustGuestRxFilters='yes'>
...
</interface>
...