1. 1

    1: Why kubeadm and what are we building

    Most “install Kubernetes” tutorials fall into one of two camps. There’s the five-minute k3s/kind crowd, where you run a single command and end up with something that boots but doesn’t behave like the cluster you’ll…

  2. 2

    2: VM Prep

    If post 1 was the setup, this post is the part where we make sure the VMs are actually ready to host a Kubernetes cluster. Nothing in this post is glamorous. All of it is the reason your cluster either comes up…

  3. 3

    3: Containerd

    Kubelet doesn’t run containers directly. It talks over a socket to a container runtime, using the Container Runtime Interface (CRI). The runtime does the actual work — pulling images, creating namespaces and cgroups,…

  4. 4

    4: Install kubeadm

    Three binaries, one apt repo, two gotchas. This is the shortest post in the series and one of the most consequential to get right, because the choice you make about which Kubernetes minor version to install in this…

  5. 5

    5: Kubeadm init

    This is the post where we actually get a Kubernetes API server running. After this, you’ll have a single-node control plane on cp-1 that’s already wearing its kube-vip VIP — ready for Cilium in post 6, workers in…

  6. 6

    6: Cillium

    At the end of post 5 we had a control plane running but cp-1 stuck in NotReady. That’s because kubelet refuses to be Ready until a CNI plugin has installed itself into /etc/cni/net.d/ and can hand out pod IPs. This…

  7. 7

    7: workers

    One control plane node, one CNI, zero workers. Time to fix the third one. By the end of this post we’ll have worker-1 and worker-2 joined, Cilium running on them, and three nodes Ready. The mechanics are simple; the…

  8. 8

    8: ha kube vip

    One control plane node is enough for a working cluster. It is not enough for an HA cluster. If cp-1 goes down right now, every kubectl call hangs, no pods can be scheduled, and worker kubelets eventually start…

  9. 9

    9: storage ingress

    The cluster is healthy and HA, but it’s not yet useful. Stateful workloads need somewhere to put their data, and HTTP workloads need a way to be reachable. This post installs local-path-provisioner as a default…

  10. 10

    10: day 2 ops

    Building a cluster is the easy part. Operating one for two years without losing data is the actual job. This last post in the series covers the three things that distinguish a cluster you can rely on from a cluster…