Skip to content

Instantly share code, notes, and snippets.

@carlosgrillet
Created July 18, 2025 11:52
Show Gist options
  • Select an option

  • Save carlosgrillet/5ced76d58c9f5a0aa0923b47e8dcd57d to your computer and use it in GitHub Desktop.

Select an option

Save carlosgrillet/5ced76d58c9f5a0aa0923b47e8dcd57d to your computer and use it in GitHub Desktop.
This guide explains how to configure HAProxy as a load balancer for Kubernetes clusters.

How to Set Up HAProxy as a Load Balancer for Kubernetes High Availability (HA) Clusters

This guide explains how to configure HAProxy as a load balancer for Kubernetes clusters.

Why Use a Load Balancer?

A load balancer is important for Kubernetes clusters because:

  1. High Availability: It ensures that if one control plane node fails, traffic is redirected to other working nodes.
  2. Better Performance: It distributes traffic evenly across multiple nodes, preventing overload on a single node.
  3. Simplified Access: Instead of connecting to individual control plane nodes, you can use a single entry point (the load balancer).
  4. Security: It hides the internal IP addresses of your control plane nodes, adding an extra layer of protection.

Step 1: Configure HAProxy

Before starting, make sure you can reach your control plane nodes using their DNS names or IP addresses.

Here is an example configuration file for HAProxy (haproxy.cfg):

global
  daemon
  maxconn 100000

defaults
  mode tcp
  timeout connect 5s
  timeout client 50s
  timeout server 50s

frontend kube-api
  bind *:6443
  default_backend kube-api-backend

backend kube-api-backend
  mode tcp
  option httpchk GET /healthz
  server kube-control-1 <control-plane-1-ip>:6443 check
  server kube-control-2 <control-plane-2-ip>:6443 check

Explanation:

  • Frontend: Listens on port 6443 (the default Kubernetes API port) and forwards traffic to the backend.
  • Backend: Contains the list of control plane nodes (kube-control-1, kube-control-2) with their IPs and health checks.
  • Health Check: Ensures only healthy nodes receive traffic.

Save this file and restart HAProxy to apply the changes:

sudo systemctl restart haproxy

Step 2: Update Certificates for the Load Balancer

To ensure secure communication, update the Kubernetes certificates to include the load balancer's IP and DNS name.

Create a Configuration File (Per Control Plane)

First login into you control plane node and create a new YAML file (e.g., san-config.yaml) to regenerate certificates with the load balancer's details:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
apiServer:
  certSANs:
  - <proxy-ip>
  - <dns-record>

Replace <proxy-ip> with the load balancer's IP address and <dns-record> with its DNS name.


Step 3: Backup Existing Certificates (Per Control Plane)

On each control plane node, back up the existing Public Key Infrastructure (PKI) files:

tar czf pki.tar.gz /etc/kubernetes/pki

This creates a compressed archive of the certificate files in case you need to restore them later.


Step 4: Delete Old Certificates (Per Control Plane)

Delete the existing apiserver certificates on each control plane node:

rm /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.key

This step removes the old certificates so they can be replaced with new ones that include the load balancer's details.


Step 5: Generate New Certificates (Per Control Plane)

Run the following command on each control plane node to generate new certificates using the updated configuration:

kubeadm init phase certs apiserver --config san-config.yaml

After running the command, you should see output similar to this:

[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [<control-plane-hostname> kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local <your-dns-record>] and IPs [10.96.0.1 <control-plane-ip> <proxy-ip>]

This confirms that the new certificates include the load balancer's IP and DNS name.


Step 6: Update Your .kube/config File

Finally, update your Kubernetes configuration file (~/.kube/config) to point to the load balancer instead of a specific control plane node.

Locate the cluster section and replace the control plane IP with the load balancer's IP:

clusters:
- cluster:
    server: https://<proxy-ip>:6443
  name: kubernetes

Save the file, and you're done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment