The vast majority of layer 4 load balancers use LVS in two-arm NAT mode. In this mode the load balancer can control all traffic and it's also source IP transparent.
The disadvantage of NAT mode is that the load balancer must be the default gateway for the servers, which can be a pain when you need to re-arrange the whole network to put servers behind the load balancer.
Loadbalancer.org did some work ages ago with the open source community to create SNAT mode, which is a bit like NAT without the need for being a default gateway. LVS-SNAT mode changes the source address of all the packets to be the load balancer so you don't need to change your default gateway (obviously Layer 4 SNAT is not source IP transparent)
BTW. DR mode also solves this problem while staying transparent (which is why we love it!)
NB. v8.3.1 includes full support for Layer 4 LVS-SNAT (so no need to keep reading this blog unless you are a geek who likes to know how things actually work!).
The rest of this blog is fairly old but still interesting.... so pretend you are in a time machine when you read it! (Also, feel free to check out our roadmap blog to see what we've got in the pipeline for future releases.)
Firstly this is all very bleeding edge and as yet has not made it into the current kernel it should be in 2.6.36 with a new version of iptables released not long after that.
But for those of you far to eager to use this already here is what you do. N.B I will also go through the process of enabling it so if your reading this and 2.6.36 is available as is the latest version of iptables you can probably skip the start of this article.
The patches are available as part of the LVS list, Which Should be available here http://archive.linuxvirtualserver.org/html/lvs-devel/2010-07/msg00033.html
There are 4 patches in all that you need to implement. There is also a Git repository available (at the time of writing) to get a patched version of 2.6.35-rc1. Firstly you need to install GIT
Then
git clone -b full-nat
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git
For instructions on building your kernel see http://howtoforge.com/kernel_compilation_centos_p2 which is the method that I used, feel free to use your own should you require.
When you come to your make menuconfig section please make sure you enable LVS and Netfilter making sure you enable ipvs match support which can be found ->
Networking support
Networking Options
Network packet filtering framework (Netfilter)
Core Netfilter Configuration
"ipvs" match support
then
make all
make modules_install
make install
and reboot into your new kernel version.
Once you have that running you must make sure that the xt_ipvs module was installed so a quick search
find / -name xt_ipvs.*
should turn it up in your /lib/modules folder if its not there you need to check that it was enabled correctly in your kernel config.
Right now thats done time to rebuild iptables -
for this your looking for the patch "[patch v2.7 4/4] libxt_ipvs: user-space lib for netfilter matcher xt_ipvs"
which will patch iptables
I downloaded their latest version http://www.netfilter.org/projects/iptables/files/iptables-1.4.8.tar.bz2
and untared it to /usr/src then copied the patch into the iptables-1.4.8 direcory then patched it.
Then ran a
make install
after all that you should be ready to go!
Im going to detail my setup -
The Loadbalancer
IPVS 1.2.1
iptables 1.4.8 --patched
kernel - 2.6.35-rc1 --patched
eth0 ip 192.168.17.93
eth0:45 192.168.18.21 (I would have used eth1 but couldn't find a test box spare with 2 network cards in)
My test box -
eth0 192.168.18.1
The Webserver -
192.168.17.4:80
Commands to setup ipvs and iptables
IPVS
ipvsadm -A -t 192.168.18.21:80 -s rr
ipvsadm -a -t 192.168.18.21:80 -r 192.168.17.4:80 -m
iptables
/usr/local/sbin/iptables -t nat -A POSTROUTING -m ipvs --vaddr 192.168.18.21/24 --vport 80 -j SNAT --to-source 192.168.17.93
iptables shows -
iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- anywhere anywhere vaddr 192.168.18.0/24 vport 80 to:192.168.17.93
ipvsadm shows -
ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.18.21:80 rr
-> 192.168.17.4:80 Masq 1 0 0
Connected to the IP from my browser page loaded fine and you can see in the apache log -
"192.168.17.93 - - [21/Jul/2010:08:44:00 -0400] "GET / HTTP/1.1" 200 82"
If all that worked you should be ready to go! HAPPY SNATTING (is that even a word, ah well it is now).
Mark