# Why kubeadm (and not k3s or a managed service)

There are easier ways to get a Kubernetes cluster. `k3s` is a single binary. A cloud provider will hand you one in ten minutes. I deliberately used `kubeadm` anyway.

The reason is the goal. This lab exists to *understand* the platform, and to show that understanding. `kubeadm` builds a stock, upstream cluster — the same control-plane components (etcd, API server, scheduler, controller-manager) and the same `kubelet` you'd meet in any "real" cluster, with none of the abstractions a distro folds away. When something breaks, you debug the actual thing rather than a wrapper around it.

- **Managed (EKS/GKE/AKS):** great for production, useless for learning the internals — the control plane is invisible.
- **k3s / k0s:** lovely for edge and small prod; but they bundle and hide pieces (their own CNI, a SQLite datastore, etc.), which is exactly what I wanted to *see*.
- **kubeadm:** more steps, more to get wrong, and that's the point — every step here maps to a concept worth knowing.

> **Why we use this:** for a portfolio/teaching lab, the harder path is the feature, not the bug. If you can stand a cluster up with `kubeadm`, fix the join that fails because of a firewall, and pick a CNI on purpose, you understand Kubernetes in a way that "click to create" never teaches.

The cluster is four nodes: one control-plane node and three workers, all Ubuntu, running Kubernetes 1.36 with `containerd` as the runtime and Calico for networking.

## Diagram

![Four nodes: a tainted control plane, three workers, one CNI](https://docs.devopsawi.com/uploads/images/gallery/2026-05/d-56.png)