Kubernetes Home Lab
What it is
A lightweight Kubernetes cluster running on a handful of small machines at home. It hosts the services that used to run as standalone containers, and it is the environment most of this site's infrastructure lessons come from.
The control plane runs three nodes with embedded etcd, so the cluster has a real quorum instead of a single point of failure. The nodes started on Wi-Fi and were later moved to wired networking: etcd peer traffic is sensitive to latency and packet loss in ways ordinary workloads are not.
Architecture
Control plane
Three nodes run the API server, scheduler, controller manager and embedded etcd. A virtual IP managed by kube-vip provides a single stable API endpoint and floats between the control-plane nodes.
Ingress
Traefik is the bundled ingress controller. Services are exposed by hostname, and the load-balancer service is reachable on every node.
Storage
Longhorn provides replicated block storage for stateful workloads, with volumes attached to whichever node is running the workload.
Delivery / GitOps
Workloads and configuration live in a Git repository and are reconciled into the cluster by Flux CD:
- A monorepo holds cluster-level configuration under
clusters/and one directory per application underapps/. - Each application has a
base/directory of Kubernetes manifests plus a FluxKustomizationthat defines its reconciliation interval, pruning, health checks and dependencies. - Changes are committed to Git rather than applied directly to the cluster;
rolling back is a
git revert. - Secret material is encrypted in Git with SOPS and an age key. The cluster holds only the decryption key, injected into the GitOps controller during bootstrap, so secrets stay reviewable in Git without appearing in plain text.
Components
Components live here, not as projects of their own:
- Grafana / Prometheus / Alertmanager — metrics, dashboards and alerting.
- Longhorn — the storage layer behind persistent volumes.
- kube-vip — the virtual IP that keeps the API endpoint reachable when a control-plane node goes down.
Story
The cluster replaced a collection of docker-compose stacks that had become impossible to reason about. Moving to Kubernetes gave every service a common deployment model; moving delivery to Git later made the cluster reproducible instead of remembered.
Delivery started with manual kubectl apply and ad-hoc Helm commands, which
worked until they did not: reconstructing what the cluster actually contained
meant inspecting it piece by piece. Migrating to Flux and SOPS turned the
cluster into the output of a repository, and onboarding a new application into
"add a directory and a Kustomization" instead of replaying a sequence of
remembered commands.
The most expensive lesson so far came from treating a high-availability control plane as a checkbox. Quorum tolerates exactly one failure, and a broken network path can take down more than one node at once — which is how a small routing problem turns into an extended outage.
Journal
Ingress and VIP design for a home Kubernetes cluster
How traffic reaches a small cluster from the internet and from the LAN, and why a single virtual IP is not the same as high availability.
Migrating a K3s etcd cluster from Wi-Fi to wired networking
Moving a three-node control plane off Wi-Fi to eliminate etcd peer timeouts and restore a stable quorum.
How a leftover kube-vip DaemonSet poisoned ARP and broke etcd quorum
A post-mortem of a cluster outage caused by a reverted VIP experiment, a stuck DaemonSet and a router ARP table with one MAC address for many IPs.
Migrating a cluster to GitOps with Flux and SOPS
Replacing ad-hoc kubectl and Helm apply with a Git repository as the source of truth, including encrypted secrets.
Tailscale subnet routers and asymmetric routing on the home LAN
A LAN host became unreachable from its own network while still reachable over Tailscale. The cause was a subnet router advertising the very subnet it lived on.
Alerting on a small Kubernetes cluster
Prometheus decides that something is wrong; Alertmanager decides whether anyone hears about it. The second part deserves as much design attention as the first.