Shane Rainville
I.T. professional with over a decade of experience, ranging from application development to system & infrastructure administration. He's worked with small startups to large corporate companies, using unique and creative solutions to solve problems.

Overview

HAProxy is a light-weight load balancer that is quick and easy to setup. Although it lacks a lot of the functionality found in enterprise balancers from companies like F5 and Citrix, it’s still a powerful server freely available on almost any Linux distro. I have used in many projects with low budgets that required load balancing.

As the name suggests, all balanced traffic is proxied through HAProxy. Therefore, when designing a load balance solution around it, it’s important to understand that all network traffic flows through it – from the incoming requests to outgoing responses.

FIG1 - All balanced traffic flows in and back out of the HAProxy server

FIG1All balanced traffic flows in and back out of the HAProxy server

You will need to size the network of the HAProxy server to be high enough to handle all traffic. When balancing a WordPress blog, for example, it’s unlikely that a single server will consume the entire bandwidth of your an HAProxy on a 1GbE connection. However, if the servers being balanced are serving large media movie files, for example, you’re HAProxy server is going to require a rather large network pipe to handle the requests for all of the backend servers. It certain doesn’t scale well at all when balancing large data, highly-accessed data.

Create Virtual IP

The virtual IP is the IP address users will use to connect to the load balanced application. This is the address you will register in DNS. In our example, the virtual IP will be assigned to ETH0 – our only network interface on the HAProxy server. In production it would be wise to separate balanced traffic and server management traffic onto different network interfaces.

    1. Open the network configuration file into a text editor.
      sudo nano /etc/network/interfaces
    2. Under the existing network interface, add a new interface using the same name with a colon (:) appended to the end. For example, the interface we’re attaching the virtual IP to is named ETH0. Therefore, our new virtual interface will be named ETH0:1.
      # This file describes the network interfaces available on your system
       and how to activate them. For more information, see interfaces(5).
       
       # The loopback network interface
       auto lo
       iface lo inet loopback
       
       # The primary network interface
       auto eth0
       iface eth0 inet static
        address 172.30.0.100
        netmask 255.255.255.0
        network 172.30.0.0
        broadcast 172.30.0.255
        gateway 172.30.0.1
       
       # HAProxy Virtual IP 1
       auto eth0:1
       iface eth0:1 inet static
        address 172.30.0.101
        netmask 255.255.255.0
       
    3. Save your changes and exit the text editor.
    4. Bring the new interface up.
      ifup eth0:1

 

  • Use ifconfig eth0:1 to verify the interface is up. The output should look similar to the following example.
    eth0:1     Link encap:Ethernet  HWaddr 00:0c:29:b6:f3:e8
               inet addr:172.30.0.101  Bcast:172.30.0.255  Mask: 255.255.255.0
               UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

 

Installing HAProxy

The HAProxy package is available in the Ubuntu 14 repository. It can be installed by using aptitude.

  1. Log onto the server using an account that has root privileges.
  2. Install HAProxy.
    sudo apt-get install haproxy
  3. To enable the HAProxy service daemon, open /etc/defaults/haproxy into a text editor.
    sudo nano /etc/defaults/haproxy
  4. Set the Enabled value to 1.
    # Set ENABLED to 1 if you want the init script to start haproxy
     ENABLED=1
     # Add extra flags here
     #EXTRAOPTS="-de -m 16"
  5. Save your changes and exit the text editor.

 

Layer 4 Balancing (High Performance)

Layer 4 load balancing is the faster method of balancing a web application. Simply, it receives a request submitted to the virtual IP and forwards it to a backed server (one of the web servers being balanced, for example). Very little processing is done, since the request just gets forwarded.

The limitation of balancing using layer 4 is that all backend servers must be configured identically. Otherwise, the user experience will differ depending on whichever server the user get forwarded to.

  1. Open the HAProxy configuration file into a text editor.
    sudo nano /etc/haproxy/haproxy.cfg
  2. Modify some of the values under the defaults section. More specifically, we need to ensure mode is set to tcp.
    global
      log /dev/log local0
      log /dev/log local1 notice
      chroot /var/lib/haproxy
      user haproxy
      group haproxy
      daemon
     
     defaults
      log global
      mode tcp
      option tcplog
      option dontlognull
      contimeout 5000
      clitimeout 50000
      srvtimeout 50000
      errorfile 400 /etc/haproxy/errors/400.http
      errorfile 403 /etc/haproxy/errors/403.http
      errorfile 408 /etc/haproxy/errors/408.http
      errorfile 500 /etc/haproxy/errors/500.http
      errorfile 502 /etc/haproxy/errors/502.http
      errorfile 503 /etc/haproxy/errors/503.http
      errorfile 504 /etc/haproxy/errors/504.http
     
  3. Create a new frontend section for your application. This is where we define the virtual IP of our cluster and which backend server cluster to use (which we define below). You can name the frontend whatever you want, as long as each frontend has a unique name.
    global
      log /dev/log local0
      log /dev/log local1 notice
      chroot /var/lib/haproxy
      user haproxy
      group haproxy
      daemon
     
     defaults
      log global
      mode tcp
      option tcplog
      option dontlognull
      contimeout 5000
      clitimeout 50000
      srvtimeout 50000
      errorfile 400 /etc/haproxy/errors/400.http
      errorfile 403 /etc/haproxy/errors/403.http
      errorfile 408 /etc/haproxy/errors/408.http
      errorfile 500 /etc/haproxy/errors/500.http
      errorfile 502 /etc/haproxy/errors/502.http
      errorfile 503 /etc/haproxy/errors/503.http
      errorfile 504 /etc/haproxy/errors/504.http
     
     frontend webapp1
      bind 172.30.0.101:80
      default_backend webapp1-servers
  4. Create a backend for the frontend just created. This is where we define the servers used in our cluster. We also set the balancing algorythm here, too, as well as some other optional options.
    global
      log /dev/log local0
      log /dev/log local1 notice
      chroot /var/lib/haproxy
      user haproxy
      group haproxy
      daemon
     
     defaults
      log global
      mode tcp
      option tcplog
      option dontlognull
      contimeout 5000
      clitimeout 50000
      srvtimeout 50000
      errorfile 400 /etc/haproxy/errors/400.http
      errorfile 403 /etc/haproxy/errors/403.http
      errorfile 408 /etc/haproxy/errors/408.http
      errorfile 500 /etc/haproxy/errors/500.http
      errorfile 502 /etc/haproxy/errors/502.http
      errorfile 503 /etc/haproxy/errors/503.http
      errorfile 504 /etc/haproxy/errors/504.http
     
     frontend webapp1
      bind 172.30.0.101:80
      default_backend webapp1-servers
     
     backend webapp1-servers
      balance roundrobin
      mode tcp
      server webserver1 172.30.0.102
      server webserver2 172.30.0.103
      server webserver3 172.30.0.104
      server webserver4 172.30.0.105
     
  5. Save your changes and exit the text editor.
  6. Start or restart HAProxy to apply our changes.
    sudo service haproxy restart

© 2014 Shane Rainville