Direct Server Return

Ulric edited this page May 21, 2015 · 1 revision

Direct server return means that traffic from the client to the server goes through Pen, but the traffic from the server to the client does not. There are a number of advantages to doing it this way, especially when it comes to performance – the load balancer never has to touch the return traffic. There are disadvantages as well, for example the load balancer cannot do SSL termination and the servers need special configuration.

To activate direct server return, specify an interface with the dsr_if option, e.g:

sudo ./pen -df -O poll -O "dsr_if eth1" -S 2 -r

This means that Pen will listen for traffic on interface eth1 destined for the "virtual ip" and forward it to two backend servers with the addresses and The port :0 is special and means that all TCP traffic should be forwarded. To forward a single port, specify that instead, e.g. :80 for http.

Configuring Pen

The interface must be dedicated, i.e. it cannot have a configured IP address and it cannot be used for management. On Debian, such an interface might be configured like this in /etc/network/interfaces:

auto eth1
iface eth1 inet manual
        pre-up ifconfig $IFACE up
        post-down ifconfig $IFACE down

Configuring Backend Servers

The backend servers also need a bit of special configuration. In addition to the network interface that is connected to the network, they also need a loopback interface with the virtual ip. But they can't tell the world about it! Only Pen must know. The following commands accomplish this:

ifconfig lo:1
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

Health Check

Now we have load balancing set up: Pen will distribute traffic among the two backend server more or less evenly. But what happens when one of the backends goes away? Normally Pen would detect that and blacklist the server temporarily, but with the return traffic bypassing Pen, there is no way to do that.

What we can do, however, is use a separate script to test the backends. Here's an old example of that: