KUBERNETES TUTORIAL

Cluster anatomy: control plane, nodes & kubectl essentials

Cluster anatomy: control plane, nodes & kubectl essentials

What we're doing

When you hit Start, you're on a real 3-node Kubernetes cluster (anatomy-control-plane + two workers) running the shop app. You'll meet the control-plane components (API server, etcd, scheduler, controller-manager), the node components (kubelet, kube-proxy), inspect a node with describe, practice the core kubectl verbs and output formats, and delete a control-plane pod to watch it come back.

Watch the video first, then run these as you read. kubectl is already set up here; nothing needs sudo. We're still only reading the cluster, no deploying your own app yet.

The mental model: a brain plus workers

A cluster is two kinds of machine. The control plane is the brain: it decides, schedules, and remembers. The worker nodes are the muscle: they run your Pods. You only ever talk to the control plane (through kubectl), never to the workers directly. Hold that picture; everything below is a piece of it.

Step 1: See the machines

kubectl get nodes -o wide
NAME                    STATUS   ROLES           VERSION   ...   CONTAINER-RUNTIME
anatomy-control-plane   Ready    control-plane   v1.31.0   ...   containerd://1.7.18
anatomy-worker          Ready    <none>          v1.31.0   ...   containerd://1.7.18
anatomy-worker2         Ready    <none>          v1.31.0   ...   containerd://1.7.18

Three nodes. The ROLES column shows one control-plane (the brain) and two workers (<none>). -o wide adds detail like each node's container runtime. You talk to the control plane; the workers run the work.

Step 2: Meet the control plane (the four components)

The control plane is four small programs, each with one job:

Component Its one job
kube-apiserver the front door, every command and component talks through it
etcd the cluster's memory, the single source of truth
kube-scheduler picks which node a new Pod runs on
kube-controller-manager runs the loops that keep reality matching what you asked for

See them as real pods:

kubectl get pods -n kube-system
NAME                                            READY   STATUS    AGE
coredns-... (x2)                                1/1     Running   ...
etcd-anatomy-control-plane                      1/1     Running   ...
kube-apiserver-anatomy-control-plane            1/1     Running   ...
kube-controller-manager-anatomy-control-plane   1/1     Running   ...
kube-scheduler-anatomy-control-plane            1/1     Running   ...
kindnet-... (x3)                                1/1     Running   ...
kube-proxy-... (x3)                             1/1     Running   ...

kube-system is the namespace where Kubernetes runs its own machinery. The four components are right there, each ending in -anatomy-control-plane because they run on the control-plane node. coredns is the cluster's internal DNS.

Worth knowing: a lightweight distro like k3s bundles these four into a single process, so you can't see them separately. This cluster uses kind (real upstream Kubernetes) precisely so they show up as real, inspectable pods.

Step 3: Meet the node components

The kube-proxy and kindnet entries above are the per-node parts, three of each, one per node:

  • kubelet, the node's agent: takes orders from the API server, runs the assigned Pods, reports health. (It runs as part of the node itself, not as a pod, so it's not in the list.)
  • kube-proxy: wires up Service networking on each node.
  • container runtime (containerd): actually pulls images and runs containers.

The rule is always: the control plane decides, the kubelet on each node does.

Step 4: Inspect a node end to end

describe node is the single best way to understand a machine:

kubectl describe node anatomy-worker

Read it section by section:

  • Roles / Labels, what kind of node this is.
  • Taints, rules about what may run here. The control-plane node has a taint that keeps app Pods off it; workers have none.
  • Conditions, the health report. MemoryPressure / DiskPressure / PIDPressure should be False, and Ready should be True (that's the kubelet saying "I'm healthy").
  • Capacity / Allocatable, how much CPU, memory, and how many pods this node can hold.
  • System Info, kernel, OS image, container runtime version, kubelet version, the real software on the box.
  • Non-terminated Pods, everything running here and what each reserves.

One command, and you know the node's role, health, size, software, and workload.

Step 5: The kubectl essentials

You already know get. Two more verbs complete the core set:

kubectl get pods -n shop                       # list
kubectl describe pod -n shop <a-web-pod>        # zoom into one + its Events

describe shows an Events list at the bottom, always your first stop when something is wrong.

Output formats change how much get shows:

kubectl get pods -n shop -o wide                # extra columns (incl. NODE)
kubectl get pod -n shop <name> -o yaml          # the entire object, every field
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.kubeletVersion}'   # pluck one field
  • -o wide, more columns, like which node a Pod is on.
  • -o yaml, the full object exactly as the API server stores it (great for learning what fields exist).
  • -o jsonpath, pulls out a single value, here every node's kubelet version on one line.

And apply, the declarative verb you'll use most:

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml    # or a local file.yaml
kubectl get pod nginx                                            # it's there
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml    # run again: "unchanged"

apply reads a manifest and makes the cluster match it. Run it twice and the second time reports unchanged, it only applies differences. That declarative loop is how you'll work with Kubernetes from here on. (Just a taste today; real deploying is the next tutorial.)

Step 6: Watch the control plane heal itself

The control-plane components are static pods, their manifests live on the node and the kubelet keeps them alive no matter what. Prove it.

In one terminal, watch:

kubectl get pods -n kube-system -w

In a second terminal, delete the scheduler (use the real name from Step 2):

kubectl delete pod -n kube-system kube-scheduler-anatomy-control-plane

Back in the watch: the scheduler disappears, then within seconds a fresh kube-scheduler-... pod appears and goes Running. You did nothing. The control-plane node's kubelet saw the static-pod manifest, noticed the scheduler was gone, and rebuilt it. Even the brain self-heals. Stop the watch with Ctrl+C.

The pieces you just met

Where Component Job
Control plane kube-apiserver front door for all requests
Control plane etcd the cluster's memory / source of truth
Control plane kube-scheduler places new Pods on nodes
Control plane kube-controller-manager reconcile loops (keep reality == desired)
Every node kubelet runs assigned Pods, reports health
Every node kube-proxy Service networking on the node
Every node containerd pulls images, runs containers

Cheat sheet

kubectl get nodes -o wide                       # the machines + roles
kubectl get pods -n kube-system                 # control-plane + node components
kubectl describe node <name>                    # one node, end to end
kubectl describe pod -n kube-system <component>  # zoom into a component + its events
kubectl get pod <name> -o yaml                  # the full object
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.kubeletVersion}'  # one field
kubectl apply -f file.yaml                      # create/update declaratively
kubectl config get-contexts                     # which cluster am I on (* = current)

The one thing to remember: the control plane decides and remembers (API server, etcd, scheduler, controller-manager); every node runs the work (kubelet, kube-proxy, runtime). One request flows through all of them, and that same loop is what heals your cluster.

Next tutorial, we deploy our own app onto this cluster.


What's next

Just hit Start and go try this out in a live environment !

Start KUBERNETES
Spec 4 CPU / 12 GiB ·Disk 20 GiB ·Lifetime 7 days
Up next in Apache Airflow Mastery Chapter 3 of 5

DAG Patterns & Best Practices

Continue

Suggested tutorials

Keep the momentum going — pick a related topic.