HAProxy is a free and open source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers. It is written in C and has a reputation for being fast and efficient.
Keepalived main goal is to provide simple and robust facilities for loadbalancing and high-availability to Linux system and Linux based infrastructures. Loadbalancing framework relies on well-known and widely used Linux Virtual Server (IPVS) kernel module providing Layer4 loadbalancing. Keepalived implements a set of checkers to dynamically and adaptively maintain and manage loadbalanced server pool according their health. On the other hand high-availability is achieved by the Virtual Router Redundancy Protocol (VRRP). VRRP is a fundamental brick for router failover. In addition, Keepalived implements a set of hooks to the VRRP finite state machine providing low-level and high-speed protocol interactions. In order to offer fastest network failure detection, Keepalived implements the Bidirectional Forwarding Detection (BFD) protocol. VRRP state transition can take into account BFD hints to drive fast state transition. Keepalived frameworks can be used independently or all together to provide resilient infrastructures.
Step 1: Install Packages
The following packages will need to be installed on both nodes that are to act as a loadbalancer:
# apt install haproxy keepalived
Step 2: Configure Keepalived
Configure keepalived for the “MASTER” and “BACKUP” node, each containing the following values:
- Define the state as MASTER
- Define the interface
- Define the Virtual Router ID
- Define priority (higher will win)
- Define authentication
- Define Virtual IP Address
Change settings in /etc/keepalived/keepalived.conf on the “MASTER” node
! Configuration File for keepalived
global_defs {
notification_email {
admin@mydomain.org
}
notification_email_from lb-keepalived@mydomain.org
smtp_server <smtp-server-ip>
smtp_connect_timeout 30
router_id lb-01
}
vrrp_instance VI_1_IPv4 {
state MASTER
interface ens224
smtp_alert
virtual_router_id 51
priority 200
unicast_src_ip <IP PRIMARY IPv4 LB>
unicast_peer {
<IP SECONDARY IPv4 LB>
}
authentication {
auth_type PASS
auth_pass dWau6GCHA2LvxRD6Rjth3pzX
}
advert_int 1
virtual_ipaddress {
<virtual-ip-address>
}
}
Change settings in /etc/keepalived/keepalived.conf on the “BACKUP” node
! Configuration File for keepalived
global_defs {
notification_email {
admin@mydomain.org
}
notification_email_from lb-keepalived@mydomain.org
smtp_server <smtp-server-ip>
smtp_connect_timeout 30
router_id lb-01
}
vrrp_instance VI_1_IPv4 {
state BACKUP
interface ens224
smtp_alert
virtual_router_id 51
priority 100
unicast_src_ip <IP PRIMARY IPv4 LB>
unicast_peer {
<IP SECONDARY IPv4 LB>
}
authentication {
auth_type PASS
auth_pass dWau6GCHA2LvxRD6Rjth3pzX
}
advert_int 1
virtual_ipaddress {
<virtual-ip-address>
}
}
On both nodes enable and start the keepalived service
# systemctl enable keepalived # systemctl restart keepalived
On the “MASTER” node you should see the virtual-ip address avaialble
# ip addr list
Step 3: Configure HAProxy
Change settings in /etc/haproxy/haproxy.conf on both “MASTER” and “BACKUP” nodes
- Define the <internal-ip-address> for communication for statistics and information
- Define the various frontend and backend services needed
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
tune.ssl.default-dh-param 2048
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
# An alternative list with additional directives can be obtained from
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
listen stats
bind <internal-ip>:8181
mode http
maxconn 5
timeout client 100s
timeout server 100s
timeout connect 100s
timeout queue 100s
stats enable
stats hide-version
stats refresh 30s
stats show-node
stats auth admin:VbWWNsQD4QLTsMejWaGPjms5
stats uri /haproxy?stats
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 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
################
# WEB : 80
################
frontend vs_web_80
bind *:80
mode http
default_backend pool_web_80
backend pool_web_80
balance roundrobin
option forwardfor
option http-server-close
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server web1 www-01.internal.mydomain.org:80 check
server web2 www-02.internal.mydomain.org:80 check
################
# WEB : 443
################
frontend vs_web_443
bind *:443 ssl crt /etc/haproxy/ssl/mydomain.org-chain.pem
mode http
option tcplog
default_backend pool_web_443
backend pool_web_443
balance roundrobin
option forwardfor
option http-server-close
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server web1 www-01.internal.mydomain.org:443 check maxconn 20 ssl verify none
server web2 www-02.internal.mydomain.org:443 check maxconn 20 ssl verify none
Before starting the service, you can check the configuration on each node
# haproxyctl configcheck Configuration file is valid
On both nodes enable and start the haproxy service
# systemctl enable haproxy # systemctl restart haproxy
Status can be checked using the CLI:
haproxyctl show backend stats BACKEND UP 0 pool_web_80 BACKEND UP 2 pool_web_443 BACKEND UP 2 pool_ftp_21 BACKEND UP 1 haproxyctl show health # pxname svname status weight stats FRONTEND OPEN stats BACKEND UP 0 vs_web_80 FRONTEND OPEN pool_web_80 web1 UP 1 pool_web_80 web2 UP 1 pool_web_80 BACKEND UP 2 vs_web_443 FRONTEND OPEN pool_web_443 web1 UP 1 pool_web_443 web2 UP 1 pool_web_443 BACKEND UP 2 vs_ftp_21 FRONTEND OPEN pool_ftp_21 ftp1 DOWN 1 pool_ftp_21 ftp2 UP 1 pool_ftp_21 BACKEND UP 1
Or visit the haproxy service defined in the configuration file e.g. http://proxy-01.mydomain.org;8181/haproxy?stats
