How to add HA networking with Keepalived
Sep 15, 2015 19:00
Overview
This post outlines the HA network configuration I’ve been using in my homelab to failover HAProxy VIPs in case of network issues on my primary HAProxy node. All my work has been done inside of virtual machines but the same concepts will apply to physical hosts. I’ll assume you have a working HAProxy configuration. There is however, one item related to HAProxy which we’ll cover later.
Assumptions
- MASTER (primary HAProxy node) and BACKUP (secondary HAProxy node) are both running CentOS 7 with SELinux in “enforcing” mode.
- Both HAProxy nodes are attached to 3 distinct networks:
- Network 1 (VIP Net) on eth0 on which the layer 7 requests are entering. eth0 is also where the VIPs are being added during failover and failback.
- Network 2 (VRRP Net) on eth1 on which the two HAProxy nodes are sending Unicast VRRP traffic to one another
- Both nodes need to have a static address configured on eth1
- If you’re running VMs on OpenStack, make sure your security groups for MASTER and BACKUP are set to “-1”
- Network 3 (LB Net) on eth2 on which the HAProxy nodes are communicating with the backend nodes
Diagram
The network layout is probably best demonstrated with a diagram:
***********
* REQUEST *
***********
|
|
V
(VIP Net)
eth0............................eth0
| |
| |
---------- (VRRP Net) ----------
| MASTER |--eth1 <------> eth1--| BACKUP |
---------- ----------
| |
| |
eth2 eth2
| |
|...............................|
|
|
(LB Net)
|
|
************
* BACKENDS *
************
Implementation
Both nodes
# yum install keepalived -y
# cd /etc/keepalived; mv keepalived.conf{,.original}
# setsebool -P domain_kernel_load_modules=true
- Create /etc/keepalived/keepalived.conf with the following content:
MASTER node
vrrp_instance HAPROXY_VIPS {
state MASTER
interface eth1 # interface connected to VRRP net
virtual_router_id 51
priority 101 # number here must be > than on BACKUP
advert_int 1
unicast_src_ip <MASTER-vrrp-net-ip>
unicast_peer {
<backup-vrrp-net-ip>
}
authentication {
auth_type PASS
auth_pass 1111 # make it whatever you want, but only the first 8 chars will be used
}
virtual_ipaddress {
X.X.X.X/32 brd X.X.X.255 dev eth0 label eth0:0
X.X.X.Y/32 brd X.X.X.255 dev eth0 label eth0:1
X.X.X.Z/32 brd X.X.X.255 dev eth0 label eth0:2
}
}
BACKUP node
vrrp_instance HAPROXY_VIPS {
state BACKUP
interface eth1
virtual_router_id 51
priority 100 # must be lower than MASTER
advert_int 1
unicast_src_ip <BACKUP-vrrp-net-ip>
unicast_peer {
<master-vrrp-net-ip>
}
authentication {
auth_type PASS
auth_pass 1111 # same as MASTER
}
virtual_ipaddress {
X.X.X.X/32 brd X.X.X.255 dev eth0 label eth0:0
X.X.X.Y/32 brd X.X.X.255 dev eth0 label eth0:1
X.X.X.Z/32 brd X.X.X.255 dev eth0 label eth0:2
}
}
Optional
Prepend something like the following to keepalived.conf on both nodes if you want to receive an email when failover/failback occurs:
global_defs {
notification_email {
user@email.tld # replace with your email address
}
notification_email_from keepalived@localhost # replace with desired "FROM" address
smtp_server 127.0.0.1 # replace
smtp_connect_timeout 30
}
Testing
After the configuration is all in place, start up keepalived for the first time on both nodes:
# systemctl start keepalived
You should see your VIPs on eth0 on MASTER:
# ip a show eth0
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
...
inet X.X.X.X/32 brd X.X.X.255 scope global eth0:0
valid_lft forever preferred_lft forever
inet X.X.X.Y/32 brd X.X.X.X.255 scope global eth0:1
valid_lft forever preferred_lft forever
inet X.X.X.Z/32 brd X.X.X.255 scope global eth0:2
valid_lft forever preferred_lft forever
...
If the VIPs show up twice, it’s probably because you have network configuration files in place which are managing the IPs. The following commands should fix that:
# ifdown eth0:0 && mv /etc/sysconfig/network-scripts/ifcfg-eth0:0 /etc/sysconfig/network-scripts/ifcfg-eth0:0.bak
# ifdown eth0:1 && mv /etc/sysconfig/network-scripts/ifcfg-eth0:1 /etc/sysconfig/network-scripts/ifcfg-eth0:1.bak
# ifdown eth0:2 && mv /etc/sysconfig/network-scripts/ifcfg-eth0:2 /etc/sysconfig/network-scripts/ifcfg-eth0:2.bak
# systemctl restart keepalived
BACKUP should not have any of the VIPs on eth0
Failover
On BACKUP follow the logs:
# tailf /var/log/messages
On MASTER, take down eth1 to simulate a network failure:
# ifdown eth1
If all goes as planned, you should see something like the following in the log output on BACKUP:
...
Sep 15 19:41:47 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Transition to MASTER STATE
Sep 15 19:41:48 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Entering MASTER STATE
Sep 15 19:41:48 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) setting protocol VIPs.
Sep 15 19:41:48 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Sending gratuitous ARPs on eth0 for X.X.X.X
Sep 15 19:41:48 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Sending gratuitous ARPs on eth0 for X.X.X.Y
Sep 15 19:41:48 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Sending gratuitous ARPs on eth0 for X.X.X.Z
...
You should also see the VIPs on BACKUP now. MASTER should no longer have any of the VIPs.
Failback
On MASTER:
ifup eth2
On BACKUP:
# tail /var/log/messages
...
Sep 15 19:41:56 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Received higher prio advert
Sep 15 19:41:56 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) Entering BACKUP STATE
Sep 15 19:41:56 BACKUP Keepalived_vrrp[12345]: VRRP_Instance(HAPROXY_VIPS) removing protocol VIPs.
The VIPs should now show up on eth0 on MASTER and should no longer be on BACKUP.
Other Items
Keep in mind that Keepalived doesn’t manage the HAProxy service as would cluster software like Pacemaker. This means you’ll need to ensure that HAProxy is both enabled and started if you want to continue serving requests via HAProxy after the failover occurs. As such, HAProxy will need to be listening on the VIPs before failover. Normally, a service cannot bind to or listen on an IP that isn’t associated with any interface. This would be the case with BACKUP before failover and on MASTER after failover. To get around this, will need make a slight kernel parameter change on both nodes:
# sysctl -w net.ipv4.ip_nonlocal_bind=1 # immediate change # echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf # persistent change
You may have noticed the unicast parameters in keepalived.conf. Many tutorials simply use multicast (the default) for keepalived communication. I chose unicast because on many networks (including mine) ACLs on the firewall drop all multicast traffic. Unicast ensures that the VRRP communication is happening only between the two nodes running keepalived and all other hosts on the network (VRRP net) don’t see any of the VRRP advertisements.
If you find you’re still unable to get a working configuration, it may be the case that IPTables on either node is dropping VRRP communication. You could add a blanket allow rule on both nodes to resolve this issue or rule it out:
# iptables -I INPUT -i eth1 -j ACCEPT -m comment --comment "VRRP communication"