Kubernetes Architecture
Understanding the architecture of Kubernetes is essential before you start deploying applications. In this chapter, we’ll explore how Kubernetes is structured, what each component does, and how they work together to manage your containerized workloads.
High-Level Overview
A Kubernetes cluster consists of two main parts:
- Control Plane (Master) — The brain of the cluster. Makes decisions about scheduling, detects events, and responds to changes.
- Worker Nodes — The machines that actually run your application containers.
┌─────────────────────────────────────────────────────┐
│ CONTROL PLANE │
│ ┌───────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ API Server│ │Scheduler │ │Controller Manager │ │
│ └─────┬─────┘ └─────┬────┘ └────────┬──────────┘ │
│ │ │ │ │
│ ┌─────▼─────────────▼───────────────▼──────────┐ │
│ │ etcd │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────┬───────────────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Worker │ │ Worker │ │ Worker │
│ Node 1 │ │ Node 2 │ │ Node 3 │
│┌───────┐│ │┌───────┐│ │┌───────┐│
││kubelet││ ││kubelet││ ││kubelet││
││kube- ││ ││kube- ││ ││kube- ││
││proxy ││ ││proxy ││ ││proxy ││
││runtime││ ││runtime││ ││runtime││
│└───────┘│ │└───────┘│ │└───────┘│
│ [Pod] │ │ [Pod] │ │ [Pod] │
│ [Pod] │ │ [Pod] │ │ [Pod] │
└─────────┘ └─────────┘ └─────────┘
Control Plane Components
The Control Plane is responsible for the global state of the cluster. In production, it runs across multiple machines for high availability.
kube-apiserver
The API Server is the front door to Kubernetes. Every interaction with the cluster — whether from kubectl, the dashboard, or internal components — goes through the API Server.
Key responsibilities:
- Exposes the Kubernetes REST API
- Validates and processes API requests
- Acts as the gateway to
etcd(the only component that talks to etcd directly) - Handles authentication and authorization
# Every kubectl command hits the API Server
kubectl get pods
# This translates to: GET /api/v1/namespaces/default/pods
etcd
etcd is a distributed key-value store that serves as Kubernetes’ database. It stores the entire cluster state — every Pod, Service, ConfigMap, Secret, and more.
Key characteristics:
- Consistent and highly available
- Only the API Server reads/writes to etcd
- Uses the Raft consensus algorithm
- Should always be backed up in production
Example of what etcd stores:
/registry/pods/default/my-nginx-pod
/registry/services/default/my-service
/registry/deployments/default/my-deployment
kube-scheduler
The Scheduler watches for newly created Pods that don’t have a node assigned and selects the best node for them to run on.
Scheduling decisions consider:
- Resource requirements (CPU, memory)
- Hardware/software constraints
- Affinity and anti-affinity rules
- Taints and tolerations
- Data locality
Think of the Scheduler as a matchmaker — it finds the right node for each Pod based on constraints and available resources.
kube-controller-manager
The Controller Manager runs a collection of controllers — each one is a control loop that watches the cluster state and makes changes to move the current state toward the desired state.
Key controllers include:
| Controller | What it does |
|---|---|
| Node Controller | Monitors node health, responds when nodes go down |
| ReplicaSet Controller | Ensures the correct number of Pod replicas are running |
| Deployment Controller | Manages rolling updates and rollbacks |
| Job Controller | Manages one-off batch jobs |
| Service Account Controller | Creates default service accounts for namespaces |
cloud-controller-manager
If you’re running Kubernetes on a cloud provider (AWS, Azure, GCP), the Cloud Controller Manager handles cloud-specific logic:
- Creating load balancers for Services of type
LoadBalancer - Managing cloud storage volumes
- Managing node lifecycle (detecting when cloud VMs are deleted)
Note: This component doesn’t exist in Minikube or bare-metal clusters.
Worker Node Components
Worker nodes are where your application Pods actually run. Each worker node has three essential components.
kubelet
The kubelet is an agent that runs on every worker node. It’s responsible for:
- Communicating with the API Server
- Ensuring containers described in PodSpecs are running and healthy
- Reporting node and pod status back to the control plane
- Executing liveness and readiness probes
The kubelet doesn’t manage containers that weren’t created by Kubernetes.
kube-proxy
kube-proxy maintains network rules on each node. These rules allow network communication to your Pods from inside or outside the cluster.
Key responsibilities:
- Implements the Kubernetes Service concept
- Manages iptables or IPVS rules for traffic routing
- Handles load balancing across Pod replicas
When you create a Service, kube-proxy ensures that traffic to the Service’s ClusterIP gets routed to one of the backing Pods.
Container Runtime
The container runtime is the software responsible for actually running containers. Kubernetes supports several runtimes through the Container Runtime Interface (CRI):
| Runtime | Notes |
|---|---|
| containerd | Default in most K8s distributions. Lightweight and production-ready. |
| CRI-O | Designed specifically for Kubernetes. Used by OpenShift. |
| Docker Engine | Was the original runtime. Kubernetes deprecated the Docker shim in v1.24 (Docker still works via containerd). |
How a Pod Gets Created — The Full Flow
Let’s trace what happens when you run kubectl create deployment nginx --image=nginx:
- kubectl sends a POST request to the API Server
- API Server validates the request, authenticates you, and writes the Deployment object to etcd
- Deployment Controller (in Controller Manager) detects the new Deployment, creates a ReplicaSet
- ReplicaSet Controller detects the ReplicaSet, creates the required Pod objects
- Scheduler sees unscheduled Pods, evaluates nodes, and assigns each Pod to a node
- kubelet on the assigned node picks up the Pod spec, instructs the container runtime to pull the image and start the container
- kube-proxy updates network rules if a Service is involved
kubectl → API Server → etcd
↓
Controller Manager
(Deployment → ReplicaSet → Pod)
↓
Scheduler
(assigns Pod to Node)
↓
kubelet
(starts container)
↓
kube-proxy
(updates networking)
The Declarative Model
Kubernetes uses a declarative model. Instead of telling K8s how to do something step by step, you declare what you want the end state to look like, and Kubernetes figures out how to get there.
Imperative (what you do):
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
Declarative (what you should do):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
The declarative approach is preferred because:
- It’s version-controllable (store YAML in Git)
- It’s reproducible (apply the same manifest anywhere)
- It’s self-documenting (the YAML describes the desired state)
Summary
| Component | Role | Runs On |
|---|---|---|
| API Server | Front door to the cluster | Control Plane |
| etcd | Cluster state database | Control Plane |
| Scheduler | Assigns Pods to Nodes | Control Plane |
| Controller Manager | Ensures desired state = current state | Control Plane |
| kubelet | Runs Pods on nodes | Worker Node |
| kube-proxy | Network routing for Services | Worker Node |
| Container Runtime | Actually runs containers | Worker Node |
What’s Next?
Now that you understand the architecture, let’s dive into the most fundamental building block in Kubernetes — the Pod.