Title: Lecture 6 — Anatomy of a Kubernetes Cluster
Course: AIINFRA 101: Applied Infrastructure & Containerization > Section: Week 06 — Introduction to Kubernetes: Architecture & kubectl

📖 Lecture — Anatomy of a Kubernetes Cluster

Earlier in this course you learned to package applications into container images. This week we zoom out: how does a fleet of containers get scheduled, monitored, and kept running across many machines? The answer is Kubernetes, and before you type a single kubectl command, you need a mental model of what a "cluster" actually is. The control plane and the worker nodes A Kubernetes cluster is really two groups of machines (or, in our lab this week, two groups of containers pretending to be machines) working together:

Plane | Component | Job
Control plane | kube-apiserver | The single front door for all cluster communication — every read and write passes through it
Control plane | etcd | Distributed key-value store that holds all cluster state
Control plane | kube-scheduler | Watches for newly created pods with no assigned node and picks a node for them
Control plane | kube-controller-manager | Runs controller loops that reconcile the cluster's actual state toward the desired state
Worker node | kubelet | Agent that makes sure containers described in pod specs are actually running on that node
Worker node | kube-proxy | Maintains network rules so traffic can reach the right pods
Worker node | Container runtime | The engine (such as containerd) that actually pulls images and runs containers

The control plane makes the decisions; the worker nodes do the work of actually running your application containers. Everything you deploy — your model-serving container, your data-preprocessing job, your training pod — ends up running on a worker node, scheduled there by the control plane. Correcting a common misconception: kubectl is not the cluster It is easy to think of kubectl as "the thing that runs Kubernetes," the way docker felt like "the thing that runs containers." That is not accurate. kubectl is a client. It reads a kubeconfig file (which tells it which cluster to talk to and how to authenticate), then sends HTTPS requests to the kube-apiserver. The cluster itself — the actual compute, state, and scheduling logic — is the combination of the control-plane components and the worker nodes, running independently of whether you have kubectl open or not. You could delete kubectl from your laptop entirely and your cluster would keep running exactly as before; you just would have no way to talk to it. Correcting a second misconception: etcd holds the real state, not the API server A related mistake is assuming the kube-apiserver "remembers" your cluster's state in memory. It does not. The API server is deliberately close to stateless — it validates requests, applies authorization and admission rules, and then reads from or writes to etcd, the distributed key-value store that is the actual source of truth. Every pod definition, every Service, every Secret, every ConfigMap you create is persisted in etcd. If etcd is lost with no backup, the cluster's entire memory of what it is supposed to be running is gone, even if the API server process is perfectly healthy. This is why etcd backups are treated as one of the most critical operational tasks for any production cluster. The three kubectl verbs you will use constantly

Command | What it does
kubectl get <resource> | Retrieves one or more resources of a given type (e.g., kubectl get pods, kubectl get nodes) — a quick snapshot
kubectl apply -f <file>.yaml | Creates a resource if it does not exist, or declaratively updates it to match the YAML if it does
kubectl describe <resource> <name> | Builds a detailed view of one resource, including status, configuration, and recent events — your first stop when debugging

A good habit: get to see what exists, describe to see why something is broken, apply to declare what you want to exist. Version awareness As of this writing, Kubernetes v1.36.2 is the latest release, with v1.35 and v1.34 also actively supported. kubectl follows a version-skew policy of plus-or-minus one minor version relative to the kube-apiserver it talks to — so a v1.35 kubectl client can safely talk to a v1.34, v1.35, or v1.36 API server, but not much further out than that. Always check kubectl version when something behaves unexpectedly across environments. Namespaces organize, but do not isolate Kubernetes ships with a few default namespaces, most importantly kube-system (where control-plane pods like the API server, scheduler, and etcd itself often run as pods) and default (where your own workloads land if you do not specify otherwise). Namespaces are a logical grouping and naming boundary — useful for organizing teams, environments, or projects — but they are not a security or resource boundary. Workloads in different namespaces still share the same underlying control plane, the same network fabric, and the same pool of physical or virtual nodes. A namespace does not stop a noisy or misbehaving pod in one namespace from starving nodes shared by pods in another namespace, which is exactly what we will discuss this week. Local clusters for learning: kind, minikube, k3d You do not need an AWS or GCP account to learn Kubernetes. Tools like kind (Kubernetes IN Docker, currently at v0.32.0) use Docker containers themselves as stand-ins for full-blown cluster nodes, letting you spin up a multi-node cluster in under a minute at zero cost. minikube and k3d are close alternatives with slightly different tradeoffs (minikube emphasizes a single-VM, feature-rich experience; k3d wraps the lightweight k3s distribution). This week's lab uses kind because it maps most directly onto the "real" multi-node architecture you just learned about.