Kubernetes the Hard Way Playground
A manually assembled Kubernetes cluster, inspired by Kelsey Hightower's "Kubernetes the Hard Way" tutorial.

Welcome to the Kubernetes the Hard Way lab environment!
This playground is inspired by Kelsey Hightower's tutorial of the same name...
... with one key difference: everything is already set up and ready for you to explore!
No need to manually provision VMs on a cloud provider or spend hours configuring each component from scratch.
The goal of this playground is to provide a learning environment for exploring and understanding the inner workings of a Kubernetes cluster.
The configuration and operational practices presented here are NOT recommended for production use.
Try this at home (not at work!)
People often say "don't try this at home" when they're doing something dangerous.
In this case, you should try this at home instead of at work.
Your production clusters will thank you for learning the hard way in a safe environment first! 😉
What makes this different?
This lab environment provides the end result of Kelsey's tutorial: a fully functional, manually assembled Kubernetes cluster where every component runs as a systemd service (rather than as containers).
Instead of spending hours setting up cloud VMs and configuring each component, you can jump straight into exploring and learning from a working "hard way" cluster.
In addition to Kelsey's original tutorial setup, this lab also includes:
- CoreDNS for DNS resolution within the cluster
- Flannel as a network addon (replacing static routes for Pod networking)
Architecture overview
This cluster consists of multiple nodes running various Kubernetes components as systemd services. The architecture follows the traditional Kubernetes design, but with everything running on the host system rather than in containers.
Control Plane
The control plane runs the core Kubernetes services that manage cluster state and make scheduling decisions.
Control plane components
These components are essential for the control plane to function properly:
| Component | Role |
|---|---|
| etcd | Distributed key-value store that holds all cluster data. |
| kube-apiserver | The heart and soul of the Kubernetes control plane, exposing the Kubernetes API. |
| kube-controller-manager | Manages various controllers that maintain the desired state of the cluster. |
| kube-scheduler | Schedules Pods onto Nodes based on resource availability and other constraints. |
| CoreDNS (optional) | Provides DNS resolution and service discovery for the cluster. |
Worker nodes
Worker nodes run the actual workloads and provide the runtime environment for pods.
Worker node components
| Component | Role |
|---|---|
| kubelet | Primary node agent that ensures containers are running in pods. |
| Container Runtime (containerd) | Manages container creation, execution, and cleanup. |
| Network addon (flannel) | Provides networking for pod-to-pod communication. |
| kube-proxy | Network proxy that maintains network rules on nodes for service networking. |
Getting Started
- Explore the environment: Each component's systemd service file shows exactly how Kubernetes components are configured
- Check service status: Use
systemctl status <service-name>to see the health of each component - Review logs: Use
journalctl -u <service-name>to view detailed logs for troubleshooting - Modify configurations: Edit service files and restart services to see how changes affect the cluster
- Break things safely: This is a learning environment—experiment with stopping services or changing configurations
Versions
The playground comes with the following component versions:
- containerd: 2.1.4
- runc: v1.3.0
- CNI plugins: v1.7.1
- nerdctl: 2.1.3
- etcd: v3.6.4
- Kubernetes: v1.34.0
- Network addon (flannel): v0.27.2
- CNI plugin: v1.7.1-flannel2
- CoreDNS: 1.12.2
(Kinda) Certified

Here's a fun fact: this manually assembled, systemd-managed Kubernetes cluster actually passes the sonobuoy conformance tests!
This means our "distribution" of Kubernetes could technically be submitted for official CNCF certification. Of course, we're not going to certify "Kubernetes the Hard Way on systemd" as an official distribution, but it's impressive that a cluster assembled entirely by hand can meet the same standards as enterprise-grade Kubernetes platforms.
This demonstrates that under the hood, Kubernetes is "just" a collection of well-designed, interoperable components.
So congratulations—you're playing with a (kinda) certified Kubernetes distribution! 🎉
A real VM, not a container
Get root on a VM with its own kernel, so Docker, Kubernetes, and systemd just work.
Read the docs →
SSH from browser or CLI
Use the built-in web terminal, or connect with labctl ssh, plain ssh, scp, or rsync.
Read the docs →
Drive it with AI
Let Claude, Codex, or any MCP client start this playground and run commands in it.
Read the docs →
Expose HTTP(S) ports
Give any web app running inside the VM a public URL - for yourself or to share with others.
Read the docs →
Share terminals
Invite others into your terminal session, or open it yourself from another device.
Read the docs →
Customize with init scripts
Add shell scripts that run at boot to install packages, clone repos, or seed test data.
Read the docs →
Private networking
VMs reach the internet via NAT with no public IP; several VMs share bridge networks.
Read the docs →
Ephemeral or persistent
By default, VMs are destroyed when the session ends; enable persistence to keep the disks for next time.
Read the docs →
Built-in container registry
A private registry.iximiuz.com for every playground to share images across services and VMs.
Read the docs →