User-defined Playground

HA Kubernetes Cluster Playground

A multi-node, highly available Kubernetes cluster provisioned with kubeadm.

HA Kubernetes Cluster playground: A multi-node, highly available Kubernetes cluster provisioned with kubeadm.
Machines & network
5 VMs · 10 vCPU · 15GiB RAM
Playground host Internet NAT MASQUERADE local (bridge) 172.16.0.0/24 gw 172.16.0.1/24eth0eth0eth0eth0eth0
VM
vCPU ·
eth0
/
oci://ghcr.io/sagikazarmark/iximiuz-labs/playgrounds/kubeadm-cluster/dev-machine:live@sha256:686acd9a10da117be78b736b6cbba8d231da71f3b9152386c1952807ea0a6e62
VM
vCPU ·
eth0
/
oci://ghcr.io/sagikazarmark/iximiuz-labs/playgrounds/kubeadm-cluster/control-plane:live@sha256:2f30645a25c82c01aeb393b83ae49eece674a489c83d2b7c794136449815b707
VM
vCPU ·
eth0
/
oci://ghcr.io/sagikazarmark/iximiuz-labs/playgrounds/kubeadm-cluster/control-plane:live@sha256:2f30645a25c82c01aeb393b83ae49eece674a489c83d2b7c794136449815b707
VM
vCPU ·
eth0
/
oci://ghcr.io/sagikazarmark/iximiuz-labs/playgrounds/kubeadm-cluster/control-plane:live@sha256:2f30645a25c82c01aeb393b83ae49eece674a489c83d2b7c794136449815b707
VM
vCPU ·
eth0
/
oci://ghcr.io/sagikazarmark/iximiuz-labs/playgrounds/kubeadm-cluster/worker:live@sha256:f5195a4c46f450caea6805e0b94b777e1ce440e6578d091e825617f27c020cbc
About

📖 Overview

This playground provides a complete HA Kubernetes cluster with:

  • 3 Control Plane Nodes: cplane-01, cplane-02, cplane-03
  • 1 Worker Nodes: worker-01
  • IP Failover: Keepalived for moving the virtual IP address between control plane nodes

🛠️ Tools

  • kubectl (alias: k): Kubernetes cluster management and debugging
  • nerdctl: Docker-compatible CLI for containerd
  • krew: kubectl plugin manager for extending functionality

🔥 Testing High Availability and Failover

One of the key benefits of an HA cluster is its resilience to node failures. Here are several tests you can perform to verify your cluster's fault tolerance:

Test 1: Control Plane Node Failure

Figure out which control plane node is active

# On each control plane node
ip a | grep inet | grep vip

# If you see the VIP address, it means the node is active

Stop kubelet on the Active Control Plane Node

# On the active control plane node (e.g., cplane-02)
sudo systemctl stop kubelet

# From another node, verify the cluster still functions
kubectl get nodes
kubectl get pods --all-namespaces

# The failed node should show as "NotReady" (may take a few minutes)
# but the cluster should remain operational

Stop API Server Container

# On the same control plane node, stop the API server container
# List containers in the k8s.io namespace
nerdctl --namespace k8s.io ps

# Stop the API server containers
nerdctl --namespace k8s.io stop $(nerdctl --namespace k8s.io ps -a --format "{{json .}}" | jq -r --arg name "k8s://kube-system/kube-apiserver-$(hostname)" 'select(.Names == $name or .Names == $name+"/kube-apiserver") | .ID')

# Verify from another node that the API is still accessible
kubectl cluster-info
kubectl get componentstatuses

# Find the new active control plane node
ip a | grep inet | grep vip

Recovery

# Start kubelet service
sudo systemctl start kubelet

# Verify node returns to Ready state
kubectl get nodes

Test 2: Worker Node Failure

# Deploy a test application
kubectl create deployment podinfo --image=ghcr.io/stefanprodan/podinfo --port=9898

# Figure out which node the pod is running on
kubectl get pods -o wide

# Stop kubelet on that worker node
sudo systemctl stop kubelet

# Watch pods get rescheduled to other nodes (it may take a few minutes)
kubectl get pods -o wide --watch

# Pods should be automatically rescheduled to healthy worker nodes

🧪 Playgrounds

Happy learning! 🚀

Every playground includes
Learn more about playgrounds
Start
Settings