Enhancing Load Balancing by Using Keepalived With HAProxy

Keepalived can provide failover services for backup routers, while at the same time also use HAProxy for load balancing to achieve high availability across distributed servers. The advantage of this approach is that the packet and application layers are separated, which means that the health checks that are performed by Keepalived for the load-balancing servers aren't impacted by the inbound HTTP or TCP traffic that HAProxy is managing. Also, failover routing, which is achieved by using VRRP, can be activated automatically without waiting for a client response to timeout. To learn more about the usefulness of VRRP, see Using Keepalived With VRRP.

The practicality of using this method is that if the public-facing HAProxy load balancer goes offline, Keepalived automatically detects this event and dynamically switches to another HAProxy server. If the Keepalived primary router goes offline, the VRRP settings that you configured ensure that traffic is automatically handled by the Keepalived backup router.

The role of HAProxy in the setup is to provide inbound load balancing and session persistence to the backend servers: Keepalived is solely responsible for monitoring the status of HAProxy and providing an alternative routing mechanism. Using both tools in combination provides a highly available and resilient load-balancing solution.

The following procedure is similar to Setting Up Load Balancing in NAT Mode, however in this case HAProxy is installed on both the Keepalived primary server and the Keepalived backup server.

In this procedure, the external virtual IP address is 192.168.1.1 on the 192.168.1.0/24 external network. This IP address is dynamically assigned through NAT between the Keepalived primary server whose IP address is 192.168.1.10, and the Keepalived backup server, whose external IP address is 192.168.1.11.

The internal network is hosted on the 10.0.0.0/24 subnet. For IP addresses, websvr1 has 10.0.0.71 while websvr2 has 10.0.0.72.

Figure 3-2 Keepalived and HAProxy Configuration for High Availability Load Balancing


The figure shows that the Keepalived primary server running HAProxy has network addresses 192.168.1.10, 10.0.0.10, and 10.0.0.100 (virtual). The Keepalived backup server also running HAProxy has the network addresses 192.168.1.11 and 10.0.0.11, and it becomes the new primary router if the current primary router becomes unavailable. For IP addresses, websvr1 has 10.0.0.71 while websvr2 has 10.0.0.72.
  1. Configure Keepalived on the primary server.

    The following example shows the configuration in the /etc/keepalived/keepalived.conf file on the primary server

    global_defs {
     
      notification_email {
        root@example.com
      }
     
      notification_email_from srv1@example.com
      smtp_server localhost
      smtp_connect_timeout 30
    }
     
    vrrp_sync_group vg1 {
      group {
        external
        internal
      }
    }
     
    vrrp_script chk_haproxy {
      script "killall -0 haproxy" # check the haproxy process
      interval 2 # every 2 seconds
      weight 2 # add 2 points if OK
    }
     
    vrrp_instance external {
      state MASTER
      interface enp0s8
      virtual_router_id 91
      priority 200
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1215
      }
      virtual_ipaddress {
        192.168.1.1/24
      }
      track_script {
        chk_haproxy
      }
    }
     
    vrrp_instance internal {
      state MASTER
      interface enp0s9
      virtual_router_id 92
      priority 200
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1215
      }
      virtual_ipaddress {
        10.0.0.100/24
      }
    }     
  2. Verify that the configuration file is valid.
    sudo keepalived -t
  3. Configure Keepalived on the backup server.

    The configuration for the backup Keepalived server is identical, but the state value must be set to BACKUP. You don't need to set up a virtual_server because in this scenario, Keepalived is only used to route traffic, not to perform load balancing. An example configuration for the backup server follows:

    global_defs {
     
      notification_email {
        root@example.com
      }
     
      notification_email_from srv1@example.com
      smtp_server localhost
      smtp_connect_timeout 30
    }
     
    vrrp_sync_group vg1 {
      group {
        external
        internal
      }
    }
     
    vrrp_script chk_haproxy {
      script "killall -0 haproxy" # check the haproxy process
      interval 2 # every 2 seconds
      weight 2 # add 2 points if OK
    }
     
    vrrp_instance external {
      state MASTER
      interface enp0s8
      virtual_router_id 91
      priority 200
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1215
      }
      virtual_ipaddress {
        192.168.1.1/24
      }
      track_script {
        chk_haproxy
      }
    }
     
    vrrp_instance internal {
      state BACKUP
      interface enp0s9
      virtual_router_id 92
      priority 200
      advert_int 1
      authentication {
        auth_type PASS
        auth_pass 1215
      }
      virtual_ipaddress {
        10.0.0.100/24
      }
    }     
  4. Verify that the configuration file is valid.
    sudo keepalived -t
  5. Configure firewall rules for Keepalived on each server.

    For more information about configuring Keepalived and setting the appropriate firewall rules, see Setting Up Load Balancing by Using Keepalived.

  6. Configure HAProxy on each server.

    The HAProxy settings are configured in the /etc/haproxy/haproxy.cfg file. The settings are identical for both HAProxy installations because Keepalived dynamically routes from one configuration to the other automatically, as needed:

    global
      daemon
      log 127.0.0.1 local0 debug
      maxconn 4000
      nbthread 1
     
    defaults
      mode          http
      retries       3
      timeout connect 5s
      timeout client 25s
      timeout server 25s
      timeout queue 10s
    
    listen http-incoming
      mode http
      bind internal-server-ip:80
      option http-server-close
      option forwardfor
      default_backend app
    
    backend app
      balance roundrobin
      option httpchk 
      http-check send meth HEAD ver HTTP/1.1 hdr Host localhost
      option httpclose
      option forwardfor
      server websrv1 192.168.1.71:80 weight 1 maxconn 512 check
      server websrv2 192.168.1.72:80 weight 1 maxconn 512 check

    In the configuration example, the option http-server-close and option httpclose options are used to stop idle connections. This configuration shows the round-robin, load-balancing strategy. If no option is specified, then HAProxy defaults to using the option http-keep-alive option, which keeps any new connections open until every request and response journey that's associated with them is processed.

    For more information about configuring HAProxy and setting the appropriate firewall rules, see Setting Up Load Balancing by Using HAProxy.