kubeadm Playground
A single-machine playground to experiment with kubeadm, a tool built to provide best-practice "fast paths" for creating Kubernetes clusters.
This is a single-machine playground. A multi-machine playground for larger and HA clusters is WIP.
๐ง System Components
kubelet: The primary node agent that runs on each node- Container Runtimes:
- containerd: Lightweight container runtime (recommended)
- CRI-O: Lightweight container runtime for Kubernetes
- Networking:
- CNI plugins: Container Network Interface plugins
- Flannel: Network overlay for pod-to-pod communication
- Canal: Calico for network policy and Flannel
๐ ๏ธ Tools
kubeadm: Cluster lifecycle management and bootstrappingkubectl(alias:k): Kubernetes cluster management and debuggingnerdctl: Docker-compatible CLI forcontainerdkrew:kubectlplugin manager for extending functionality
๐ฏ Getting Started
Quick Setup
If you want to quickly set up a working cluster, use the automated script:
/opt/lab/init.sh --remove-taint
Available options
| Option | Default | Description |
|---|---|---|
--remove-taint | false | Remove the NoSchedule taint that may prevent pods from being scheduled to this node. |
--cni | flannel | Network add-on to install. Valid values: none, flannel, canal |
--no-load-images | false | Do not load the images from local cache. |
โ ๏ธ When none is selected as the network addon, the initialization script will skip installing any CNI plugin.
On the dev-machine, run the following command to configure kubectl:
/opt/lab/configure.sh
Manual Setup
For a manual setup, check out this tutorial.
Verify Your Cluster
# Check all system pods are running
kubectl get pods --all-namespaces
# Deploy a test application
kubectl create deployment podinfo --image=ghcr.io/stefanprodan/podinfo --port=9898
kubectl expose deployment podinfo --port=9898
# Wait for the pod to be ready
kubectl wait --for=condition=Ready pods --all --timeout=300s
# Check the deployment
kubectl get pods,services
# Send a request to the application
curl http://$(kubectl get svc podinfo -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')
Resetting the Cluster
The easiest way to reset the cluster is terminating the playground and starting a new one.
That being said, it's a good idea to learn how to reset the cluster manually.
First, reset the cluster itself using kubeadm:
kubeadm reset -f
Stop kubelet:
systemctl stop kubelet
Then cleanup any CNI config created by the network addon you installed:
rm -rf /etc/cni/net.d/*.{conf,conflist}
Delete any CNI interfaces created by the network addon:
ip link delete cni0
# For flannel
ip link delete flannel.1
๐ Learn More
- Kubernetes
- Container runtimes
- Networking
๐งฉ Related Content
๐ Tutorials
๐งช Playgrounds
- Kubernetes Playgrounds (official)
- contaiNERD CTL (official)
- containerd
- CRI-O
Happy learning! ๐
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 โ