Builing a HAProxy Failover Cluster on CentOS 7

We are going to build HAProxy version 2.3.9 with SSL support on CentOS 7.

When you need to have a highly available load balanced setup HAProxy and keepalived are your friends. In this short tutorial I will be showing you how to quickly get this setup done.

First things first, ensure that you have 2 Centos 7 Servers (Minimal) installed and up-to-date with the latest patches.

Server ip’s:

LB01 – 192.168.1.5

LB02 – 192.168.1.6

Virtual IP: 192.168.1.2

Load Balancer Stats: 192.168.1.3

On both servers run the following:

yum install gcc pcre-static pcre-devel openssl-devel -y

We need to also allow Centos to add IP addresses that is not bound to it’s local network card. This is needed for the failover to take place.

Let’s first make sure it’s not already enabled

cat /proc/sys/net/ipv4/ip_nonlocal_bind

if the value get back is 0 (Zero) then it’s not enabled

so lets create a file to enable this at run time

nano /etc/sysctl.d/99-custom.conf

in the file add the below content

#allow HAProxy to start and bind to non local IP
net.ipv4.ip_nonlocal_bind=1

Once done, reboot both servers 🙂

Now let’s start with the HAProxy installation

wget http://www.haproxy.org/download/2.3/src/haproxy-2.3.9.tar.gz -O ~/haproxy.tar.gz
tar xzvf ~/haproxy.tar.gz -C ~/
cd haproxy-2.3.9/

We now have the latest 2.3 version downloaded, time to build.

make TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1

sudo make install

sudo mkdir -p /etc/haproxy
sudo mkdir -p /var/lib/haproxy
sudo touch /var/lib/haproxy/stats
sudo ln -s /usr/local/sbin/haproxy /usr/sbin/haproxy
sudo cp examples/haproxy.init /etc/init.d/haproxy
sudo chmod 755 /etc/init.d/haproxy
sudo systemctl daemon-reload
sudo chkconfig haproxy on
sudo useradd -r haproxy
haproxy -v
cd /etc/haproxy/
vim haproxy.cfg

haproxy -f haproxy.cfg

systemctl start haproxy
systemctl status haproxy

Here is a sample HAProxy cfg file.

global
   log /dev/log local0
   log /dev/log local1 notice
   chroot /var/lib/haproxy
   stats timeout 30s
   user haproxy
   group haproxy
   daemon
   tune.ssl.default-dh-param 2048

defaults
   log global
   mode http
   option httplog
   option dontlognull
   option http-server-closeoption forwardfor except 127.0.0.0/8 option redispatch retries 3timeout http-request 10s timeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10s timeout check 10s
   maxconn 3000

frontend http_front
   bind 192.168.1.2:443
   default_backend web_nodes
   mode http
   acl is-ssl dst_port 443
   bind *:443 ssl crt /etc/haproxy/ssl2019/bundle.crt no-sslv3 ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    reqadd X-Forwarded-Proto:\ https
    reqadd X-Forwarded-Protocol:\ https
    reqadd X-Forwarded-Port:\ 443
    reqadd X-Forwarded-SSL:\ on
    reqadd X-Forwarded-Proto:\ https if { ssl_fc }
    reqadd X-Proto:\ SSL  if is-ssl
    http-response set-header Strict-Transport-Security max-age=31536000;\ includeSubdomains;\ preload
    http-response set-header X-Frame-Options DENY
    http-response set-header X-Content-Type-Options nosniff


backend web_nodes     
   mode http     
   balance roundrobin     
   option forwardfor     
   option httpchk HEAD / HTTP/1.1\r\nHost:localhost     
   server web01 192.168.1.11:9000 check     
   server web02 192.168.1.12:9000 check     
   server web03 192.168.1.13:9000 check     
   http-request set-header X-Forwarded-Port %[dst_port]     
   http-request add-header X-Forwarded-Proto https if { ssl_fc }

listen stats
     bind  192.168.1.3:8088       #Virtual IP for Stats
     log   global                    
     stats enable                    
     stats hide-version              
     stats refresh 30s               
     stats show-node                 
     stats auth lbadmin:P@ssword     
     stats uri /lb_stats            

Remember that Centos 7 has a firewall enabled by default, so lets add the the ports to the allowed list on the firewall

firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=8088/tcp --permanent

Reload the firewall with the new ports

firewall-cmd --reload

Now that we have HAProxy configured, we need to setup Keepalived to move that IP address that HAProxy needs to use to the Master server only.

We need to install keepalived on both servers

yum install -y keepalived

On the LB01 server create the below configuration file and save it as

/etc/keepalived/keepalived.conf
global_defs {
    router_id LVS_DEVEL
 }
 #health-check for keepalive
 vrrp_script chk_haproxy { # Requires keepalived-1.1.13
     script "pidof haproxy"
     interval 2 # check every 2 seconds
     weight 3 # add 3 points of priority if OK
 }
 vrrp_instance VI_1 {
     state MASTER
     interface eth0
     virtual_router_id 100
     priority 101
  track_script {     
       chk_haproxy 
   }
   
  advert_int 1 
  authentication {     
       auth_type PASS     
       auth_pass VerySecretPass 
   }
 
  unicast_src_ip 192.168.1.5
  unicast_peer {
       192.168.1.6
   }
 
  virtual_ipaddress {
      192.168.1.2 
  }
 }

On LB02 use the below

global_defs {
    router_id LVS_DEVEL
 }
 #health-check for keepalive
 vrrp_script chk_haproxy { # Requires keepalived-1.1.13
     script "pidof haproxy"
     interval 2 # check every 2 seconds
     weight 3 # add 3 points of priority if OK
 }
 vrrp_instance VI_1 {
     state BACKUP
     interface eth0
     virtual_router_id 100
     priority 100
  track_script {     
       chk_haproxy 
   }
   
  advert_int 1 
  authentication {     
       auth_type PASS     
       auth_pass VerySecretPass 
   }
 
  unicast_src_ip 192.168.1.6
  unicast_peer {
       192.168.1.5
   }
 
  virtual_ipaddress {
      192.168.1.2 
  }
 }

you can now start keepalived

systemctl enable keepalived
systemctl start keepalived

To check the status of keepalived

systemctl status  keepalived

You should now have a fully functioning HAProxy failover cluster

Centos


Recent Posts

Latest Tweets