I haven’t written a blog post for a while; like everyone else I’m working on other things and haven’t been able to dedicate any time towards blogging. However, on a slow Sunday morning I thought I’d take a quick look at ucarp which is a way to provide virtual IPs, ie. IP addresses that can failover to another server, should the one it’s running on stop working.
Frankly I don’t have a lot of experience providing highly available IP addresses (from now on I’ll call the virtual IPs or vips, though that’s probably not the right term). There are quite a few ways to achieve vips, such as using technologies like VRRP, Pacemaker, Corosync, Keepalived, ECMP/BGP, etc. All have their pros and cons, some are simpler than others…make your own well-informed decision. :)
For my particular purposes, at this time at least, I chose CARP.
There was a big kerfuffle back in the late 90’s about Cisco creating, and patenting, VRRP. OpenBSD was not happy with the situation, and created CARP. I’ve used CARP a lot over the years, especially with OpenBSD firewalls. So when it came time to do highly available virtual IPs with Linux, CARP seemed a good choice. I didn’t want to over-engineer too early, so using something simple like CARP seemed a good strategy.
PS. Use more OpenBSD!
UCARP allows a couple of hosts to share common virtual IP addresses in order to provide automatic failover. It is a portable userland implementation of the secure and patent-free Common Address Redundancy Protocol (CARP, OpenBSD’s alternative to the patents-bloated VRRP).
In Ubuntu the ucarp system/package provides CARP virtual IP capability.
$ dpkg --list ucarp Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-===============================================-============================-============================-=================================================================================================== ii ucarp 1.5.2-1+nmu1ubuntu1 amd64 user-space replacement to VRRP -- automatic IP fail-over
Once the ucarp package is installed, the /etc/network/interfaces file can be configured to use ucarp.
Below are a couple example sections from a ucarp configured network interface file. Please note that I am using bonding and VLANs as well as ucarp. Bonding and vlans are not required to use ucarp, but it’s fun so why not.
The primary node (node1):
# internal network auto bond0.777 iface bond0.777 inet static vlan-raw-device bond0 address 192.168.1.12 netmask 255.255.252.0 ucarp-vid 1 ucarp-vip 192.168.1.9 ucarp-password SHAREDSECRET ucarp-advskew 10 ucarp-advbase 1 ucarp-master yes
And here is a secondary (node2):
# internal network auto bond0.777 iface bond0.777 inet static vlan-raw-device bond0 address 192.168.1.13 netmask 255.255.252.0 ucarp-vid 1 ucarp-vip 192.168.1.9 ucarp-password SHAREDSECRET ucarp-advskew 20 ucarp-advbase 1 ucarp-master no
Once I configured the interfaces, I rebooted all the nodes.
Here’s the output from running ansible across all the nodes looking for the ucarp vip.
$ ansible -m shell -a "ip ad sh | grep bond0.777:ucarp" ucarp-node node1 | success | rc=0 >> inet 192.168.1.9/32 brd 192.168.1.9 scope global bond0.777:ucarp node2 | FAILED | rc=1 >> node3 | FAILED | rc=1 >>
As can be seen above, only one of the nodes has the ucarp vip. If I were to power off node2 one of the other nodes would obtain the vip. If you see more than one node with the same IP then likely ucarp is configured but the ucarp package is not installed.
Right now, to me ucarp’s only limitation is that it’s active/passive. However, ucarp is quite easy to setup and works well. Simplicity helps uptime too.
There are a few things I still have to investigate
While we are investigating other more complicated active/active HA processes for IP addresses, thanks to its simplicity I’m quite sure parts of my infrastructure will continue to use ucarp.