Build a 4-Node Raspberry Pi 5 Kubernetes Cluster for Under $500

DIY Hardware
Date:November 5, 2026
Topic:
Build a 4-Node Raspberry Pi 5 Kubernetes Cluster for Under $500
⏱ 3 min read

Four Raspberry Pi 5 boards, a managed switch, and a weekend. That is all it takes to spin up a production-grade Kubernetes cluster for less than $500. No cloud bills, no vendor lock-in, and a homelab that actually teaches you how control planes, networking, and storage behave under load.

Bill of Materials

ComponentQtyUnit CostTotal
Raspberry Pi 5 (8 GB)4$80$320
Official 27 W USB-C PD PSU4$12$48
Active cooler + fan4$5$20
32 GB microSD (A2 rated)4$8$32
2.5 GbE managed switch (8-port)1$45$45
Cat6a patch cables (0.5 m)4$3$12
M.2 NVMe HAT + 500 GB drive1$45$45
Total$522
💡
TipDrop one Pi 5 to the 4 GB model and skip the NVMe HAT to slide under $500 flat.

Hardware Assembly

Mount each Pi on its active cooler, insert the microSD, and connect power and Ethernet. Label every cable and port with a label maker—future-you will thank present-you during a 2 a.m. debug session. Place the NVMe HAT on the designated storage node (node-0) for etcd and persistent volumes.

OS Baseline & PXE Boot

Flash Raspberry Pi OS Lite (64-bit) to every card. Enable SSH, set static hostnames (node-0 through node-3), and configure the switch port for node-0 as PXE server. Use rpi-eeprom-config to set BOOT_ORDER=0xf21 so nodes attempt network boot before SD. This lets you reimage the entire cluster by updating one TFTP directory.

bash
# On node-0 (PXE server)
sudo apt update && sudo apt install -y dnsmasq nfs-kernel-server
sudo systemctl enable --now dnsmasq nfs-server
# Export /srv/nfs/pi5 as rootfs for netboot

K3s Control Plane

Install K3s on node-0 with embedded etcd and the NVMe-backed data dir. Join the remaining nodes as agents. Disable Traefik and ServiceLB; we will deploy MetalLB and NGINX Ingress ourselves for tighter control.

bash
# node-0
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik,servicelb --data-dir=/mnt/nvme/k3s" sh -
# nodes 1-3
curl -sfL https://get.k3s.io | K3S_URL=https://node-0:6443 K3S_TOKEN=$(cat /mnt/nvme/k3s/server/node-token) sh -

Networking & Storage

Deploy MetalLB in Layer 2 mode for LoadBalancer IPs (192.168.1.200-210). Add Longhorn for replicated block storage across the three agent nodes; keep the NVMe volume on node-0 exclusively for etcd. Enable CSI snapshots for painless backup/restore.

yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: homelab-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.200-192.168.1.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2-advert
  namespace: metallb-system

Observability Stack

Helm-install kube-prometheus-stack and Loki/Promtail. Scrape interval 15s, retention 14d. Alert on CPU > 80%, memory > 85%, and etcd latency > 100 ms. Grafana dashboards imported: 315 (Kubernetes), 1860 (Node Exporter), 12412 (Longhorn).

⚠️
WarningDisable swap on all nodes (<code>sudo swapoff -a && sudo sed -i '/swap/d' /etc/fstab</code>) or kubelet will refuse to start.

Validation & Chaos

Run kubectl get nodes -o wide and verify all four show Ready. Deploy a test workload: three replicas of nginx behind a MetalLB Service. Pull power on node-2; confirm pods reschedule within 40 seconds and Longhorn rebuilds the replica. That is your resilience proof.


✦

You now own a four-node, HA Kubernetes cluster that cost less than a mid-range GPU. Next step: GitOps with Flux, secrets via SealedSecrets, and a CI pipeline that deploys to this cluster on every merge. The hardware is paid for; the learning curve is yours to climb.

Share𝕏 Twitterin LinkedInin Whatsapp