Lesson 5 of 16
Bootstrap the lab cluster
We need a multi-node cluster so later lessons can simulate node-level failures (drain a worker, corrupt a kubelet, watch the operator react). One node is not enough.
Working directory check
Every command in this lesson runs from ~/incident-cluster/ — the workspace you set up in the previous lesson. If your terminal is somewhere else:
cd ~/incident-cluster
The cluster config
Create kind-incident.yaml in ~/incident-cluster/:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: incident-lab
nodes:
- role: control-plane
- role: worker
- role: worker
Three things this declares:
kind: Clusterhere is the kind CLI's schema, not Kubernetes's —kindborrows the API-style format on purpose, but theClusterresource is parsed by thekindbinary itself.name: incident-labbecomes the kubectl context name (kind-incident-lab) and the prefix for every node container.- Three nodes — one control plane and two workers — each backed by a Docker container running
kubeadminside.
Create it
kind create cluster --config kind-incident.yaml
kubectl cluster-info --context kind-incident-lab
First run pulls the kindest/node image (~1GB) and takes a couple of minutes. Subsequent runs are seconds.
What's actually running
Open a second terminal:
docker ps --format '{{.Names}}\t{{.Image}}'
You'll see three containers: incident-lab-control-plane, incident-lab-worker, incident-lab-worker2, all running kindest/node:v1.35.0. Inside each, kubeadm has bootstrapped a real Kubernetes node — etcd on the control plane, kubelet everywhere, CNI plugged in.
The mental model:
┌───────── your laptop ─────────┐
│ ┌─────────────────────────┐ │
│ │ Docker daemon │ │
│ │ ┌──────────────────┐ │ │
│ │ │ control-plane │◄──┼───┼── kubectl talks here
│ │ └──────────────────┘ │ │ (port-forwarded to localhost)
│ │ ┌──────────────────┐ │ │
│ │ │ worker │ │ │
│ │ └──────────────────┘ │ │
│ │ ┌──────────────────┐ │ │
│ │ │ worker2 │ │ │
│ │ └──────────────────┘ │ │
│ └─────────────────────────┘ │
└───────────────────────────────┘
kubectl is talking to the API server inside the control-plane container; pods in the cluster will land on either of the two worker containers. They share a Docker network so cluster networking just works.
Acceptance test
kubectl get nodes
You should see three Ready nodes — one control-plane (with control-plane in the ROLES column) and two workers. If a node is NotReady, give it ~30 seconds; the kubelet may still be coming up.
The cluster is disposable
We'll cover the full teardown (cluster + port-forward + Docker Desktop) at the end of this section — until then, leave the cluster running. But internalise the principle now: this thing is meant to be thrown away. When something gets weird in a later lesson, deleting and recreating is a legitimate first move, not a defeat. Recreating from the config you just wrote takes seconds because the node image is cached in Docker.