On this page
You’ve been running containers for a while. Docker Compose brings your stack up, and it’s been fine. Then one night a container dies and stays dead until you notice. Or one machine fills up and you wish the load could spill onto another. Or you just keep hearing the word Kubernetes and want to know what everyone’s on about. That’s what this post is for.
I’ll explain Kubernetes — “K8s” for short — in plain English, no cloud-architect vocabulary. By the end you’ll know what a pod, a node, the control plane, a service, and an ingress actually are, and whether any of it belongs in your homelab.
The one idea underneath all of it
Here’s the mental model that makes everything else click: Kubernetes is declarative. You don’t tell it “start this container.” You tell it “I want three copies of this app running, always” — and then Kubernetes takes responsibility for making that true and keeping it true. A container crashes? It starts another. A machine dies? It reschedules that machine’s work elsewhere. You describe the destination; it drives.
That constant “compare what-is to what-should-be, then fix the gap” loop is called reconciliation, and it’s the heartbeat of the whole system.
Everything below is just the vocabulary for the pieces in that picture.
Nodes: the machines that do the work
A node is a worker machine — a physical box, a VM, or an LXC container — that actually runs your containers. A cluster is just a set of nodes pooled together so your workloads can land on whichever one has room. On each node runs an agent called the kubelet, whose job is simple to state: make sure the containers that are supposed to be running here actually are.
The control plane: the brain that decides
If nodes are the hands, the control plane is the brain. It’s the set of components that hold the desired state and drive the cluster toward it. You don’t run apps here; you run the decision-making. Its main parts, in plain terms:
- kube-apiserver — the front door. Every command and every component talks through this HTTP API. When you run
kubectl, you’re talking to the API server. - etcd — the memory. A consistent, highly-available key-value store that holds all cluster data: what should exist, and what currently does.
- kube-scheduler — the placement engine. It spots pods that haven’t been assigned a home yet and picks a suitable node for each.
- kube-controller-manager — the enforcers. It runs the control loops that notice “desired says 3, reality says 2” and act to close the gap.
That last one is the reconciliation loop from the top of the post, made concrete.
Pods: the smallest unit Kubernetes runs
You’d expect the basic unit to be “a container.” It’s almost that: it’s a pod — one or more containers that share a network address and storage and are always scheduled together onto the same node. In practice the overwhelming majority of pods hold exactly one container; the multi-container case is for tightly-coupled helpers.
Here’s the important habit: you almost never create pods yourself. You create a higher-level object — most often a Deployment — that says “keep 3 replicas of this pod.” The Deployment creates the pods, replaces them when they die, and handles rolling updates. Pods are cattle, not pets; the Deployment is the rancher.
Because a Deployment can recreate a pod at any moment on any node, pods are treated as throwaway. That’s the source of Kubernetes’ self-healing — but it’s also why “where does my data live?” becomes its own topic (persistent volumes), separate from the pod itself.
Services and ingress: how anything reaches your app
Disposable pods create a puzzle: if a pod can be replaced at any time — new pod, new internal IP — how does anything reliably talk to it? Two objects solve that.
- A Service is a stable front for a changing set of pods. It gets a fixed cluster address and load-balances across whichever pods currently match it. Pods come and go; the Service address stays put.
- An Ingress handles traffic arriving from outside the cluster — HTTP and HTTPS routing by hostname and path, sending
photos.homelab.lanto one Service andgrafana.homelab.lanto another. If you’ve used a reverse proxy, an Ingress is the same idea, expressed the Kubernetes way. (k3s even ships Traefik as its default ingress controller.)
So should you run it at home?
Let me be honest, because the hype rarely is: most homelabs do not need Kubernetes, and that’s completely fine. If Docker Compose on one box covers your services, adding Kubernetes trades a simple system you understand for a complex one you’re still learning — more moving parts, more ways to get stuck.
It becomes genuinely worthwhile when one of these is true:
- you want self-healing and high availability across more than one machine;
- you’re learning the tool that runs a huge share of the modern cloud, on purpose, for your career;
- you’ve outgrown “one host” and want workloads to schedule across a pool.
If that’s you, the good news is you don’t start with the heavyweight version. A single-binary distribution called k3s gives you real, compliant Kubernetes on hardware as small as a mini PC — and that’s exactly where the companion how-to picks up.
Related posts:
- How and When to Use Kubernetes in a Homelab — the hands-on companion: install k3s, deploy your first app, and an honest look at when it’s overkill.
- Your First Docker Compose Stack — the simpler tool Kubernetes is often compared to; master this first.
- Docker on Proxmox: LXC vs VM, Done Right — where your containers run before you ever reach for an orchestrator.
- Proxmox VM vs LXC: Which to Use — the kind of node a homelab Kubernetes cluster runs on.
- What Is Traefik? The Reverse Proxy, Explained — the same routing idea an Ingress expresses inside a cluster.
- Build a Proxmox Cluster — pooling machines at the hypervisor layer, a useful comparison to pooling them at the container layer.
Comments
Comments are powered by GitHub Discussions — sign in with a GitHub account to join the conversation.