Sunday, May 25, 2008

simple load balancing with iptables

iptables has an extension called clusterip. Clusterip extension uses multicast arp feature to achieve load balancing. Let's say we have two web servers called web1(192.168.0.1) and web2(192.168.0.2) and a virtual ip (192.168.0.10) which will be accepting requests for these machines.

virtual ip:192.168.0.10
web1:192.168.0.1
web2:192.168.0.2

Virtual ip will accept the requests and load balance them between these two web servers.

on web1 server run:

# iptables -I INPUT -d 192.168.0.10 -i eth0 -p tcp --dport 80 -j CLUSTERIP --new --clustermac 01:02:03:04:05:06 --total-nodes 2 --local-node 1 --hashmode sourceip
# ifconfig eth0:1 192.168.0.10 netmask 255.255.255.0 up

on web2 server run:
# iptables -I INPUT -d 192.168.0.10 -i eth0 -p tcp --dport 80 -j CLUSTERIP --new --clustermac 01:02:03:04:05:06 --total-nodes 2 --local-node 2 --hashmode sourceip
# ifconfig eth0:1 192.168.0.10 netmask 255.255.255.0 up

only difference between web1 and web2 commands is local-node option as seen above.
now any web requests coming to 192.168.0.10 will be load balanced between web1 and web2.

clusterip supports three hashmodes (sourceip,sourceip-sourceport and sourceip-sourceport-destport) to determine how to route requests to each servers.

This configuration has one drawback. If one of the nodes fall, the other one does not serves incoming requests for the other one. You need to install linux-ha.

If you want to see which requests served by web1 for example, simply run
# cat /proc/net/ipt_CLUSTERIP/192.168.0.1

Let's say web2 is crashed and we would like to first web server (web1) to take care the requests coming to web2.
on web1 server run:
# echo "+2" >> /proc/net/ipt_CLUSTERIP/192.168.0.1
now on, web1 will take the requests coming to web1.
When you up the web2 server, just run
# echo "-2" >> /proc/net/ipt_CLUSTERIP/192.168.0.1
and web1 will not serve the request for web2.