How To Install HAProxy for Kubernetes Load Balancer

Written by: Bagus Facsi Aginsa
Published at: 12 Nov 2023


If you deploy the Kubernetes cluster on-premise, then you will need a dedicated load balancer to process the incoming traffic to your cluster. There are 2 popular load balancer options for this, HAProxy and Nginx. For this use case, I recommend using HAProxy because it supports high-availability features like health checks. This feature is not directly supported in the Opensource version of Nginx. We will also use keepalived to provide HA (High Availability) capability to the load balancer.

Notes!

Besides Kubernetes, this load balancer setup will also work on similar cloud-native platforms such as k3s, minik8s, OKD, etc.

So, let’s get started

Prerequisite

  1. Ubuntu 18.04 or later

Sudo Privileges

Before starting, we make sure that we will have no permission issues on the installation and configuration.

sudo su

Planning the Cluster

So let’s say we build a Kubernetes cluster like this:

The k8s Master IP address:

master-1: 10.0.0.20/24
master-2: 10.0.0.21/24
master-3: 10.0.0.22/24

The Load Balancer IP address:

lb-1: 10.0.0.11/24
lb-2: 10.0.0.12/24

Plus additional Virtual IP address for LB VRRP:

vip: 10.0.0.10/24

HAProxy Layer 4 Load Balancer Setup

Install HAProxy and Keepalived on both of your Load Balancer VM

apt install haproxy keepalived

Add This configuration to the HAProxy config file /etc/haproxy/haproxy.cfg on both of your Load Balancer VM

frontend k8s-master-frontend
    bind :6443
    mode tcp
    option tcplog
    default_backend k8s-master-backend

backend k8s-master-backend
    mode tcp
    option tcp-check
    balance roundrobin
    default-server inter 10s downinter 5s
    server server-1 10.0.0.20:6443 check
    server server-2 10.0.0.21:6443 check
    server server-3 10.0.0.22:6443 check

Note that you can edit the marked parameter to another value that suits your needs. For the balance parameter, you can use balance leastconn as an alternative to roundrobin.

After that, restart the HAProxy

service haproxy restart

Next, add this configuration to the keepalived configuration file /etc/keepalived/keepalived.conf on lb-1 VM

   
vrrp_script check_haproxy {
    script 'killall -0 haproxy'
    interval 2
}

vrrp_instance haproxy-vip {
   interface eth1
    state MASTER
    priority 200

    virtual_router_id 101

    virtual_ipaddress {
        10.0.0.10/24
    }

    track_script {
        check_haproxy
    }
}

Restart the keepalived service

service keepalived restart

Add this configuration to the keepalived configuration file /etc/keepalived/keepalived.conf on lb-2 VM

vrrp_script check_haproxy {
    script 'killall -0 haproxy'
    interval 2
}

vrrp_instance haproxy-vip {
   interface eth1
    state BACKUP
    priority 100

    virtual_router_id 101

    virtual_ipaddress {
        </mark>10.0.0.10/24</mark>
    }

    track_script {
        check_haproxy
    }
}

Restart the keepalived service

service keepalived restart

Notice the difference between lb-1 and lb-2 are state and priority parameters. Also, note that you should change the interface name to match the VM’s interface name.

Note that the virtual_ipaddress must be on the same subnet as the Kubernetes master VM. For you who wonder how can we acquire the virtual_ipaddress, you just need to search for the IP address that is currently not used on the host network, and then just use that IP address.

That’s it, now your cluster is highly available.