There is a small K3s cluster running in my house. Most days I do not think about it, which is the nicest thing I can say about home infrastructure.
It runs the unglamorous services that make the rest of the network feel normal: local DNS, a few dashboards, home-automation helpers, and the internal tools I use for side projects. None of it is dramatic. When it works, the cluster is mostly invisible.
Getting it that quiet took some work.
Why K3s ended up here
I did not choose Kubernetes because these workloads demand it. A handful of containers would run fine under Docker Compose. I chose K3s because I wanted a real Kubernetes API without turning the lab into a full-time job.
It gives me a place to learn the parts that are hard to understand from a tutorial: how scheduling feels when a node disappears, how persistent workloads constrain upgrades, and how DNS, ingress, storage, and certificates combine into one request path.
The cluster is small on purpose. The nodes are ordinary machines already suited to staying on. I would rather understand a modest setup than operate a miniature copy of a cloud platform. There is no service mesh and no internal developer platform. Most workloads are a Deployment or StatefulSet, a Service, and an Ingress.
That is enough complexity for a house.
Git is how I remember what I did
I keep the Kubernetes manifests in Git and organize them by service. Namespaces, configuration, storage claims, and ingress rules are visible in the same place. Secrets take a separate path and are decrypted only where they are needed.
This is not about fashionable GitOps vocabulary. I have an unreliable memory. If I change a port from the command line at midnight, I will not remember it later. If I change a manifest, the diff tells me what happened and gives me a way back.
I still use kubectl for inspection. I try not to use it as a configuration database.
My usual deployment loop is boring on purpose:
- Edit the manifest locally.
- Review the diff.
- Apply the change.
- Watch the rollout and events.
- Confirm the service from a browser or DNS client, not from inside the pod.
That last step has caught more mistakes than any complicated health check. A green pod does not prove that DNS resolves, the ingress routes correctly, or a browser can complete the request.
Persistent storage is the limit
Stateless services are easy. They can land on another node and start again. State is where the cluster stops being an abstract learning environment and starts holding things I care about.
I keep persistent storage simple and make the backup boundary explicit. Application data is backed up. Containers and generated files are not. I also keep a note describing how to restore each important service. A backup job that reports success is comforting. A restore procedure is evidence.
This setup does not pretend that every disk or node can fail without interruption. Some services will be down while I repair something. I accept that, because extra storage layers would be more systems to understand and maintain.
AI is a helper, not a cluster operator
The cluster is also a useful sandbox for AI-assisted engineering. I have used coding agents to draft a first version of a manifest, compare an application’s environment variables with its documentation, and turn a messy troubleshooting session into a short runbook.
I do not let an agent improvise changes against the live cluster. Generated YAML can be syntactically valid and still be wrong in ways that matter: an overly broad security context, a missing resource limit, storage mounted at the wrong path, or a Service selector that matches nothing.
The safe workflow is the same one I use for code. Let the tool propose a change, inspect the diff, validate it, then watch what actually happens. The cluster is small enough that I can keep the whole change in my head.
Leave it alone
I occasionally want to add another controller, dashboard, or automation layer. Usually I wait. If the same problem annoys me three times, it may deserve a tool. If not, a paragraph in the runbook is often enough.
What I ended up with would make a boring cluster diagram. I mean that as a compliment. It gives me hands-on practice and supports daily life without asking to be noticed. I can experiment with a new workload, learn something about Kubernetes, and remove it again without rebuilding the foundation.
I wanted a cluster that still teaches me, and that I can ignore for a week.