Kubernetes basics

Kubernetes architecture

How Kubernetes works: orchestration, the declarative model and the cluster components.

6 min read

Kubernetes architecture

In this section you will learn how Kubernetes works under the hood: why orchestration is needed, what the declarative model means and which parts a cluster consists of. At the end there is a short hands-on exercise where you explore the components of your own cluster.


1. Why is orchestration needed?

When an application is packaged into a container (e.g. Docker), running a single container is easy. Problems begin when there are dozens or hundreds of containers that need to work reliably:

  • Scaling – How do I add or remove replicas based on load?
  • Fault tolerance – What happens when a container or an entire server crashes?
  • Networking – How do containers find each other and how is traffic distributed?
  • Releases – How do I roll out a new version without downtime?

Orchestration means automating these things. Kubernetes is the de facto standard for container orchestration: it decides where containers run, restarts crashed ones, and makes sure the desired state is achieved.

💡 Core idea: You tell Kubernetes what you want, not how it is done.


2. The declarative model and the reconciliation loop

Kubernetes works declaratively. You describe the desired end state (desired state) – for example “run 3 replicas of this application” – and Kubernetes continuously strives to reach and maintain it.

This is implemented by the reconciliation loop:

flowchart LR
	A[Desired state<br/>desired state] --> B{Compare}
	C[Current state<br/>current state] --> B
	B -->|differs| D[Take corrective actions]
	D --> C
	B -->|same| E[No actions]

Example: if you define 3 replicas but one crashes, the current state (2) differs from the desired state (3). Kubernetes notices the difference and starts a new replica automatically.

Imperative vs. declarative

Imperative (how)Declarative (what)
“Start container A, then B”“These applications must be running”
You control every stepKubernetes decides the steps
State is lost on failureState is restored automatically

3. Cluster components

A Kubernetes cluster consists of a control plane and worker nodes.

flowchart TB
	subgraph CP[Control Plane]
		API[kube-apiserver]
		ETCD[(etcd)]
		SCH[kube-scheduler]
		CM[controller-manager]
		API --- ETCD
		API --- SCH
		API --- CM
	end
	subgraph N1[Worker Node]
		K1[kubelet]
		P1[kube-proxy]
		R1[Container runtime]
		POD1[Pod]
		K1 --- R1
		R1 --- POD1
	end
	API --- K1
	kubectl[kubectl / user] --> API

Control plane

The control plane is the cluster’s “brain” – it makes the decisions and stores the state.

  • kube-apiserver – The cluster’s central API. All communication (including kubectl) goes through it. It is the only component that writes to etcd.
  • etcd – A distributed key–value database that stores the entire cluster state. This is the cluster’s “source of truth”.
  • kube-scheduler – Decides which worker node a new Pod is placed on (based on resources, constraints and rules).
  • controller-manager – Runs reconciliation loops (e.g. makes sure the number of replicas stays correct).

Worker nodes

Worker nodes run the actual application containers.

  • kubelet – The node agent that makes sure the Pods assigned to it are running and healthy. Reports the state to the kube-apiserver.
  • kube-proxy – Handles the node’s networking rules and routing of traffic to services.
  • Container runtime (e.g. containerd) – Starts and runs the containers.

Pod – the smallest unit

A Pod is the smallest deployable unit in Kubernetes. It contains one or more closely related containers that share the same network and storage. In practice, one Pod = often one application container.


4. Application lifecycle

This is how an application you define ends up running:

  1. Submission – You submit the desired state (e.g. YAML) to the kube-apiserver with the kubectl tool.
  2. Storage – The kube-apiserver stores the definition in etcd.
  3. Scheduling – The scheduler selects a suitable worker node for the Pod.
  4. Startup – The kubelet on the selected node starts the container using the container runtime.
  5. Monitoring – The controllers and kubelet continuously watch that the state matches the desired one. Deviations are corrected automatically.
sequenceDiagram
	participant U as kubectl
	participant A as kube-apiserver
	participant E as etcd
	participant S as scheduler
	participant K as kubelet
	U->>A: Desired state (YAML)
	A->>E: Store state
	S->>A: Select node for Pod
	A->>K: Start Pod on node
	K->>A: Report state (Running)

5. Hands-on exercise (5 min)

In this exercise you will use a shared Kubernetes cluster maintained by the instructor. First download the cluster’s kubeconfig below (you will need the password from your instructor) and activate it so that the following kubectl commands work.

Cluster access (kubeconfig)

Enter the password provided by your instructor to reveal the kubeconfig.

Activate the downloaded file either by setting the KUBECONFIG environment variable or by copying the file to the default location:

bash
# Option A: point kubectl at the downloaded file in the current session
export KUBECONFIG=$HOME/Downloads/config

# Option B: copy it to the default location
mkdir -p $HOME/.kube && cp $HOME/Downloads/config $HOME/.kube/config

Finally, create your own namespace to work in, so that your exercises do not mix with other participants’ resources on the shared cluster:

bash
# Replace <your-name> with your own name
kubectl create namespace <your-name> --dry-run=client -o yaml | kubectl apply -f -
kubectl config set-context --current --namespace=<your-name>

After this, kubectl commands automatically target your own namespace (system components are still inspected separately with the -n kube-system flag).

1. View the cluster nodes and their status:

bash
kubectl get nodes -o wide

You will see the cluster’s worker nodes, their status (Ready) and the Kubernetes version.

2. Inspect the control plane and system components:

bash
kubectl get pods -n kube-system

The kube-system namespace runs system components such as kube-proxy and the networking parts. You will see that Kubernetes also manages its own parts as Pods.

3. See which components the cluster reports as healthy:

bash
kubectl get componentstatuses

4. Try the declarative model in practice. Create a Deployment, delete its Pod and watch what happens:

bash
# Create a Deployment that maintains 1 replica of nginx
kubectl create deployment web --image=nginx

# View the created Pods
kubectl get pods

# Delete the Pod manually (replace <name> with the name you got from the list)
kubectl delete pod <name>

# Look again – Kubernetes has already started a replacement Pod
kubectl get pods

🔎 Note: Even though you deleted the Pod, the reconciliation loop noticed the difference from the desired state (1 replica) and created a new Pod automatically. This is the declarative model in action.

Finally, clean up the exercise by deleting your namespace, which also removes all the resources it contains:

bash
kubectl delete namespace <your-name>

Summary

  • Kubernetes orchestrates containers: scaling, fault tolerance, networking and releases are handled automatically.
  • The model is declarative: you describe the desired state, and the reconciliation loop maintains it.
  • The control plane (kube-apiserver, etcd, scheduler, controller-manager) makes the decisions; the worker nodes (kubelet, kube-proxy, container runtime) run the applications.
  • A Pod is the smallest deployable unit.
  • When you delete a Pod, Kubernetes recreates it – exactly as the declarative model is supposed to work.