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
| Component | Qty | Unit Cost | Total |
|---|---|---|---|
| Raspberry Pi 5 (8 GB) | 4 | $80 | $320 |
| Official 27 W USB-C PD PSU | 4 | $12 | $48 |
| Active cooler + fan | 4 | $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 drive | 1 | $45 | $45 |
| Total | $522 |
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.
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.
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.
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).
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.