Control plane and node components

What each part of a Kubernetes cluster does, in plain words, how it is started, and where to read its settings.

35 min 2 hands-on tasksArchitecture · 25% of the exam

Key ideas in this lesson · tap one for a simple explanation

What you will be able to do

  • Say in one sentence what each part of a cluster does, and tell kubeadm, kubectl and kubelet apart.
  • Read a part's live settings from its static Pod file, its mirror Pod or the kubelet's config file.
  • Create and remove a static Pod on any node.

A Kubernetes cluster is a group of machines that work together to run your apps. A few parts make the decisions; together they are called the . The other machines, the worker , do the actual work of running your apps. This lesson shows what each part does, how it is started, and where to read its settings. That last part matters most: the exam never asks you to draw the diagram below, it asks you to find things, such as which setting the runs with.

The parts of a cluster

Control plane

makes the decisions

API server

the front door

etcd

the database

Scheduler

picks a node

Controller manager

keeps things as asked

Worker node

runs your apps

kubelet

starts the Pods

Container runtime

runs the containers

kube-proxy

routes Service traffic

Your Pods

your apps

kubectl talks only to the API server. The kubelet on each worker node also talks to the API server, to learn which Pods it should run.

kubeadm, kubectl and kubelet: three names, three jobs

These three names look alike and confuse almost everyone at first, but they are completely different things:

NameWhat it isWhen you use itExample
A setup toolOnce per machine, to build or upgrade the clusterkubeadm init, kubeadm join
A command-line toolAll day, from your terminal, to work with the clusterkubectl get pods
An agent: a program running in the backgroundNever directly. It runs on every node all the time and starts the systemctl status kubelet

What each part does

Here is every part with its job in plain words. kind, the tool behind this course's lab, builds its clusters with kubeadm, so these are the same parts and the same file paths you will meet on exam day.

PartIts job, in plain wordsWhere it runs
kube-apiserverThe front door. Every request goes through it. It checks who is asking and whether they are allowed, then saves the change in .Control plane, as a
etcdThe database. It stores every object in the cluster: every Pod, and .Control plane, as a static Pod
Picks a node for each new Pod.Control plane, as a static Pod
Keeps things the way you asked. You ask for 3 copies of an app and one dies, so it starts a new one.Control plane, as a static Pod
kubeletStarts the Pods assigned to its node, restarts them if they crash, and reports their status.Every node, as a normal Linux service
Container runtime ()Actually runs the . The kubelet tells it what to start.Every node, as a normal Linux service
Makes addresses work by passing their traffic to the right Pods.Every node, as a Pod (one per node)

What breaks when each part stops is a topic of its own. You will meet it in Control plane failures and Worker node failures.

Three ways the parts are started

Each part is started in one of three ways. Knowing which group a part is in tells you which tool to use when it breaks.

  • As a normal Linux service: the kubelet and the . They start when the machine boots, and you check them with systemctl status kubelet.
  • As static Pods: the API server, etcd, the scheduler and the controller manager. The kubelet starts them from files on the control plane node, as the next section shows.
  • As ordinary Pods: kube-proxy and the network plugin ( in this lab), in the kube-system . You check them with kubectl -n kube-system get pods.

Static Pods

Normally you create a Pod through the API server: kubectl sends it, the API server saves it, the scheduler picks a node, and that node's kubelet starts it. But the API server is itself a Pod. Who starts it, when there is no API server yet? The kubelet does, from a file.

A static Pod is a Pod defined by a file in a folder on the node: /etc/kubernetes/manifests on kubeadm clusters. The kubelet runs every file in that folder and restarts the Pod if it stops. No API server and no scheduler are involved.

How a static Pod starts

A YAML file

/​etc/​kubernetes/​manifests

kubelet

runs every file in that folder

Pod running

on this node

Mirror Pod

a read-only copy you see in kubectl

So that you can still see these Pods with kubectl, the kubelet also puts a read-only copy in the API, called a mirror Pod. Its name is the Pod's name plus the node's name, for example kube-apiserver-cka-control-plane. Deleting the mirror Pod changes nothing. To change or stop a static Pod, edit or delete its file.

Find the static Pod path and recognize a mirror Pod
# exam: ssh <node>    lab: docker exec -it cka-control-plane bash
grep staticPodPath /var/lib/kubelet/config.yaml
ls /etc/kubernetes/manifests
# etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml

# From your workstation: a mirror Pod is owned by a Node and sourced from a file
kubectl -n kube-system get pod kube-apiserver-cka-control-plane \
  -o jsonpath='{.metadata.ownerReferences[0].kind}{" "}{.metadata.annotations.kubernetes\.io/config\.source}{"\n"}'
# Node file

Reading a part's settings

Exam questions often ask for a setting, such as the range of IP addresses that Services get. There are three places to read it; use whichever is quickest.

Three places to read a setting
# 1. What the kubelet was told to run: the static Pod's file on the node
docker exec cka-control-plane grep -- --service-cluster-ip-range /etc/kubernetes/manifests/kube-apiserver.yaml

# 2. The same through the API, no node shell needed
kubectl -n kube-system get pod -l component=kube-apiserver \
  -o jsonpath='{.items[0].spec.containers[0].command}' | tr ',' '\n' | grep service-cluster

# 3. The kubelet keeps its own settings in a config file on each node
docker exec cka-control-plane grep -E 'staticPodPath|containerRuntimeEndpoint|cgroupDriver' /var/lib/kubelet/config.yaml

Always read the value from the cluster in front of you, never from memory. For example, kubeadm's default Service range is 10.96.0.0/12, but this lab uses 10.96.0.0/16.

In the official docs· open on exam day too

Hands-on task 1 of 2ar-cp-1
~5 min3% weightArchitecture

Read control plane settings from the node

Answer three questions about this cluster by reading it. Write each answer as a single bare value. (1) The IP range the API server assigns Service ClusterIPs from, to /tmp/cka/ar-svc-cidr.txt. (2) The directory the kubelet on cka-control-plane loads static Pod manifests from, to /tmp/cka/ar-static-path.txt. (3) The CRI endpoint that same kubelet uses to reach its container runtime, to /tmp/cka/ar-cri-endpoint.txt.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-1/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-1/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-1/cleanup | bash
Hands-on task 2 of 2ar-cp-2
~6 min4% weightArchitecture

Run a static Pod on a worker

Run a static Pod named ar-static-web in namespace ar-cp on node cka-worker. It uses image nginx:1.27, has the label app=ar-static-web and declares container port 80. It must be started by the kubelet on cka-worker from a manifest file, so that deleting it through the API does not get rid of it.

Cluster:kubectl config use-context kind-cka

  1. 1

    Set up the scenario

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-2/setup | bash
  2. 2

    Solve it in your terminal

    Use kubectl and the Kubernetes docs, like on exam day. Save any answer files under /tmp/cka/.

  3. 3

    Check your work

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-2/verify | bash
    Got FAIL? Read which check failed, fix it, run it again.
  4. 4

    Clean up (optional)

    curl -fsSL https://codewithmuh.com/labs/cka/t/ar-cp-2/cleanup | bash

Finished this lesson?

0 of 2 tasks passed. Your readiness counts tasks, so run them before you move on.