The Kubernetes control plane doesn’t actually run your applications; it just makes sure they run correctly.

Let’s watch this happen. Imagine we have a simple nginx deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.3
        ports:
        - containerPort: 80

When you kubectl apply -f deployment.yaml, a few things kick off. The apiserver (the front door) receives this. The scheduler then looks at the desired state (3 replicas) and finds suitable kubelets on worker nodes that can host these pods. The controller-manager (specifically the deployment controller) notices the discrepancy between desired and actual state and creates ReplicaSet objects. The replicaset controller then creates Pod objects. Finally, the kubelet on each chosen worker node, reporting back to the apiserver, is instructed to pull the nginx:1.25.3 image and start the containers. If a pod dies on a worker node, the kubelet reports this to the apiserver, and the controller-manager (again, the deployment controller) sees the missing replica and starts the process to schedule a new one.

The core problem Kubernetes solves is managing distributed state reliably. It abstracts away the underlying infrastructure – the VMs, bare metal, network – and presents a unified API for deploying, scaling, and managing containerized applications. The control plane components are the brains, constantly observing the cluster’s current state and reconciling it with the desired state defined by users.

Here’s a breakdown of the key control plane components:

  • kube-apiserver: This is the gateway to the Kubernetes cluster. All communication, whether from kubectl, other control plane components, or worker nodes, goes through the API server. It validates and processes REST operations, serving as the cluster’s central hub.
  • etcd: This is Kubernetes’ distributed key-value store. It’s the single source of truth for the cluster’s state, storing configuration data, desired states, and actual states of all objects. If etcd is unavailable, the cluster essentially loses its memory.
  • kube-scheduler: This component watches for newly created pods that have no node assigned. For every pod, it finds the best worker node for that pod to run on. It considers factors like resource requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, and data locality.
  • kube-controller-manager: This component runs controller processes. Logically, each controller is a separate process, but to reduce complexity, they are all compiled into a single binary and run in a single process. These controllers include:
    • Node Controller: Responsible for noticing and responding when nodes go down.
    • Replication Controller: Responsible for maintaining the correct number of pods for every application.
    • Endpoints Controller: Populates the Endpoints object (that is, joins Services & Pods).
    • Service Account & Token Controllers: Create default accounts and API access tokens for new namespaces.
  • cloud-controller-manager: This component embeds cloud-specific control logic. It allows you to link your cluster into your cloud provider’s API, and separates components that interact with the cloud platform from components that are just used in-cluster.

And on the other side, you have the Worker Nodes:

  • kubelet: This is an agent that runs on each worker node in the cluster. It makes sure that containers are running in a Pod. It takes PodSpecs, which are provided through various mechanisms, and ensures that those containers in those Pods are running and healthy. It does not manage containers not created by Kubernetes.
  • kube-proxy: This is a network proxy that runs on each worker node in your cluster. It maintains network rules on nodes. These network rules allow network communication to your Pods from inside or outside of your cluster. kube-proxy implements the Kubernetes Service concept.
  • Container Runtime: This is the software that is responsible for running containers. Kubernetes supports several container runtimes, such as Docker, containerd, and CRI-O.

The magic happens because these components are constantly talking to each other via the apiserver. The control plane declares the desired state, and the worker nodes, through kubelet and kube-proxy, work to achieve and maintain that state.

Most people think of Kubernetes as just an orchestrator for containers. While that’s true, the truly powerful aspect is its declarative nature and self-healing capabilities, driven by the continuous reconciliation loop of the control plane components. You tell Kubernetes what you want, and it figures out how to make it happen and keep it happening.

When you see a CrashLoopBackOff error, it’s often because the kubelet on a worker node is trying to start a container, but the container is exiting immediately. The kubelet reports this back to the apiserver, and the controller-manager sees that the pod isn’t running as expected and attempts to restart it, leading to the loop. The apiserver is the messenger, etcd holds the state, the scheduler picks a home, and the kubelet executes the command.

The next thing you’ll likely encounter is understanding how Kubernetes networking actually routes traffic between pods, especially when Services are involved.

Want structured learning?

Take the full Containers & Kubernetes course →