Kubernetes HA with kube-vip as API Server Load Balancer (AlmaLinux 10.1)

If you’re running a multi-master Kubernetes cluster, having a highly available control plane endpoint is critical. In this guide, I’ll walk through how to use kube-vip as a lightweight, ARP-based load balancer for the Kubernetes API server.

Cluster Overview

We are running a 3-node control plane:

NodeRoleIP Address
master-01control-plane192.168.20.81
master-02control-plane192.168.20.82
master-03control-plane192.168.20.83
  • OS: AlmaLinux 10.1
  • Kubernetes: v1.35.2
  • Container Runtime: containerd
  • Virtual IP (VIP): 192.168.20.80

What is kube-vip?

kube-vip provides a virtual IP (VIP) that floats between control-plane nodes using leader election.

👉 It ensures:

  • A single stable endpoint for the API server
  • Automatic failover if a master node goes down
  • No need for external load balancers

How kube-vip Works

  1. kube-vip runs as a static pod on each control-plane node
  2. One node becomes the leader via Kubernetes leader election
  3. The leader:
    • Owns the VIP (192.168.20.80)
    • Responds to ARP requests
  4. If the leader fails:
    • Another node takes over the VIP automatically

Architecture Flow

kubectl / clients
        ↓
  192.168.20.80 (VIP)
        ↓
Active kube-vip leader node
        ↓
Local kube-apiserver (6443)

kubeadm Configuration

Your kubeadm-config.yaml defines the VIP as the control plane endpoint:

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: stable
controlPlaneEndpoint: "192.168.20.80:6443"
networking:
  podSubnet: "10.244.0.0/16"
apiServer:
  certSANs:
    - "192.168.20.80"
    - "192.168.20.81"
    - "192.168.20.82"
    - "192.168.20.83"

✅ Important: The VIP must be included in certSANs.


kube-vip Static Pod Manifest

Place this file on each control-plane node:

sudo tee /etc/kubernetes/manifests/kube-vip.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: kube-vip
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-vip
    image: ghcr.io/kube-vip/kube-vip:v0.8.0
    imagePullPolicy: IfNotPresent
    args:
    - manager
    env:
    - name: vip_arp
      value: "true"
    - name: port
      value: "6443"
    - name: vip_interface
      value: "ens33"
    - name: cp_enable
      value: "true"
    - name: cp_namespace
      value: "kube-system"
    - name: vip_ddns
      value: "false"
    - name: svc_enable
      value: "false"
    - name: vip_leaderelection
      value: "true"
    - name: vip_leaseduration
      value: "5"
    - name: vip_renewdeadline
      value: "3"
    - name: vip_retryperiod
      value: "1"
    - name: address
      value: "192.168.20.80"
    - name: kubernetes_addr
      value: "https://192.168.20.81:6443"
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_RAW
    volumeMounts:
    - mountPath: /etc/kubernetes/admin.conf
      name: kubeconfig
      readOnly: true
  volumes:
  - name: kubeconfig
    hostPath:
      path: /etc/kubernetes/admin.conf
      type: File
EOF

Key Configuration Explained

  • vip_arp=true → Uses ARP to advertise VIP on the network
  • cp_enable=true → Enables control-plane load balancing
  • svc_enable=false → Disables service load balancing
  • vip_leaderelection=true → Ensures only one active VIP owner
  • address=192.168.20.80 → Your virtual IP
  • kubernetes_addr → Bootstrap API endpoint

SELinux Fix (Important)

Ensure kube-vip can read the kubeconfig:

ls -Z /etc/kubernetes/admin.conf
sudo chcon -t container_file_t /etc/kubernetes/admin.conf
ls -Z /etc/kubernetes/admin.conf

Expected output:

system_u:object_r:container_file_t:s0 /etc/kubernetes/admin.conf

Verification Commands

Check kube-vip pod

crictl ps | grep kube-vip

Check VIP ownership

ip addr show | grep 192.168.20.80

Test API via VIP

kubectl --server=https://192.168.20.80:6443 get nodes

Failover Test

  1. Identify current leader node
  2. Stop kubelet or power off that node
  3. Watch VIP move:
watch -n1 ip addr show

✅ VIP should migrate to another master within seconds


Best Practices

  • Use dedicated interface (ens33) correctly
  • Ensure L2 network allows ARP broadcasts
  • Keep vip_leaseduration low for fast failover
  • Always test failover before production

Conclusion

kube-vip is a simple yet powerful solution for Kubernetes HA control planes:

✔ No external load balancer needed
✔ Fast failover using ARP
✔ Native Kubernetes leader election

Perfect for on-prem, lab, and edge clusters.

If you found this helpful, feel free to share or drop questions! 🚀

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *