A production-grade home lab Kubernetes cluster running on Raspberry Pi 4B devices using k3s. The cluster hosts home network infrastructure (DNS, NTP, monitoring) and public-facing services (URL shortener, uptime monitoring) with TLS, high availability, and automated deployment.
The project is divided into two parts:
rpi/— One-time provisioning scripts that prepare a fresh Raspberry Pi OS install as a k3s master or worker node. Run in order withsudoon each device; seerpi/README.mdfor step-by-step instructions.k8s/— Kubernetes manifests and Helm values that define all cluster services. Deployed viak8s/src/deploy.sh(ordeploy-from-local.shfrom a workstation). Seek8s/README.mdfor the full service catalog.
- At least two Raspberry Pi 4B's (8 GB models recommended)
- Raspberry Pi OS (64-bit, Lite) written to a Micro SD card
- Static IP reservations for all nodes (MAC-based via DHCP/router)
- An SSH key for passwordless login
- SSH enabled on first boot (
touch /Volumes/bootfs/sshon macOS, or enable via Raspberry Pi Imager) - Recommended: a domain name you control (otherwise
.home.arpaworks)
-
Clone the repository onto each Raspberry Pi:
mkdir -p ~/src && cd ~/src git clone https://github.com/brandonmartinez/raspberry-pi-kubernetes-cluster.git cd raspberry-pi-kubernetes-cluster
-
Copy the sample environment file and customize it for your network:
cp .env.sample .env nano .env
The
.envfile powers both the provisioning scripts (rpi/src/) and the Kubernetes deployments (k8s/src/). Keep real secrets out of source control and document any new variables in.env.sample. -
On every node, run the numbered scripts in
rpi/src/withsudo, rebooting when prompted. Script004.shinstalls k3s — run it without arguments on the master and withPRIMARY_IPandTOKENarguments on workers. Seerpi/README.mdfor detailed steps. -
After the cluster is ready, deploy services:
- From the master node:
cd ~/src/raspberry-pi-kubernetes-cluster/rpi/src/ && sudo ./005.sh - From a workstation:
cd k8s/src && ./deploy-from-local.sh(fetches the live kubeconfig via SCP and runsdeploy.sh)
deploy.shassembles a temporarykustomization.yml, renders manifests withkubectl kustomize | envsubst, and applies them. Literal$characters in YAML are preserved by writing${DOLLAR}in source files. - From the master node: