17.10 Making HAProxy Highly Available Using Keepalived

The following example uses Keepalived to make the HAProxy service fail over to a backup server in the event that the master server fails.

Figure 17.5 shows two HAProxy servers, which are connected to an externally facing network (10.0.0/24) as 10.0.0.11 and 10.0.0.12 and to an internal network (192.168.1/24) as 192.168.1.11 and 192.168.1.12. One HAProxy server (10.0.0.11) is configured as a Keepalived master server with the virtual IP address 10.0.0.10 and the other (10.0.0.12) is configured as a Keepalived backup server. Two web servers, websvr1 (192.168.1.71) and websvr2 (192.168.1.72), are accessible on the internal network. The IP address 10.0.0.10 is in the private address range 10.0.0/24, which cannot be routed on the Internet. An upstream network address translation (NAT) gateway or a proxy server provides access to and from the Internet.

Figure 17.5 Example of a Combined HAProxy and Keepalived Configuration with Web Servers on a Separate Network

The diagram shows two HAProxy servers, which are connected to an externally facing network (10.0.0/24) as 10.0.0.11 and 10.0.0.12 and to an internal network (192.168.1/24) as 192.168.1.11 and 192.168.1.12. One HAProxy server (10.0.0.11) is configured as a Keepalived master server with the virtual IP address 10.0.0.10 and the other (10.0.0.12) is configured as a Keepalived backup server. Two web servers, websvr1 (192.168.1.71) and websvr2 (192.168.1.72), are accessible on the internal network. The IP address 10.0.0.10 is in the private address range 10.0.0/24, which cannot be routed on the Internet. An upstream network address translation (NAT) gateway or a proxy server provides access to and from the Internet.


The HAProxy configuration on both 10.0.0.11 and 10.0.0.12 is very similar to Section 17.3, “Configuring Simple Load Balancing Using HAProxy”. The IP address on which HAProxy listens for incoming requests is the virtual IP address that Keepalived controls.

global
    daemon
    log 127.0.0.1 local0 debug
    maxconn 50000
    nbproc 1

defaults
    mode http
    timeout connect 5s
    timeout client 25s
    timeout server 25s
    timeout queue 10s

# Handle Incoming HTTP Connection Requests on the virtual IP address controlled by Keepalived
listen  http-incoming
    mode http
    bind 10.0.0.10:80
# Use each server in turn, according to its weight value
    balance roundrobin
# Verify that service is available
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
# Insert X-Forwarded-For header
    option forwardfor
# Define the back-end servers, which can handle up to 512 concurrent connections each
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 check

It is also possible to configure HAProxy and Keepalived directly on the web servers as shown in Figure 17.6. As in the previous example, one HAProxy server (10.0.0.11) is configured as the Keepalived master server with the virtual IP address 10.0.0.10 and the other (10.0.0.12) is configured as a Keepalived backup server. The HAProxy service on the master listens on port 80 and forwards incoming requests to one of the httpd services, which listen on port 8080.

Figure 17.6 Example of a Combined HAProxy and Keepalived Configuration with Integrated Web Servers

The diagram shows one HAProxy server (10.0.0.11) is configured as the Keepalived master server with the virtual IP address 10.0.0.10 and the other (10.0.0.12) is configured as a Keepalived backup server. The HAProxy service on the master listens on port 80 and forwards incoming requests to one of the httpd services, which listen on port 8080.


The HAProxy configuration is the same as the previous example except for the IP addresses and ports of the web servers.

...
    server websvr1 10.0.0.11:8080 weight 1 maxconn 512 check
    server websvr2 10.0.0.12:8080 weight 1 maxconn 512 check

The firewall on each server must be configured to accept incoming TCP requests on port 8080.

The Keepalived configuration for both example configurations is similar to that given in Section 17.6, “Configuring Simple Virtual IP Address Failover Using Keepalived”.

The master server has the following Keepalived configuration:

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from haproxy1@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state MASTER
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
#   The virtual router ID must be unique to each VRRP instance that you define
    virtual_router_id 41
#   Set the value of priority higher on the master server than on a backup server
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.10/24
    }
}

The configuration of the backup server is the same except for the values of notification_email_from, state, priority, and possibly interface if the system hardware configuration is different:

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from haproxy2@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state BACKUP
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
    virtual_router_id 41
#   Set the value of priority lower on the backup server than on the master server
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.10/24
    }
}

In the event that the master server (haproxy1) fails, keepalived assigns the virtual IP address 10.0.0.10/24 to the enp0s8 interface on the backup server (haproxy2), which becomes the master server.

See Section 17.2, “Installing and Configuring HAProxy” and Section 17.5, “Installing and Configuring Keepalived” for details of how to install and configure HAProxy and Keepalived.