Kubernetes Administration — Level by Level›01 · Set up your practice lab

Lesson 01 of 32 · Level 1 — Foundations

Set up your practice lab

Build a free, disposable Kubernetes cluster on your own laptop in about five minutes, so every lesson after this is hands-on.

Beginner
Key wordskindkubectlkubeconfigcontextcluster

Why start with a lab

You can read about Kubernetes for weeks and still freeze the first time a pod won't start. The fix is to touch it. Every lesson in this course has commands you run yourself, and at least one thing you break on purpose.

Learning Kubernetes from slides is like learning to ride a bike from a book. We're going to build a bike in your garage, one that's free, fits on your laptop, and that you're allowed to crash.

We will use kind (Kubernetes IN Docker). It runs each Kubernetes "server" as a Docker container on your laptop. It's the same tool the Kubernetes project uses to test itself, so what you learn here is real Kubernetes, not a toy.

Option Good for Why not here
kind Multi-node clusters on one laptop, fast rebuilds ✅ Our choice
minikube Single-node learning, lots of add-ons Multi-node is less natural
k3d / k3s Lightweight clusters, edge Slightly different from upstream
Managed (EKS, GKE, AKS) Real production Costs money, slower to rebuild

What you need

  • Docker (Docker Desktop on Mac/Windows, Docker Engine on Linux) and about 4 GB of free RAM.
  • A terminal. On Windows, use WSL2.

Check Docker works first:

$ docker run --rm hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

Install kubectl and kind

macOS (Homebrew):

$ brew install kubectl kind

Linux (x86-64):

$ curl -LO "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
$ sudo install -m 0755 kubectl /usr/local/bin/kubectl
$ curl -Lo kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
$ sudo install -m 0755 kind /usr/local/bin/kind

Check the versions

Run kubectl version --client and kind version. v0.24.0 above is an example: check the kind releases page on GitHub for the newest version and swap it into the URL.

Create a 3-node cluster

A single-node cluster hides important behaviour (scheduling, node failures). We'll use one control-plane node and two workers. Save this as kind-lab.yaml:

# kind-lab.yaml: a small but realistic practice cluster
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
$ kind create cluster --name lab --config kind-lab.yaml
Creating cluster "lab" ...
 ✓ Ensuring node image (kindest/node:v1.31.0) 🖼
 ✓ Preparing nodes 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-lab"

Your version numbers may be newer. That's fine.

Say hello to your cluster

$ kubectl get nodes
NAME                STATUS   ROLES           AGE   VERSION
lab-control-plane   Ready    control-plane   60s   v1.31.0
lab-worker          Ready    <none>          40s   v1.31.0
lab-worker2         Ready    <none>          40s   v1.31.0

Three nodes, all Ready. Now look at what those "nodes" really are:

$ docker ps --format '{{.Names}}\t{{.Image}}'
lab-control-plane   kindest/node:v1.31.0
lab-worker          kindest/node:v1.31.0
lab-worker2         kindest/node:v1.31.0

Each "computer" in your cluster is really a box inside Docker, like three toy houses on one table. Kubernetes doesn't know or care that they're toys. It treats them exactly like real servers.

How kubectl found the cluster

kind wrote connection details into your kubeconfig file (~/.kube/config). A kubeconfig holds three things:

  • clusters: where the API server is (address + CA certificate)
  • users: how to log in (here, a client certificate)
  • contexts: a named pairing of cluster + user (+ default namespace)
$ kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO   NAMESPACE
*         kind-lab   kind-lab   kind-lab

Always know which cluster you're pointing at

At work you'll have contexts for dev, staging and production in the same file. Many outages start with "I thought I was in dev". Put the current context in your shell prompt, or run kubectl config current-context before anything destructive.

Quality-of-life setup (2 minutes, saves hours)

$ echo 'alias k=kubectl' >> ~/.bashrc
$ echo 'source <(kubectl completion bash)' >> ~/.bashrc
$ echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
$ source ~/.bashrc

Now k get no<TAB> completes to k get nodes. On zsh, use kubectl completion zsh instead.

The single most useful command you'll learn is kubectl explain: built-in documentation for every field, matched to your cluster's version.

$ kubectl explain pod.spec.containers.image
KIND:       Pod
VERSION:    v1

FIELD: image <string>

DESCRIPTION:
    Container image name. More info:
    https://kubernetes.io/docs/concepts/containers/images

Try it: break it and rebuild it

  1. Delete the cluster: kind delete cluster --name lab
  2. Run kubectl get nodes. Read the error carefully. What is kubectl complaining about?
  3. Recreate it with the same kind create cluster command.

You've just learned that clusters are cattle, not pets: rebuildable from a file. That idea runs through everything in platform engineering.

Going deeper: what's inside a kind node

Run docker exec -it lab-control-plane bash. You're now "on" the control-plane node. Try crictl ps (containers the kubelet is running), ls /etc/kubernetes/manifests (the control plane runs as static pods), and systemctl status kubelet. It's a real kubeadm-built node, which makes kind excellent for practising kubeadm upgrades, certificate rotation and static-pod debugging before you touch real servers.

Recap

  • kind gives you a real, multi-node Kubernetes cluster inside Docker, for free.
  • kubectl talks to the cluster's API server using the kubeconfig.
  • A context = cluster + user. Always know which one you're in.
  • Rebuilding is cheap, so experiment boldly.

This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.