Learn Kubernetes by building a real cluster with
kubeadm, one component at a time.
Problem: Running containers by hand —
docker runon one machine, restarting them when they crash, wiring up networking, scaling by copy-paste — falls apart the moment you have more than one container or more than one machine.Solution: Kubernetes lets you declare the desired state of your apps in YAML and continuously reconciles reality to match it — self-healing, scaling, rolling out new versions, and routing traffic, all repeatably.
Many tutorials start you off on minikube or kind — quick to set up, but the components are mostly hidden. Here you stand up a real, upstream Kubernetes cluster with kubeadm instead, learn it by taking every component apart — kube-apiserver, etcd, kubelet, the CNI — and then put it to work, watching the cluster live in k9s.
Every concept is paired with a runnable kubectl apply example, all building toward one concrete outcome: deploying a two-tier app (web + database) — configured with ConfigMaps/Secrets, persisted on a PVC, exposed through a Service + Ingress — then rolling out an update and tearing it back down.
No prior Kubernetes experience assumed. New to k8s? Read top to bottom. Already know the basics? Jump straight to the Table of Contents.
The single-node cluster you'll build by hand — control plane and your app on one machine:
---
config:
look: handDrawn
theme: default
themeVariables:
fontFamily: '"Comic Sans MS", "Comic Sans", "Segoe Print", "Bradley Hand", cursive'
clusterBkg: '#FAFAFA'
clusterBorder: '#94A3B8'
lineColor: '#FFFFFF'
edgeLabelBackground: '#475569'
themeCSS: |
.edgeLabel, .edgeLabel p, .edgeLabel span { color: #FFFFFF !important; }
---
flowchart TB
you(["👩💻 you<br/>kubectl · k9s"])
subgraph host["🖥️ Your ONE node"]
direction TB
subgraph cp["🧠 Control Plane · static Pods"]
direction LR
sched["📌 kube-scheduler"]
kcm["🔁 kube-controller-manager"]
api["🚪 kube-apiserver<br/>the front door"]
etcd[("🗄️ etcd<br/>cluster state")]
sched --> api
kcm --> api
api <--> etcd
end
subgraph runtime["⚙️ Node Runtime"]
direction LR
kubelet["🤖 kubelet<br/>runs Pods on this node"]
cri["📦 containerd<br/>CRI runtime"]
proxy["🔀 kube-proxy<br/>Service routing"]
end
pods["🚀 your Pods<br/>web & database"]
subgraph addons["🔌 Add-ons · also Pods"]
direction LR
cni["🌐 CNI · flannel<br/>pod networking"]
dns["📇 CoreDNS<br/>in-cluster DNS"]
end
kubelet --> cri --> pods
proxy -. routes traffic to .-> pods
cni -. networking .-> pods
dns -. DNS .-> pods
end
you --> api
api ==>|"schedule & run"| kubelet
classDef ctrl fill:#0F172A,stroke:#2563EB,stroke-width:2px,color:#FFFFFF
classDef eng fill:#D97706,stroke:#92400E,stroke-width:3px,color:#FFFFFF
classDef tgt fill:#0F172A,stroke:#16A34A,stroke-width:2px,color:#FFFFFF
class you ctrl
class api eng
class etcd,sched,kcm,kubelet,proxy,cri,pods,cni,dns tgt
linkStyle 9 stroke:#D97706,stroke-width:3px
style host fill:#1E293B,stroke:#334155,color:#F1F5F9,fillStyle:solid
style cp fill:#000000,stroke:#94A3B8,color:#FFFFFF,fillStyle:solid
style runtime fill:#000000,stroke:#94A3B8,color:#FFFFFF,fillStyle:solid
style addons fill:#000000,stroke:#94A3B8,color:#FFFFFF,fillStyle:solid
Every box above is something you set up and understand with kubeadm — not a black box a one-line installer hid from you.
"kubeadm" is not a different kind of Kubernetes. It's the official installer that assembles upstream components the standard way — so a kubeadm cluster is plain, vanilla Kubernetes (the same thing the official docs and the CKA exam describe). k3s, by contrast, is a repackaged lightweight distro with batteries-included defaults baked in. Analogy: Kubernetes is the Linux kernel, kubeadm is a clean standard install, k3s is a pre-loaded distro like Ubuntu. More in Architecture Overview.
By the end you'll be able to:
- Read the architecture and say what each component does — control plane vs. node (see the diagram above).
- Deploy and expose apps with the core objects: Pods, Deployments, Services.
- Separate config from images with ConfigMaps and Secrets, and persist data with PersistentVolumeClaims.
- Keep apps healthy and current — health probes, resource limits, scaling, and rolling updates with rollback.
- Control where Pods run and who can touch them — taints/tolerations for placement, RBAC and NetworkPolicy for access control.
- Route traffic in with an Ingress, and debug confidently when things break.
- Tie it all together in the capstone: a Vue + FastAPI Todo app — configured, persisted with SQLite on a PVC, exposed, updated, and torn down.
Every section is hands-on: a manifest you kubectl apply, then watch take effect.
A Linux host (or WSL2 / a VM), kubectl installed, and basic shell + container familiarity.
For the kubeadm path, use a fresh Linux machine where you can run sudo (Ubuntu is the assumed happy path in the companion Ansible role). A single-node lab is comfortable with 2 vCPU, 4 GB RAM, and 20 GB disk. Start from a clean host if you can; old container runtimes, stale kubeconfigs, or half-removed clusters make first-time Kubernetes debugging unnecessarily noisy.
You'll need a cluster to follow along. Two ways to get one:
-
The real lesson — build it with kubeadm. Provision the single-node cluster with the companion Ansible tutorial → kubeadm Role, then read Set Up a Cluster (kubeadm) to understand every component you just stood up. This is the path the guide is built around.
-
Fast lane — just want to run the examples? Spin up a real single-node cluster with k3s in one line and circle back to kubeadm later:
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644 export KUBECONFIG=/etc/rancher/k3s/k3s.yaml # so plain kubectl just works
This is convenient for a throwaway lab, but it still runs a remote install script as root. For anything beyond a local practice VM, inspect the script first or use your platform's normal package/install process.
k3s is great for running the manifests quickly, but its defaults are not identical to bare kubeadm: it may include built-in storage, ingress, and load-balancer helpers that vanilla kubeadm does not. When this guide calls that out, trust the kubeadm behavior as the main lesson.
Before starting Part 1, verify your cluster is reachable and healthy:
kubectl get nodes # one node, STATUS Ready
kubectl get pods -n kube-system # CoreDNS, kube-proxy, flannel, and control-plane Pods RunningIf those commands fail, finish Set Up a Cluster (kubeadm) or fix your kubeconfig before continuing.
Getting Started
- What is Kubernetes? — declarative vs. imperative; the one idea behind everything.
- Architecture Overview — every component, and why a kubeadm cluster is vanilla k8s.
- Set Up a Cluster (kubeadm) — build the cluster, then understand each piece the installer wires up.
- kubectl 101 — the everyday commands you'll live in.
- Anatomy of a Manifest —
apiVersion/kind/metadata/spec, once and for all. - Inspect with k9s — a live terminal dashboard for your cluster.
Part 1 — Core Objects
- Pod — the smallest thing Kubernetes runs.
- Labels & Selectors — the glue wiring objects together.
- Deployment — keep N replicas alive and roll out updates.
- ReplicaSet — what actually maintains the replica count.
- Scheduling, Taints & Tolerations — control where Pods can land.
- DaemonSet (intro) — one Pod per node.
- Job & CronJob — batch and scheduled work.
- Service — a stable address + load balancer for Pods.
- Namespace — partition the cluster.
Part 2 — Configuration & Data
- ConfigMap — keep config out of the image.
- Secret — sensitive values.
- Environment Variables & Mounts — how config reaches the container.
- Volumes & PersistentVolumes — storage that survives restarts.
- StatefulSet (intro) — stable identity + storage for stateful apps.
Part 3 — Running & Operating
- Health Checks — liveness / readiness / startup probes.
- Resource Requests & Limits — CPU/memory scheduling and caps.
- Scaling — manual and autoscaling.
- Rolling Update & Rollback — zero-downtime releases, instant undo.
- Graceful Shutdown & Disruptions — SIGTERM, preStop, drains, and PDBs.
- Debugging — the commands that explain a broken Pod.
- Security Basics — ServiceAccounts, RBAC, Secrets, and NetworkPolicy.
Part 4 — Networking & Access
- Service Discovery & DNS — find Pods by name.
- Ingress — route external traffic by host/path.
Part 5 — Packaging & Beyond
- Helm (intro) — the Kubernetes package manager.
- Kustomize (intro) — overlay-based config.
Capstone
- Deploy Todo Board — Vue + FastAPI + SQLite, end to end.
- Cleanup — tear it all back down.
Appendix
- Cluster Lifecycle (kubeadm) — upgrades, etcd backup, certs, and reset.
- kubectl Cheat Sheet — one-page reference.
- Troubleshooting — symptom → cause → fix.
- Further Reading — advanced topics beyond this guide.