k3s: Kubernetes That Fits in a Homelab
k3s gives a homelab the same orchestration primitives as production Kubernetes, at a fraction of the hardware cost — the honest head-to-head.

My git runner choked on a Friday night. I had a handful of AI agents building three or four separate apps in parallel, each one kicking off a build the moment it pushed, and the single runner pod fell behind and started queueing jobs like a barista during a rush it didn’t staff for.
The fix wasn’t a rebuild, a bigger box, or a support ticket. It was one line:
kubectl scale deployment/forgejo-runner --replicas=3Three pods, same node pool, jobs draining within a minute. That’s the whole pitch for k3s in a homelab, distilled into one command: it’s not a toy version of Kubernetes, it’s the same orchestration primitives production clusters run on, sized for hardware you’d otherwise call “too small for this.”
Where I started
Before k3s, I ran Docker Swarm and, before that, plain docker compose up on VMs on
Proxmox. Both are genuinely good for day-to-day container management — Swarm in
particular has built-in DNS-based service discovery and load balancing that “just
works” without any extra pieces. I iterate constantly — new app idea most weekends —
and Swarm and bare Compose kept working for the boring, single-service cases. Where
they ran out of road was the moment I wanted a rolling update that didn’t drop
connections, a secret that wasn’t a plaintext file mounted into a container, or an
ingress and service-discovery layer that didn’t need me to hand-wire it per app. k3s
gave me all three as defaults, not add-ons.
The head-to-head
Here’s the honest comparison, engineering angle only — what each platform actually gives you versus what you have to bolt on yourself, going by the same four questions every time: rolling updates, secrets, ingress, and what it costs at idle. (The idle numbers below are pulled from third-party benchmarks, not vendor specs — treat them as directional, not exact.)
| Platform | Rolling updates | Secrets | Ingress | Idle footprint | License / cost |
|---|---|---|---|---|---|
| k3s | Native | K8s Secrets API, GitOps-ready | Traefik, bundled | ~450–500MB | Apache 2.0, free |
| Docker Swarm | Yes, no readiness gating | Docker secrets, no rotation | DNS-based, built-in LB | Minimal, no extras | Apache 2.0, free |
| Proxmox + Compose | Manual | Env vars / plaintext | Hand-wired per app | Bare Docker only | AGPLv3, free (support optional) |
| TrueNAS SCALE Apps | Compose-level | Compose env/secrets | App-template dependent | Appliance-level | Open source CE, free (paid Enterprise tier) |
| Unraid | Manual recreation | Plaintext env vars | None built-in | Appliance-level | Proprietary — license required, from ~$49 |
| kubeadm (vanilla k8s) | Native | Full Secrets API, etcd-backed | Your choice of controller | ≥2 cores / ≥2GB RAM min | Apache 2.0, free |
A few of those rows are worth a second look on their own.
kubeadm is where the “fraction of the hardware cost” claim gets concrete. k3s ships as a single binary under 100MB. Its agent (worker) minimum is 1 core / 512MB RAM — k3s’s own server (control-plane) node wants the same 2 cores / 2GB RAM as kubeadm’s baseline, so the real saving shows up as you add workers: every extra k3s agent costs 512MB, every extra kubeadm node costs 2GB, and that’s before you’ve stood up an ingress controller, a CNI, or anything else k3s bundles for free. The other half of the gap is the datastore: standard Kubernetes runs on etcd, a distributed key-value store that wants its own resources and its own operational attention; k3s defaults to an embedded SQLite database with near-zero overhead. The catch is that SQLite only backs a single k3s server — there’s no HA control plane without switching to embedded etcd or an external database. That’s a real constraint, just not one to lose sleep over in a homelab: one server node is exactly what I run.
TrueNAS SCALE is the twist I didn’t expect. It actually ran k3s under the hood for its Apps feature for years — until the 24.10 “Electric Eel” release, when iXsystems ripped it out in favor of a native Docker engine, because the k3s-based system had become “cumbersome and complicated to manage” for their appliance users. That’s not a knock against k3s. It’s a difference in who the tool is for: an appliance optimized for point-and-click app installs doesn’t want rolling updates and a Secrets API, it wants one button that doesn’t break. A developer iterating on their own infrastructure wants exactly the opposite.
Nomad is the honest outlier. A bare Nomad agent idles around 60–80MB in third-party benchmarks — genuinely lighter than k3s’s bundled 450–500MB. But that’s the agent alone, with no ingress controller, no service mesh, no DNS, nothing k3s ships by default. The real comparison isn’t “80MB vs 500MB,” it’s “80MB plus whatever you bolt on” versus “500MB with half the pieces already in the box.” And the ecosystem argument tips it further: most self-hosted apps ship Helm charts or Kubernetes manifests; almost none ship Nomad job specs. It’s also not free-as-in-freedom the way the rest of this list is — HashiCorp relicensed Nomad under BSL 1.1 in 2023, source-available rather than OSI open source. Free to run in a homelab, just not Apache 2.0.
k0s is genuinely leaner than k3s, if you’re chasing the smallest possible footprint — benchmarked around 400–600MB at a steady 12% idle CPU against k3s’s ~20%. It’s plain vanilla Kubernetes with nothing extra bundled in, which is also its tradeoff: no Traefik, no opinionated defaults, more assembly required. Apache 2.0, same as k3s — no licensing catch here. If minimal resource use is the entire goal, k0s earns a look. If you want the biggest pile of tutorials and homelab-specific guides when something breaks at midnight, k3s wins on sheer ecosystem gravity.
The hardware this runs on
None of this is running on a rack of enterprise gear. The whole cluster lives on three secondhand small-form-factor PCs — Dell OptiPlex and Lenovo ThinkCentre Micro/Tiny boxes, corporate lease returns, upgraded with aftermarket RAM — for under R19,000 total. I wrote up the actual hunt for that hardware in Using AI to hunt homelab deals in South Africa. The point that matters here: this is genuinely modest hardware running a full GitOps-driven cluster — ArgoCD, Traefik with real TLS, ingress, ephemeral CI runners — and it does it comfortably. That’s the resource-cost argument from the table above, made physical.
The moment it clicked
The scaling story up top is the punchiest example, but the first time it actually
clicked for me was smaller: pushing a commit to main and watching ArgoCD pick it up,
diff it against the live cluster, and reconcile the change without me touching
kubectl at all. Git as the source of truth, the cluster as a thing that converges
toward it instead of a thing you imperatively poke — that’s a genuinely different way
to think about infrastructure than docker compose up -d ever was.
The runner-scaling moment is the same idea under load. Multiple agents building separate apps at once isn’t a scenario I planned for, it’s just what happens when you let AI agents loose on a weekend. The infrastructure not caring — just bumping a replica count and moving on — is the actual payoff of everything in the table above.
The learning curve is real, and worth it
I won’t pretend this was free. kubectl, Helm charts, and Kubernetes’ own vocabulary —
Deployments vs. StatefulSets vs. DaemonSets, what a Service actually routes to, why an
Ingress needs a controller before it does anything — took real time to get comfortable
with, more than Swarm or Compose ever asked of me. That tax is the honest tradeoff
against everything above. I paid it once. Every weekend project since has been cheaper
because of it.
k3s isn’t Kubernetes-lite in the sense of missing pieces. It’s the full toolset, sized for the hardware I can actually afford, and it gave me a homelab that behaves like production infrastructure instead of a pile of containers I have to babysit.