Wednesday, November 25, 2009

High Availability with FreeBSD and CARP

High Availability with FreeBSD and CARP

Introduction

Recently i was contacted to implement a content filter proxy using OpenSource tools. It is a very simple task to do, but my client asked to make the solution with HA (high availability) and Linux.

Well, Linux is a great operating system, but I have never built a Linux HA solution before, so I started to look for some information about the options I had.

My first search was for Linux clusters and I found them to be very complicate to build and manage. I needed my solution to be simple, fast, secure and easy to manage and implement.

During my research, I found some references to the CARP (Common Address Redundancy Protocol) protocol, a very smart and simple solution from the great folks at the OpenBSD project.

In a very simple way, the CARP protocol can make 2 or more network interfaces share the same IP address number. When the MASTER interface goes down, the BACKUP interface automagicaly takes its place.

It was not very difficult to find that CARP was ported to FreeBSD, NetBSD and with UCARP (Userland CARP) it is possible to use it under Linux too.

I like OpenBSD, but I am more comfortable working with FreeBSD, so it is my first option.

Now you may be asking, what about Linux? Why not use it?

In my opinion FreeBSD (and others BSDs as well) are better documented and, particularly, the FreeBSD handbook has almost everything you need to implement a good server. In Linux you have to look at various sites and search a lot to find some help. Maybe I am wrong, but it is my experience until now.

Implementation

I will not cover FreeBSD installation here. Look at FreeBSD handbook for more information. It is one of the best software documentations out there for an OpenSource OS.

On FreeBSD, CARP must be compiled in the kernel before using it. Build a new kernel is simple and take only a few minutes in current machines.

Follow these steps on all machines that will be using CARP:

- cd /usr/src/sys/i386/conf
- cp GENERIC GENERIC-CARP
- echo "device carp" >> GENERIC-CARP
- config GENERIC-CARP
- cd ../compile/GENERIC-CARP
- make depend
- make
- make install
- make clean
- shutdown -r now

Those steps will compile the carp into FreeBSD kernel and reboot the system so the changes will take effect.

To understand carp, lets see the options first.

- Preemption: When you have your hosts configured with carp they can use preemption. It will make possible for one host, the one with lower advskew, to always be authoritative for the address in the carp interface. If you don’t use preemption one of the backup’s machines may become a MASTER (when the original master fails), but when the original master is online again, it will be a BACKUP. Using preemption the original MASTER will recover it’s status as soon as it goes up again.

- vhid: This is a number indicating the group of the carp interface. You may have various carp groups to build very elaborated and complex HA solutions. Here we will be using only one group. More than one group may be used to build an arp balance solution (not covered here).

- pass: This is a passphrase used to authenticate the hosts on your carp group. You will be using the same password on all hosts for the same carp group.

- advskew: This number controls the frequency on witch the master send advertisements to the other hosts. The host with the lowest number will be MASTER. You can build an hierarchy of hosts using this, determining the order that must be used in case of failures. The higher this number less frequently the advertisements will be sent, so this host may be a backup if there are others with lower advsew.

This are the options used here. There are other options that can be reviewed by reading the manual pages for carp.

Our configuration is very simple. 2 hosts sharing 1 IP address. When the master goes down, the backup takes over the IP, when master comes back, it must be master again. I don’t want load balance here and just want to keep my services in case of failures.

The MASTER /etc/rc.conf must use a network configuration like this:

# Master net conf
defaultrouter="10.1.1.1"
hostname="master.localdomain"
cloned_interfaces="carp0"
ifconfig_em0="inet 192.168.200.1 netmask 255.255.255.0"
ifconfig_em1="inet 10.1.1.2 netmask 255.255.255.0"
ifconfig_carp0="inet 10.1.1.10 netmask 255.255.255.0 vhid 1 pass mypassword advskew 0"
# End master net conf

The BACKUP /etc/rc.conf must be like this:

# BACKUP net conf
defaultrouter="10.1.1.1"
hostname="backup.localdomain"
cloned_interfaces="carp0"
ifconfig_em0="inet 192.168.200.2 netmask 255.255.255.0"
ifconfig_em1="inet 10.1.1.3 netmask 255.255.255.0"
ifconfig_carp0="inet 10.1.1.10 netmask 255.255.255.0 vhid 1 pass mypassword advskew 100"
# End BACKUP net conf

On both hosts you must add the following line to /etc/sysctl.conf:

net.inet.carp.preempt=1

Notice: The 192.168.200 interfaces are connected directly to provide a faster route between the hosts so I can use it to sync files, share resources without compromising the real network. This interface is not used in the carp configuration that will work only using the other interfaces.

That’s it. Just reboot and all configuration will be up. To test it, ping the 10.1.1.10 address from a remote machine and shutdown the MASTER. You will see that the ping will not stop.

If you run an ifconfig, it will be possible to see the interfaces running:

MASTER ifconfig:

carp0: flags=41 mtu 1500
inet 10.1.1.10 netmask 0xffff0000
carp: MASTER vhid 1 advbase 1 advskew 0

BACKUP ifconfig:

carp0: flags=41 mtu 1500
inet 10.1.1.10 netmask 0xffff0000
carp: BACKUP vhid 1 advbase 1 advskew 100

Conclusion

Now you can configure your services to listen on carp0 interface. An HTTP, FTP or proxy server can be listening on this interface and when master goes down the backup will be up and running. You will only need to set up some synchronization for your files, to do this you can use rsync over ssh in a cron job or even share a remote storage to not waste space. The best solution is the one that fits your needs, so be creative and use this to increase your availability.

CARP is a very simple solution to a very common problem. The configuration is very easy to build and understand and it can be used to build different kinds of HA services.

I hope this article helps you. Please leave your comments.
4 Comments »

The URI to TrackBack this entry is: http://tmartins.blogsome.com/2006/07/28/high-availability-with-freebsd-and-carp/trackback/

1.

Hi! Have you try use carp with multicast (for ex. mrouted)?

Comment by Andrey — June 7, 2008 @ 10:59 am
2.

I have never used it with mrouted. Sice CARP is a multicast protocol that may be an easy task.

Try the OpenBSD documentation. There lots of info in there (http://www.openbsd.org/faq/faq6.html#CARP).

On FreeBSD I remember to see some posts in a mail list talking about problems with CARP after mrouted being configured. Is that your problem?

Comment by tmartins — June 7, 2008 @ 9:49 pm
3.

I think this line:

echo “options carp” >> GENERIC-CARP

Needs to be:

echo “device carp” >> GENERIC-CARP

Good article!

Comment by Justin — July 9, 2009 @ 3:28 pm
4.

Thanks Justin. You are right for newer FreeBSD versions. This article is old and I wrote it for FreeBSD 5. It was “options carp” back on 2006. :)

Now is “device carp”. The article was changed to reflect this.

Comment by Thiago — July 9, 2009 @ 3:50 pm

No comments: