Skip to content

Install Haproxy v1.8 and Keepalived on CentOS 7

1. Preparation

1.1 KVMs

2 KVMs

Hostname vCPUs Memory Swap IP OS sudoer
slb01.k8s 2 2G 0 CentOS 7 echo
slb02.k8s 2 2G 0 CentOS 7 echo
cluster.k8s - - - - -

NOTE: is a virtual (HA) IP which points to slb01 or slb02.

1.2 Install Ansible on Host machine

# Install ansible on host machine
sudo yum install ansible

1.3 Password free Configuration

cat <<EOF | sudo tee -a /etc/ansible/hosts

# Have a test 
ansible slb --ask-pass -u echo -m shell -a 'echo ok'

# Password free for login
ansible slb --ask-pass -u echo -m file -a "path=.ssh state=directory mode=700"
ansible slb --ask-pass -u echo -m copy -a "src=~/.ssh/ dest=.ssh/authorized_keys mode=600"

# Password free for sudo
ansible slb --ask-pass -u echo -b -m shell -a "echo 'echo ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"

# Now we can have a test as below
ansible slb -u echo -m shell -a 'echo ok'

1.4 DNS via hosts file

cat <<EOF > /tmp/
cat <<EEE >> /etc/hosts slb01.k8s slb02.k8s

# A virtual IP which points slb01 or slb02 cluster.k8s

ansible k8s -u echo -b -m script -a "/tmp/"

2. Basic Configurations for servers

2.1 Required ports (Firewall Configuration)

ansible slb -u echo -b -m shell -a "firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp --add-port=8081/tcp"
ansible slb -u echo -b -m shell -a "firewall-cmd --reload"

2.2 Set SELinux in permissive mode (effectively disabling it)

cat <<EOF > /tmp/
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

ansible slb -u echo -b -m script -a '/tmp/'

3. Install HAProxy + Keepalived on SLB servers

3.1 Install HAProxy

cat <<EOF > /tmp/
sudo yum install centos-release-scl -y
sudo yum install rh-haproxy18 -y
sudo scl enable rh-haproxy18 bash -y
sudo systemctl enable rh-haproxy18-haproxy
sudo systemctl start rh-haproxy18-haproxy

ansible slb -u echo -b -m script -a "/tmp/"

3.2 Install Keepalived

ansible slb -u echo -b -m shell -a "yum install -y keepalived"

4. Configuraton Example

4.1 Self-signed Cert

# e.g.
openssl req -newkey rsa:2048 -nodes -sha256 -keyout example.key \
  -x509 -days 3650 -out example.crt \
  -subj "/"
cat example.crt example.key > example.pem

4.2 Example of haproxy.cfg


cat <<EOF > /tmp/haproxy.cfg
# Example configuration for a possible web application.  See the
# full configuration options online.

# Global settings
    # to have these messages end up in /var/opt/rh/rh-haproxy18/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/opt/rh/rh-haproxy18/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #    local2.*                       /var/opt/rh/rh-haproxy18/log/haproxy.log
    log local2

    chroot      /var/opt/rh/rh-haproxy18/lib/haproxy
    pidfile     /var/run/
    maxconn     4000
    user        haproxy
    group       haproxy

    # turn on stats unix socket
    stats socket /var/opt/rh/rh-haproxy18/lib/haproxy/stats

    # utilize system-wide crypto-policies
    #ssl-default-bind-ciphers PROFILE=SYSTEM
    #ssl-default-server-ciphers PROFILE=SYSTEM

# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
    mode                    http
    log                     global
    #option                  httplog
    option                  dontlognull
    option http-server-close
    #option forwardfor       except
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

# main frontend which proxys to the backends
frontend main
    #bind *:80
    bind *:443 ssl crt /etc/ssl/certs/example.pem 
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    #use_backend static          if url_static
    default_backend            static

    #acl root_path path_reg ^/$

# static backend for serving up images, stylesheets and such
backend static
    balance     roundrobin
    server      static check

# round robin balancing between the various backends
# listen k8sapi
    # bind *:6443
    # mode tcp
    # balance roundrobin
    # option  tcp-check
    # server  master01 master01.k8s:6443 check
    # server  master02 master02.k8s:6443 check
    # server  master03 master03.k8s:6443 check

# HAProxy Monitoring Config
listen monitoring
    bind *:8081                #Haproxy Monitoring run on port 8081    
    mode http
    option forwardfor
    option httpclose
    stats enable
    stats show-legends
    stats refresh 5s
    stats uri /stats           #URL for HAProxy monitoring
    #stats realm Haproxy Statistics
    stats auth howtoforge:howtoforge        
    stats admin if TRUE

ansible slb -u echo -b -m copy -a \
  mode=600 owner=haproxy group=haproxy"

ansible slb -u echo -b -m copy -a \
  mode=600 owner=haproxy group=haproxy"

ansible slb -u echo -b -m shell -a "systemctl restart rh-haproxy18-haproxy"

4.3 Example of keepalived.conf


cat <<EOF> /tmp/keepalived.conf
global_defs {
   notification_email {
   notification_email_from noreply1@example.k8s
   smtp_server localhost
   smtp_connect_timeout 30

vrrp_script chk_haproxy {
  script "pkill -0 haproxy" # check the haproxy process
  interval 2 # every 2 seconds
  weight 2 # add 2 points if OK

vrrp_instance VI_1 {
  interface eth0 # interface to monitor
  state MASTER # MASTER on slb01, BACKUP on slb02
  virtual_router_id 51
  priority 100 # 100 on slb01, 99 on slb02

  #IP Address of local machine. 
  #NOTE: this is mandatory if multicast is forbidden in your network  
  unicast_peer {
    #IP Address of other machine(s). 
    #NOTE1: this is mandatory if multicast is forbidden in your network. 
    #NOTE2: multiple values can be issued here

  authentication {
    auth_type PASS
    auth_pass 1849
  virtual_ipaddress { # virtual ip address
  track_script {

ansible slb -u echo -b -m copy -a \

Edit keepalived.conf on slb02.k8s

# On slb02.k8s:
#   state BACKUP 
#   priority 99
#   unicast_src_ip
#   unicast_peer {
#   }
vi /etc/keepalived/keepalived.conf

Enable & Restart keepalived

ansible echoyun-slb -u echo -b -m shell -a "systemctl enable keepalived"
ansible echoyun-slb -u echo -b -m shell -a "systemctl restart keepalived"

5. Access HAProxy stats page

Now we can open HAProxy stats page in Browser

# auth: howtoforge:howtoforge


Last update: 2021-12-02