Kubernetes Architecture and Deployment Strategies
Prerequisite Knowledge
This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.
Previously Covered in This Subject
- Containerization fundamentals and Docker architecture — covered in Lecture 13
- Docker objects (images, containers, volumes) and Dockerfiles — covered in Lecture 13
- Kubernetes basics and the master-slave architecture — covered in Lecture 13
- kubectl and Minikube — covered in Lecture 13
- CI/CD pipelines with Docker and Kubernetes — covered in Lecture 13
Why this matters: Every cloud platform — AWS, Azure, Google Cloud — runs on Kubernetes under the hood. Understanding Kubernetes architecture is not just about one tool; it is about understanding the universal foundation that every managed container service (EKS, AKS, GKE) is built on. Learn it once, apply it everywhere.
14.1 From Docker to Kubernetes — Why Orchestration Is Needed
The core question: You already know how to package an application into a Docker container. But what happens when one container is not enough — when you need to serve millions of users, handle failures automatically, and roll out updates without downtime? This section explains why Docker alone falls short and why Kubernetes exists.
14.1.1 Docker Architecture Recap
Docker provides the foundational building block for containerized applications: the container engine (the runtime that creates, starts, and manages containers on a single machine). The Docker architecture has three tiers:
- Client side — the CLI where you type commands like
docker pull,docker build, anddocker run. The client does not run containers itself; it sends instructions to the daemon. - Docker daemon (
dockerd) — the background service on your machine that actually builds images, runs containers, manages networks, and handles storage. It listens for REST API requests from the client. - Docker Hub (or any container registry) — a central image registry where pre-built images are stored and versioned. Think of it as an app store for container images.
The workflow is straightforward:
- Write a
Dockerfilewith layer-by-layer instructions (install OS, copy code, set entrypoint). - Build an image:
docker build -t my-app:v1 . - Optionally push it to a registry:
docker push my-app:v1 - Anyone with a Docker engine can pull and run:
docker pull my-app:v1 && docker run my-app:v1
This applies uniformly whether the application is a web app, a mobile backend, or an ML model serving predictions.
Intuition — the restaurant kitchen analogy: Think of Docker as a single restaurant kitchen. It can prepare any dish (run any image), it has all the tools (runtime, networking, storage), and it keeps ingredients isolated (container isolation). But it is one kitchen in one location. If your restaurant suddenly goes viral and 10,000 customers arrive, one kitchen cannot serve them all. You need a chain manager — someone who can open new kitchens across the city, route customers to the nearest one, and close kitchens when demand drops. That chain manager is Kubernetes.
Limitations of Docker alone:
However, Docker alone is insufficient for running applications at scale across multiple nodes. When an application needs to serve hundreds of thousands or millions of users, a single container on a single machine cannot handle the load. Docker does not provide built-in mechanisms for:
- Distributing containers across machines — Docker runs containers on the machine where you execute the command. There is no built-in way to say "run this container on the machine with the most free resources."
- Load balancing traffic — If you manually run 5 copies of a container on 5 machines, Docker has no mechanism to spread incoming requests across them.
- Automatically restarting failed containers — While Docker can restart a single container with
--restart=always, it cannot detect and recover from machine-level failures. - Scaling instances based on demand — Docker cannot watch traffic metrics and add or remove containers in response.
This is where Kubernetes enters the picture. Kubernetes is a container orchestration tool — it automates the deployment, scaling, and management of containerized applications across clusters of machines.
14.1.2 Why Kubernetes Is Needed
The two technologies go hand in hand. Docker creates and runs individual containers; Kubernetes orchestrates those containers across many machines. The relationship is complementary, not competitive:
| Concern | Docker handles it? | Kubernetes handles it? |
|---|---|---|
| Build and package an application as an image | ✅ Yes | ❌ No (uses Docker images) |
| Run a container on a single machine | ✅ Yes | ❌ No (delegates to Docker/containerd) |
| Distribute containers across multiple machines | ❌ No | ✅ Yes |
| Load balance traffic across replicas | ❌ No | ✅ Yes |
| Auto-restart failed containers across nodes | ❌ No | ✅ Yes |
| Scale replicas up/down based on demand | ❌ No | ✅ Yes |
| Rolling updates with zero downtime | ❌ No | ✅ Yes |
Pitfall — confusing Docker and Kubernetes: A common beginner mistake is thinking Kubernetes replaces Docker. It does not. Kubernetes uses Docker (or another container runtime like containerd) to run containers. You still write Dockerfiles, build images, and push them to registries. Kubernetes adds the orchestration layer on top.
Every managed Kubernetes service in the cloud — AWS EKS (Elastic Kubernetes Service), Azure AKS (Azure Kubernetes Service), Google GKE (Google Kubernetes Engine) — uses the same underlying architecture. Understanding the architecture once means you can work with Kubernetes anywhere.
Recap: Docker packages and runs containers on a single machine. Kubernetes orchestrates those containers across a cluster of machines, providing distribution, load balancing, self-healing, and scaling. The two work together — you cannot have Kubernetes without a container runtime underneath.
Real-world connection: When Instagram scaled from a small startup to serving hundreds of millions of photos, they moved from running Django on a few servers to containerized microservices orchestrated by Kubernetes. The same pattern applies to ML model serving — a single docker run works for development, but production ML inference at scale requires Kubernetes to manage dozens of model-serving replicas across multiple machines.
14.2 Kubernetes Architecture — Control Plane and Worker Nodes
Hook: When you type kubectl get pods and see a list of running pods, what happens behind the scenes? Which component receives your command? Which one knows the current state? Which one decides where to run a new pod? Understanding the Kubernetes architecture means understanding the machinery behind every command you type.
Kubernetes follows a master-slave architecture (also called control plane and worker nodes). The overall structure is a three-tiered architecture:
graph TD
A["Client Tier<br/>(kubectl CLI)"] --> B["Control Plane<br/>(Master Node)"]
B --> C["Worker Node 1"]
B --> D["Worker Node 2"]
B --> E["Worker Node N"]
B --> F["etcd<br/>(State Store)"]
subgraph "Control Plane Components"
B1["API Server"]
B2["Scheduler"]
B3["Controller Manager"]
end
subgraph "Worker Node Components"
C1["Kubelet"]
C2["Container Runtime"]
C3["Pods"]
end
The three tiers of Kubernetes architecture:
Client tier: The user interacts with Kubernetes through a command-line interface called kubectl (pronounced "cube control"). This tool is available for Windows, Linux, and Mac. All Kubernetes commands start with kubectl — analogous to how Docker commands start with docker. kubectl is not part of the cluster itself; it is a client that sends HTTP requests to the API Server.
Control plane (master node): Contains four components — API Server, Scheduler, Controller Manager, and etcd. These components manage the entire cluster. The control plane does not run your application containers; it only manages them.
Worker nodes: One or more machines where the actual application containers run. Each worker node runs an instance of the Kubernetes runtime. A worker node can be a physical machine, a virtual machine (like an EC2 instance), or even a container itself. This is where your actual application code executes.
Intuition — the hospital analogy: Think of the control plane as the hospital administration. The API Server is the front desk (receiving all requests), etcd is the patient records system (storing the current state of everything), the Scheduler is the bed assignment coordinator (deciding which ward gets a new patient), and the Controller Manager is the head nurse (ensuring the right number of staff are on duty at all times). The workers are the actual wards where patients (containers) are treated. The administration never treats patients directly — they only manage the process.
14.2.1 The API Server
The API Server is the front door to the Kubernetes cluster. Every kubectl command is sent to the API Server first. It is essentially a REST API that listens for HTTP POST requests — the same pattern as running an inference server where you receive a request, process it, and return a response.
Commands that arrive at the API Server can be at multiple levels:
- Cluster level: Create an entire cluster, delete a cluster.
- Pod level: Create a new pod, delete pods, get the list of running pods.
- Container level: Inspect or manage individual containers.
Common operations map to HTTP methods:
| Operation | kubectl command | HTTP method | What it does |
|---|---|---|---|
| Get | kubectl get pods |
GET | Retrieves information from etcd |
| Create | kubectl create deployment |
POST | Creates a new resource |
| Edit | kubectl edit deployment |
PUT/PATCH | Modifies an existing resource |
| Delete | kubectl delete deployment |
DELETE | Removes a resource |
The API Server processes these commands by coordinating with the other control plane components. It does not make decisions alone — it delegates to the Scheduler for placement decisions and to the Controller Manager for state enforcement.
Worked example — what happens when you type kubectl get pods:
- kubectl sends an HTTP GET request to the API Server endpoint:
GET /api/v1/pods - The API Server authenticates the request (checks your credentials).
- The API Server queries etcd: "What pods are currently running?"
- etcd returns the list of pods with their status (Running, Pending, CrashLoopBackOff, etc.).
- The API Server formats the response and sends it back to kubectl.
- kubectl displays the table you see in your terminal.
Total time: typically under 100 milliseconds.
The professor's analogy: The API Server is like an inference server. Just as an ML inference server receives an HTTP POST request with input data, processes it through the model, and returns a prediction, the API Server receives a kubectl request, processes it through the appropriate control plane component, and returns the cluster state. The pattern is identical: receive → process → respond.
14.2.2 etcd — The Cluster State Store
etcd (pronounced "et-see-dee") is a distributed key-value store that holds the current state of the entire cluster. Just as JSON is a key-value format used in everyday computing, etcd is a purpose-built distributed key-value database for Kubernetes. It stores information such as:
- How many pods are running
- Which pods are healthy and which are unhealthy
- Which containers are running on which nodes
- The current configuration of every resource (deployments, services, config maps)
Intuition — the central ledger: Think of etcd as the central ledger in a bank. Every transaction (pod creation, deletion, scaling) is recorded there. When the API Server needs to answer "how many pods are running?", it checks the ledger. When the Scheduler needs to know which worker node has free capacity, it checks the ledger. When the Controller Manager needs to compare the desired state with reality, it checks the ledger. Everyone reads from and writes to the same ledger — it is the single source of truth.
When the API Server receives a get request (e.g., "how many pods are running?"), it queries etcd directly. etcd returns the current state, and the API Server sends the response back to the client. Every other control plane component — the Scheduler, the Controller Manager — also queries etcd whenever it needs data about the current state of the cluster.
Pitfall — etcd is not a general-purpose database: etcd is optimized for storing small, frequently-read, rarely-written configuration data. It is not designed for storing application data, logs, or large binary blobs. If you need to store application state, use a proper database (PostgreSQL, MongoDB) running as a pod in the cluster, not etcd.
Why distributed? etcd runs on multiple nodes (typically 3 or 5 for fault tolerance) and uses the Raft consensus algorithm to keep all copies in sync. If one etcd node fails, the others continue serving requests. This ensures the cluster state is never lost even if individual machines fail.
14.2.3 The Scheduler
When the API Server receives a command to create a new pod, it must decide which worker node should host that pod. This is the job of the Scheduler. Scheduling is not unique to Kubernetes — it is a fundamental problem in computing (operating systems schedule processes on CPUs, airlines schedule flights to gates, hospitals schedule surgeries to operating rooms).
The scheduling process works as follows:
- A command arrives at the API Server: "create a new pod."
- The API Server asks the Scheduler about the status of worker nodes.
- The Scheduler checks resource availability — worker node 1 might be 80% full (memory and CPU), worker node 2 might be 40% full.
- Based on its scheduling algorithm, the Scheduler suggests the API Server route the pod creation to the worker node with the most available capacity (e.g., worker node 2 at 40%).
Worked example — scheduling decision with real numbers:
Suppose you have 3 worker nodes:
| Node | Total Memory | Used Memory | Free Memory | Total CPU | Used CPU | Free CPU |
|---|---|---|---|---|---|---|
| Node-1 | 16 GB | 12 GB | 4 GB | 4 cores | 3 cores | 1 core |
| Node-2 | 16 GB | 6 GB | 10 GB | 4 cores | 1 core | 3 cores |
| Node-3 | 16 GB | 14 GB | 2 GB | 4 cores | 4 cores | 0 cores |
You request a new pod that needs 2 GB memory and 1 CPU core.
- Node-1: Has 4 GB free memory and 1 free CPU core → fits (barely).
- Node-2: Has 10 GB free memory and 3 free CPU cores → fits comfortably.
- Node-3: Has 2 GB free memory but 0 free CPU cores → does not fit.
The Scheduler selects Node-2 because it has the most available resources. The pod is assigned to Node-2.
The two primary resource constraints the Scheduler considers are memory and CPU. The Scheduler evaluates how much memory and CPU each worker node has available and assigns the pod accordingly. In practice, the default scheduling algorithm (called LeastRequested) prefers nodes with the most free resources, spreading the load evenly.
Pitfall — the Scheduler is not a load balancer: The Scheduler decides where to place a new pod (which worker node). It does not distribute incoming network traffic across pods — that is the job of kube-proxy and Services (covered in section 14.7). Confusing these two roles is a common exam mistake.
14.2.4 The Controller Manager
The Controller Manager enforces the desired state of the cluster. It continuously watches etcd for the current state and compares it to the desired state declared in your YAML manifests. If they differ, the Controller Manager takes action to reconcile them.
The professor's analogy: The Controller Manager is like a PT master (physical training instructor) in school. The PT master controls everything — how many students should be in each line, whether anyone is missing, and whether the formation matches the plan. If a student leaves the line, the PT master notices and asks someone to fill the gap. The Controller Manager does the same for pods.
It has two sub-controllers:
Replica Set Controller: Determines how many instances (replicas) of a pod should be running. If the desired replica count is 1, only one pod runs. If the replica count is increased to 10, the Replica Set Controller ensures 10 pods are created. The default replica set is 1.
For example, consider a pod running a container. If the replica set is 1, one instance runs. If demand increases (say, on December 25th when traffic spikes), the replica set can be increased from 1 to 10 or 20. Each new pod runs its own container instance of the same image. If one pod can serve 100 users, 10 pods can serve 1,000 users.
Deployment Controller: Operates at a higher level of abstraction than the Replica Set Controller. When you issue kubectl create deployment, the command goes directly to the Deployment Controller, which then coordinates with the Replica Set Controller. The hierarchy is:
Deployment → Replica Set → Pod → Container
You cannot directly create a pod in Kubernetes — you always create a deployment, which internally manages replica sets and pods.
Recap — the four control plane components:
| Component | Role | One-line summary |
|---|---|---|
| API Server | Front door | Receives all kubectl commands, coordinates with other components |
| etcd | State store | Distributed key-value database holding the current cluster state |
| Scheduler | Placement | Decides which worker node hosts a new pod based on resource availability |
| Controller Manager | Enforcement | Ensures the desired number of pods are running (Replica Set + Deployment controllers) |
All four work together in a continuous loop: the API Server receives commands, etcd stores state, the Scheduler places pods, and the Controller Manager maintains the desired count.
14.3 Pods — The Smallest Deployable Unit
Hook: You cannot run a container directly in Kubernetes. There is no kubectl run my-container command that works the way docker run does. Kubernetes forces you to wrap every container inside a pod — a thin but essential abstraction layer. Why? Because Kubernetes needs to attach networking and storage metadata to your containers, and the pod is how it does that.
A pod is the smallest deployable unit in Kubernetes. You cannot run a container directly within Kubernetes — containers must be wrapped in pods. A pod provides:
- A unique IP address (e.g., 10.10.10.1) for network access. Every pod in the cluster gets its own IP, so pods can communicate with each other directly.
- One or more containers running images.
- Optional volumes for data persistence.
Intuition — the apartment analogy: Think of a pod as an apartment in a building. The apartment (pod) has its own address (IP address), it can house one or more people (containers), and it has storage space (volumes). The building (worker node) provides utilities (CPU, memory, networking), but each apartment is independently addressed. Just as you cannot have a person living in a building without an apartment, you cannot have a container running in Kubernetes without a pod.
14.3.1 Pod Composition Patterns
A pod can contain different combinations of containers and volumes:
| Pattern | Containers | Volumes | Use case |
|---|---|---|---|
| Simplest | 1 | 0 | Single standalone application |
| With storage | 1 | 1 | Application that needs to persist data |
| Shared storage | 2 | 1 | Two containers that share a filesystem (e.g., log collector + app) |
| Complex | 3 | 2 | Multiple containers with multiple storage needs |
The general industry guideline from AWS and Azure is one container per pod (one-to-one). The reasoning is practical: if a container fails within a one-to-one pod, the kubelet simply restarts that single container. In a multi-container pod, diagnosing which container failed and restarting only the failed one adds complexity.
However, there are valid exceptions. For a small application where a web server and a database serve very few users, placing both in a single pod makes sense — they scale together. When you increase the replica set, both the web application and database instances increase in tandem.
Q: How many containers can fit in a pod? Is there a limit?
A: There is no hard limit — it depends on the worker node's resources (CPU and memory). A high-capacity VM like a C-series or X-series instance can run many containers in a pod. However, the general industry guideline from AWS and Azure is one container per pod. The reasoning is practical: fault isolation is simpler (the kubelet restarts one container, not a group), and observability is cleaner — each container exposes logs on its own port, and a monitoring tool like Prometheus can listen to each pod independently. Multi-container pods complicate monitoring because each container must expose logs on a different port.
Worked example — pod composition for a web application:
Suppose you have a simple web application that serves user profiles. Here is how you would structure the pods:
Scenario 1: One container, zero volumes (simplest)
- Pod:
user-profile-pod - Container:
user-profile-api(image:my-app:v1) - No volumes — the app is stateless, all data comes from an external database.
Scenario 2: One container, one volume (with caching)
- Pod:
user-profile-pod - Container:
user-profile-api(image:my-app:v1) - Volume:
/cache— stores frequently-accessed profile data on disk so it survives container restarts.
Scenario 3: Two containers, one volume (sidecar pattern)
- Pod:
user-profile-pod - Container 1:
user-profile-api(image:my-app:v1) — the main application. - Container 2:
log-collector(image:fluentd:v1) — reads logs from the shared volume and ships them to a central logging system. - Volume:
/var/log— shared between both containers.
In Scenario 3, both containers share the same network namespace (they can talk via localhost) and the same volume. When you scale the replica set to 5, you get 5 pods, each with both the API and the log collector.
14.3.2 Volumes and Data Persistence
A volume in Kubernetes serves the same purpose as in Docker: it persists data across container restarts. Without a volume, whenever a container is stopped and restarted, all data within that container is lost. Volumes ensure that data survives across multiple container instances within the same pod, and across pod restarts.
Pitfall — volumes do not survive pod deletion: A volume attached to a pod persists across container restarts within that pod, but if the pod itself is deleted, the volume's data may be lost (depending on the volume type). For data that must survive pod deletion, you need PersistentVolumes (PVs) — a separate Kubernetes resource backed by external storage (cloud disks, NFS, etc.).
14.3.3 Scaling with Pods
Scaling is straightforward: if you want 5 instances of an application, you create 5 pods. If one container serves 100 users, 5 pods serve 500 users. The Replica Set Controller manages this — it ensures the desired number of pod instances are always running. Behind the scenes, each pod runs its own container(s), each running the same image.
Worked example — scaling math:
- 1 pod × 100 users/pod = 100 users served
- 5 pods × 100 users/pod = 500 users served
- 10 pods × 100 users/pod = 1,000 users served
If traffic increases to 800 concurrent users and each pod handles 100, you need ⌈800/100⌉ = 8 pods. You change the replica count from the current value to 8, and the Replica Set Controller creates the additional pods.
14.3.4 Pod Size and Abstraction
A pod is an abstraction layer — it has no inherent size. The pod's resource footprint is determined entirely by the containers it encapsulates. Pod, Replica Set, and Deployment are virtual layers of abstraction; the only physical entity actually running is the container (which reflects the image). The container's size — its memory and CPU requirements — determines the effective "size" of the pod.
The professor's key insight: The only physical entity in Kubernetes is the container. Pods, Replica Sets, and Deployments are virtual layers of abstraction built on top. When you think about resource consumption, think about the container — it is the container's image that determines memory and CPU usage. The pod is just a wrapper with an IP address.
Recap: A pod is the smallest deployable unit in Kubernetes — it wraps one or more containers with a shared network namespace and optional volumes. Industry best practice is one container per pod for simplicity. Pods are abstract wrappers; the container is the physical entity that consumes resources.
14.4 The Worker Node and Kubelet — Self-Healing in Action
Hook: What happens when a container crashes at 3 AM and nobody is watching? In a traditional setup, the application stays down until someone notices and restarts it. In Kubernetes, the kubelet — a tiny agent running on every worker node — detects the failure within seconds and restarts the container automatically. This is self-healing, and it is one of Kubernetes' most powerful features.
Each worker node contains a critical component called the kubelet (pronounced "kube-let"). The kubelet is the agent responsible for maintaining the health of all pods and containers within its worker node. It performs three key functions:
- Container creation: When a new pod is scheduled to a worker node, the kubelet creates the containers within that pod by pulling the image and starting the runtime.
- Container restart: If a container crashes or stops, the kubelet restarts it immediately. It does not wait for a human to intervene.
- Health monitoring: The kubelet continuously monitors the state of every container, ensuring the desired number of healthy instances are running. It checks container status every few seconds.
Intuition — the building security guard: Think of the kubelet as a security guard stationed in a building (worker node). The guard's job is to check every room (container) regularly. If a room is empty when it should be occupied (container stopped), the guard immediately calls for a replacement. If someone is in distress (container in CrashLoopBackOff), the guard tries to help, but keeps trying at regular intervals. The guard never leaves the building and never stops checking — this is the "continuous monitoring" that makes self-healing possible.
14.4.1 Self-Healing at Two Levels
Self-healing operates at two levels in the Kubernetes architecture:
Pod level (managed by API Server and Scheduler): If a pod cannot be scheduled on a worker node (e.g., insufficient resources), it is rescheduled to another worker node. This is the cluster-level self-healing mechanism — the control plane detects that the desired state (N pods running) does not match the actual state (fewer than N pods running) and takes corrective action.
Container level (managed by kubelet): Within a worker node, if a container fails, the kubelet restarts it. This happens continuously — the kubelet never stops monitoring. If you specify that 2 pod instances should be running, the kubelet ensures exactly 2 instances are running at all times, even if one is stopped, deleted, or crashes.
Q: When we say a pod is going into a "crash loop," does that mean all containers are crashing, or can just one container crash?
A: Only one container can be in a crash loop while others continue working fine. It is not an all-or-nothing failure. The kubelet will restart only the failed container. Other containers within the same pod or other pods continue to serve users, though some users may experience inconvenience while the failed container is being recovered.
Q: Will there be an error if no space is left and the container size exceeds available resources?
A: Yes — if the Scheduler cannot find a worker node with enough memory or CPU, the pod will not be scheduled. This is where the kubelet and the self-healing mechanism come in. The pod will be rescheduled to another worker node that has sufficient capacity. At the container level, the kubelet continuously monitors health and restarts containers that fail. At the pod level, the API Server and Scheduler handle rescheduling to ensure the desired state is met.
14.4.2 Crash Loop BackOff
When a container repeatedly fails and is restarted, Kubernetes reports its status as CrashLoopBackOff. This means:
- The container is crashing (exiting with a non-zero exit code).
- Kubernetes is waiting before retrying — this is the "back off" period (exponential backoff: 10s, 20s, 40s, 80s, up to 5 minutes).
- The kubelet will attempt to restart it again after the backoff period.
Worked example — CrashLoopBackOff timeline:
| Time | Event | Status |
|---|---|---|
| T+0s | Container starts, crashes after 2s | CrashLoopBackOff |
| T+10s | Kubelet restarts container, crashes again | CrashLoopBackOff |
| T+30s | Kubelet restarts container (20s backoff), crashes again | CrashLoopBackOff |
| T+70s | Kubelet restarts container (40s backoff), crashes again | CrashLoopBackOff |
| T+150s | Kubelet restarts container (80s backoff), crashes again | CrashLoopBackOff |
| T+390s | Kubelet restarts container (240s backoff) | Continues retrying... |
The kubelet manages this cycle automatically. If one pod among several goes into CrashLoopBackOff, the remaining pods continue to serve traffic — the failure is isolated to that single pod.
Pitfall — CrashLoopBackOff is not "broken": Seeing CrashLoopBackOff in kubectl get pods does not mean Kubernetes is failing. It means Kubernetes is doing its job — detecting a crashing container and retrying. The real problem is in your application code or configuration (e.g., a missing environment variable, a bad entrypoint command, an out-of-memory error). Fix the root cause; do not just restart manually.
14.4.3 The Docker Engine Dependency
Everything in Kubernetes runs on top of the Docker engine (or another container runtime like containerd). If the Docker engine itself fails on a worker node, all pods on that node will stop running. However, as long as the Docker engine is operational, the kubelet handles all container-level failures automatically.
Pitfall — runtime failure vs. container failure: The kubelet can restart containers that crash, but it cannot restart the container runtime (Docker/containerd) if it fails. Runtime failure is a node-level problem — the control plane will detect that the node is unhealthy and reschedule its pods to other nodes, but there will be a brief interruption.
Recap: The kubelet is the health manager on every worker node. It creates containers, restarts them when they crash, and continuously monitors their state. Self-healing works at two levels: container level (kubelet restarts crashed containers) and pod level (control plane reschedules pods to healthy nodes). CrashLoopBackOff is normal retry behavior, not a system failure.
14.5 Replica Sets and Scaling
Hook: How do you go from serving 100 users to serving 10,000 users without rewriting any code? The answer is scaling — and the Replica Set is the mechanism that makes it possible. By changing a single number in your deployment configuration, Kubernetes creates or destroys pods to match your desired capacity.
The Replica Set is the mechanism for controlling how many pod instances run at any time. The default replica set is 1 — when you create a deployment, one pod is created by default.
Intuition — the photocopy machine analogy: Think of a Replica Set as a photocopy machine. You put in one original document (your container image) and tell the machine "make 10 copies." The machine produces 10 identical copies. If one copy gets damaged (a pod crashes), the machine immediately produces a replacement. If you change the setting to 5 copies, it destroys 5 extras. The Replica Set Controller is the machine — it always maintains exactly the number of copies you specified.
14.5.1 Scaling Up
To handle increased load, the replica count can be increased. For example, changing the replica set from 1 to 10 creates 9 new pods (in addition to the existing one). Each pod runs its container independently. The kubelet on each worker node is responsible for physically creating these new containers.
The command to scale is kubectl edit deployment <deployment-name>. Opening the deployment YAML shows the current replica count. Changing the number and saving the file triggers the scaling — Kubernetes automatically creates or deletes pods to match the new desired count. No manual execution step is needed; the change is applied immediately.
Worked example — scaling from 1 to 8 replicas:
- Current state:
replicas: 1→ 1 pod running. - You edit the deployment: change
replicas: 1toreplicas: 8. - The Replica Set Controller detects the desired state changed from 1 to 8.
- It issues a command to create 7 new pods.
- The Scheduler assigns each new pod to a worker node with available resources.
- The kubelet on each assigned node creates the containers.
- After a few seconds,
kubectl get podsshows 8 pods: 1 running (original) + 7 in various states (Pending → ContainerCreating → Running).
kubectl get pods
NAME READY STATUS RESTARTS AGE
iris-deploy-abc123 1/1 Running 0 5m
iris-deploy-def456 0/1 ContainerCreating 0 2s
iris-deploy-ghi789 0/1 Pending 0 2s
...
Within 30-60 seconds, all 8 pods will be in Running state.
14.5.2 Scaling Down
Scaling down works the same way in reverse. If you change the replica count from 4 to 1, three pods enter the Terminating state and are removed. The kubelet handles the deletion.
Worked example — scaling down from 4 to 1:
- Current state:
replicas: 4→ 4 pods running. - You edit the deployment: change
replicas: 4toreplicas: 1. - The Replica Set Controller detects the desired state changed from 4 to 1.
- It selects 3 pods for termination (typically the most recently created ones).
- Each selected pod enters
Terminatingstatus. - The kubelet on each worker node gracefully shuts down the containers (sends SIGTERM, waits for graceful shutdown period, then sends SIGKILL).
- After termination,
kubectl get podsshows only 1 pod.
14.5.3 Behind the Scenes
When you change the replica count, the Replica Set Controller issues the command (increase or decrease), and the kubelet on the worker node physically creates or destroys containers. The Replica Set Controller decides what to do; the kubelet does the actual work.
Pitfall — scaling is not instant: Changing the replica count does not create pods instantly. There is a delay of 10-60 seconds per pod, depending on image size, node resources, and network speed. If your image is large (e.g., a full ML framework image at 2+ GB), container creation can take several minutes. Keep images small for faster scaling.
Recap: The Replica Set ensures exactly N pods are running at all times. Scale up by increasing the replica count; scale down by decreasing it. The Replica Set Controller decides the action; the kubelet executes it. The default replica count is 1.
14.6 Deployments and YAML Manifests
Hook: Everything in Kubernetes is driven by a desired state declared in a YAML file. You do not tell Kubernetes "run this container on that machine." Instead, you tell Kubernetes "I want 3 replicas of this image running at all times" — and Kubernetes figures out how to make that happen. This is the difference between imperative (step-by-step instructions) and declarative (describe the goal) thinking.
A Deployment is the highest level of abstraction in Kubernetes. The hierarchy is:
graph TD
A["Deployment<br/>(highest abstraction)"] --> B["Replica Set<br/>(how many instances)"]
B --> C["Pod<br/>(networking + storage wrapper)"]
C --> D["Container<br/>(runs the image)"]
When you issue kubectl create deployment, the command flows through the Deployment Controller, which creates a Replica Set, which in turn creates Pods, which contain Containers. This entire chain is triggered by a single command.
14.6.1 Two Ways to Create Deployments
Method 1 — Command line (imperative):
kubectl create deployment nginx-deploy --image=nginx
This creates a deployment named "nginx-deploy" using the nginx system image. The default replica set is 1.
Method 2 — YAML manifest file (declarative): Create a YAML file that declares the desired state, then apply it:
kubectl apply -f iris-deployment.yaml
The -f flag stands for "file" (not "force").
Worked example — creating a deployment with the iris model:
Step 1: Build the Docker image locally.
docker build -t iris-model:latest .
Step 2: Load the image into Minikube (so Minikube can find it without pulling from Docker Hub):
minikube image load iris-model:latest
Step 3: Create the deployment YAML file (iris-deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: iris-deployment
spec:
replicas: 2
selector:
matchLabels:
app: iris
template:
metadata:
labels:
app: iris
spec:
containers:
- name: iris-container
image: iris-model:latest
imagePullPolicy: Never
Step 4: Apply the deployment:
kubectl apply -f iris-deployment.yaml
Step 5: Verify:
kubectl get pods
# Should show 2 pods in Running state
kubectl get deployment
# Should show iris-deployment with 2/2 READY
14.6.2 The YAML Manifest Structure
A deployment YAML file (also called a manifest) has this structure:
| Field | Purpose | Example |
|---|---|---|
apiVersion |
Kubernetes API version | apps/v1 |
kind |
Resource type | Deployment |
metadata.name |
Name of the deployment | iris-deployment |
spec.replicas |
How many pod instances (default: 1) | 2 |
spec.template.spec.containers[].name |
Container name | iris-container |
spec.template.spec.containers[].image |
Image to use | iris-model:latest |
spec.template.spec.containers[].imagePullPolicy |
Where to fetch the image | Never (local only) |
Pitfall — imagePullPolicy: Never vs imagePullPolicy: Always: Setting imagePullPolicy: Never means Kubernetes will only use images available locally (from Docker Desktop or Minikube). It will never try to pull from Docker Hub. This is essential for local development with custom images. In production, you typically use imagePullPolicy: Always to ensure the latest version is always pulled from the registry.
14.6.3 YAML as a Configuration Language
YAML is a semi-structured language, sitting between structured data (Excel, CSV) and unstructured data (PPT, video). XML and JSON were historically the most popular semi-structured formats, but YAML has become the dominant language for configuration files, especially in Kubernetes and cloud-native tooling.
Why YAML, not JSON? YAML is human-readable in a way JSON is not. Compare:
JSON:
{"apiVersion": "apps/v1", "kind": "Deployment", "spec": {"replicas": 2}}
YAML:
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
YAML uses indentation instead of braces, and does not require quotes around most values. This makes it easier to read and edit by hand — which is exactly what you do when managing Kubernetes deployments.
The manifest file is written in YAML and describes the desired state of the cluster — what deployments should exist, how many replicas, which images, and so on.
14.6.4 kubectl apply vs kubectl create deployment
Both commands achieve the same result — creating a deployment — but they work differently:
| Aspect | kubectl create deployment |
kubectl apply -f |
|---|---|---|
| Approach | Imperative (command-line) | Declarative (YAML file) |
| Reproducibility | One-shot; hard to reproduce | YAML file is version-controlled |
| Production use | Quick testing only | Preferred for production |
| Rollback | Manual | Can revert to previous YAML in Git |
| Team collaboration | Requires sharing the exact command | Team reads the YAML file |
The professor's explanation: kubectl create deployment is a one-shot command — you run it once and the deployment exists, but there is no record of what you did. kubectl apply -f reads the desired state from a YAML file and applies it. The YAML file can be stored in Git, shared with your team, and used to recreate the exact same deployment on any cluster. This is the declarative approach — you describe what you want, not how to create it.
Recap: A Deployment is the top-level abstraction in Kubernetes. It manages Replica Sets, which manage Pods, which manage Containers. You create deployments either imperatively (kubectl create deployment) or declaratively (kubectl apply -f). The YAML manifest is the source of the desired state — store it in Git, apply it with kubectl.
14.7 Kube Proxy and Services — Making Pods Accessible
Hook: You have pods running your application, but how does a user in Tokyo reach them? Pods have IP addresses, but those IPs change every time a pod is recreated. You cannot give users a pod IP and expect it to work forever. The Service abstraction solves this by providing a stable, permanent IP address that routes traffic to whichever pods are currently running.
14.7.1 Static IPs, DNS, and Request Routing
All the components discussed so far — pods, replica sets, deployments — operate within the cluster. But the end goal is for users anywhere in the world to access the application. With so many layers of abstraction, how does an end user reach the right container?
The answer involves two components: Services and kube-proxy.
Service: A Service creates a static IP address with a DNS name (e.g., www.something.com) at the pod level. The end user accesses this static IP — they do not know and do not need to know which specific pod replica they are hitting. Whether they are routed to replica 1 or replica 10 is transparent. The Service IP remains constant even as pods are created and destroyed.
kube-proxy: kube-proxy handles the actual request routing. When a request arrives at the Service's static IP, kube-proxy redirects it to an available pod instance based on availability and load. You cannot manually write rules like "request 1 goes to pod 1, request 2 goes to pod 2" — kube-proxy handles this automatically.
Intuition — the phone number analogy: Think of a Service as a company's main phone number (e.g., 1-800-FLOWERS). You dial one number, and the phone system routes your call to whichever representative is available. You do not need to know each representative's direct line. The Service is that main number; kube-proxy is the phone system that routes calls.
graph LR
A["User Request"] --> B["Service<br/>(Static IP + DNS)"]
B --> C["kube-proxy<br/>(Load Balancer)"]
C --> D["Pod 1<br/>(Running)"]
C --> E["Pod 2<br/>(Running)"]
C --> F["Pod 3<br/>(Crashed)"]
The implication is important: all pod replicas are equal in nature. Any incoming request is routed to whichever pod is available. This means state should not be maintained within containers — if you need a database or event store, it should be in a separate container or external service. The application containers should be stateless.
Q: Within the worker node, how is load balancing maintained?
A: Load balancing across worker nodes is handled externally, not within individual worker nodes. A load balancer component sits outside the worker nodes and decides which worker node should receive incoming traffic. Within a worker node, the kubelet manages container health, but traffic distribution across nodes is an external concern.
Pitfall — pods are ephemeral, Services are stable: Never hard-code pod IPs in your application or share them with users. Pod IPs change every time a pod is recreated. Always use the Service's static IP or DNS name. This is a fundamental design principle in Kubernetes.
Recap: Services provide stable IP addresses and DNS names that route traffic to healthy pod replicas. kube-proxy handles the actual load balancing. All replicas are equal — any request can go to any pod. This is why Kubernetes applications should be stateless.
14.8 Minikube — A Single-Node Cluster for Learning
Hook: You do not need a multi-node cloud cluster to learn Kubernetes. Minikube creates a complete single-node Kubernetes cluster on your laptop — it includes the control plane and one worker node, all running inside a single machine. Every command that works on Minikube works identically on AWS EKS, Azure AKS, and Google GKE.
14.8.1 Minikube Setup and Commands
Minikube is a tool that creates a single-node Kubernetes cluster — it includes both a control plane and one worker node on your local machine. Every command that works on a production Kubernetes cluster (AWS EKS, Azure AKS, Google GKE) also works on Minikube. It is designed for experimentation and learning purposes.
Worked example — complete Minikube workflow with the iris model:
Step 1: Install and start Minikube.
# Install Minikube (if not already installed)
# Then start the cluster
minikube start
This creates a single-node cluster with both the control plane and worker node running on your machine.
Step 2: Load a local Docker image into Minikube.
minikube image load iris-model:latest
This copies a locally built Docker image into Minikube's internal container registry so pods can use it without pulling from Docker Hub.
Step 3: Apply a deployment YAML.
kubectl apply -f iris-deployment.yaml
This creates the deployment, which creates the Replica Set, which creates the Pods.
Step 4: View running pods.
kubectl get pods
Output shows the pods in Running state:
NAME READY STATUS RESTARTS AGE
iris-deployment-7b8f9d4c5-abc12 1/1 Running 0 30s
iris-deployment-7b8f9d4c5-def34 1/1 Running 0 30s
Step 5: View deployments.
kubectl get deployment
Output shows the deployment with ready replicas:
NAME READY UP-TO-DATE AVAILABLE AGE
iris-deployment 2/2 2 2 45s
Step 6: Edit the deployment to scale up.
kubectl edit deployment iris-deployment
This opens the deployment YAML in your default editor. Change replicas: 2 to replicas: 8, save, and close. Kubernetes immediately begins creating 6 additional pods.
Step 7: Open the Minikube dashboard.
minikube dashboard
This opens a web-based UI showing the cluster state, pods, services, deployments, and other resources in a visual format.
Step 8: Delete the deployment.
kubectl delete deployment iris-deployment
This removes the deployment, all its Replica Sets, and all its pods.
Pitfall — forgetting minikube image load: A common beginner mistake is building a Docker image locally and then applying a deployment without loading the image into Minikube first. Kubernetes inside Minikube cannot see your local Docker images unless you explicitly load them with minikube image load. Without this step, pods will be stuck in ImagePullBackOff status because they cannot find the image.
Recap: Minikube is a local single-node Kubernetes cluster for learning. The workflow is: minikube start → minikube image load → kubectl apply -f → kubectl get pods. Every command works the same on production clusters. The minikube dashboard command provides a visual UI for monitoring.
14.9 The Layers of Abstraction in Kubernetes
Hook: Why does Kubernetes have so many layers? Why not just run containers directly? The answer is separation of concerns — each layer handles one job. The container handles the application. The pod handles networking. The Replica Set handles scaling. The Deployment handles versioning and updates. Understanding these layers is the key to understanding how Kubernetes works.
14.9.1 Container, Pod, Replica Set, Deployment
Kubernetes introduces four layers of abstraction, each building on the one below:
graph TD
A["Deployment<br/>Manages versions and rollouts"] --> B["Replica Set<br/>Maintains N copies"]
B --> C["Pod<br/>Networking + storage wrapper"]
C --> D["Container<br/>Runs the image"]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
style D fill:#fff3e0
| Layer | What it does | Physical or virtual? | Analogy |
|---|---|---|---|
| Container | Runs an application image | Physical — this is what actually executes | A single worker at a desk |
| Pod | Wraps containers with networking (IP) and storage (volumes) | Virtual — wrapper around containers | An office room (desks + shared resources) |
| Replica Set | Ensures N pod copies are running | Virtual — a scaling policy | The hiring manager (maintains headcount) |
| Deployment | Manages Replica Sets, versions, and rollouts | Virtual — the top-level orchestrator | The department head (strategy + versioning) |
The key insight: you cannot directly create a pod in Kubernetes. There is no kubectl create pod command. You always create a deployment (kubectl create deployment), and the entire chain — Deployment → Replica Set → Pod → Container — is created automatically.
The professor's warning: This is a common exam question. Students often confuse the layers. Remember: the only physical entity is the container. Everything above it (Pod, Replica Set, Deployment) is an abstraction layer. The container is what consumes CPU and memory. The pod just wraps it with an IP address. The Replica Set just counts how many pods. The Deployment just manages versions and rollouts.
Worked example — tracing a command through the layers:
When you run kubectl create deployment my-app --image=nginx, here is what happens at each layer:
- Deployment layer: The Deployment Controller creates a new Deployment resource named
my-app. - Replica Set layer: The Deployment Controller creates a Replica Set with
replicas: 1(the default). - Pod layer: The Replica Set Controller creates 1 Pod with a unique IP address (e.g., 10.244.0.5).
- Container layer: The kubelet on the assigned worker node pulls the
nginximage and starts a container inside the pod.
You typed one command; four layers of abstraction were created automatically.
Recap: Kubernetes has four abstraction layers: Container (physical, runs the image) → Pod (adds networking and storage) → Replica Set (maintains N copies) → Deployment (manages versions and rollouts). You always create Deployments, never Pods directly. Each layer has exactly one job.
14.10 Current State vs. Desired State — The Self-Healing Loop
Hook: What makes Kubernetes "self-healing"? The secret is a simple but powerful idea: Kubernetes is always comparing what is running (current state) with what should be running (desired state), and it never stops trying to close the gap. If a pod crashes, the current state drops below the desired state, and Kubernetes creates a replacement. If you scale down, the current state exceeds the desired state, and Kubernetes deletes extras. This continuous loop is the heartbeat of Kubernetes.
14.10.1 The Reconciliation Cycle
The fundamental operating principle of Kubernetes is the continuous reconciliation of two states:
Current state: What is actually running in the cluster right now. Stored in etcd. This is updated by the kubelet, the Scheduler, and other components as they report changes.
Desired state: What should be running, as declared in the YAML manifest file. This is the "spec" — the contract you wrote when you created the deployment.
Every Kubernetes component — the Scheduler, the kubelet, the Controller Manager — works continuously to match the current state to the desired state. If the desired state says "5 replicas" but only 3 are running, Kubernetes creates 2 more. If 7 are running but only 5 are desired, Kubernetes deletes 2.
Intuition — the thermostat analogy: Think of Kubernetes as a thermostat in your house. You set the desired temperature to 72°F (desired state). The thermostat continuously checks the actual temperature (current state). If the room drops to 68°F, the heater turns on. If it rises to 74°F, the air conditioner turns on. The thermostat never stops checking and adjusting — it is always reconciling current state with desired state. Kubernetes does the same thing, but for containers instead of temperature.
graph TD
A["YAML Manifest<br/>(Desired State)"] --> B["Control Plane<br/>(Comparison)"]
C["etcd<br/>(Current State)"] --> B
B -->|"Current < Desired"| D["Create Pods"]
B -->|"Current > Desired"| E["Delete Pods"]
B -->|"Current = Desired"| F["No Action"]
D --> C
E --> C
This reconciliation happens continuously. The source of the desired state is the manifest file (YAML), which is typically stored in a Git repository. A CD pipeline (Continuous Deployment tool) — such as Argo CD, Jenkins, or Flux CD — pulls changes from Git and syncs them with the cluster. The default sync interval is 3 minutes (180 seconds), though it can be configured to be nearly continuous.
Worked example — reconciliation in action:
Scenario: You have a deployment with replicas: 3. One pod crashes.
| Step | Current State (etcd) | Desired State (manifest) | Action |
|---|---|---|---|
| 1. Normal operation | 3 pods running | 3 replicas | No action |
| 2. Pod crashes | 2 pods running | 3 replicas | Mismatch detected |
| 3. Controller Manager | 2 pods running | 3 replicas | Create 1 new pod |
| 4. Scheduler assigns | 2 pods + 1 pending | 3 replicas | Assign to worker node |
| 5. Kubelet creates | 3 pods running | 3 replicas | Reconciled |
Total time: typically 10-30 seconds from crash to recovery.
The sync cycle works as follows:
- The CD pipeline pulls the latest manifest file from Git.
- It compares the desired state (from the manifest) with the current state (from etcd).
- It calculates the differences.
- The self-healing mechanism (kubelet, Scheduler, Controller Manager) creates, updates, or deletes pods to reconcile the differences.
This is the "big picture" of how changes flow from a developer's YAML file to running containers in production.
Pitfall — editing the live cluster instead of the manifest: You can use kubectl edit deployment to change the desired state directly in the cluster. However, this is dangerous because the change is not recorded in Git. If someone else applies the old manifest from Git, your change is overwritten. Always update the YAML file in Git first, then apply it.
The professor's key insight: The reconciliation loop is the entire point of Kubernetes. Every component — API Server, Scheduler, Controller Manager, kubelet — exists to support this one idea: continuously compare current state with desired state, and close the gap. If you understand this loop, you understand Kubernetes.
Recap: Kubernetes continuously reconciles the current state (stored in etcd) with the desired state (declared in YAML manifests). If pods crash, Kubernetes creates replacements. If there are too many pods, Kubernetes deletes extras. CD pipelines like Argo CD sync manifest changes from Git to the cluster.
14.11 Deployment Strategies
Hook: You have a new version of your application ready. How do you switch from V1 to V2 without users noticing? If you simply stop V1 and start V2, there will be a gap — users will see errors for a few seconds or minutes. Deployment strategies are the answer: they define how to transition between versions while maintaining availability. There are four standard strategies, each with different trade-offs between risk, cost, and complexity.
Whenever an application is deployed to production, the goal is zero downtime deployment — end users should not experience any interruption when switching from version 1.0 to version 2.0. There are four standard deployment strategies:
| Strategy | Risk | Cost | Rollback Speed | Consistency | Best for |
|---|---|---|---|---|---|
| Basic | High | Low | Slow | 100% consistent | Small apps, dev environments |
| Ramped (Rolling) | Medium | Low | Medium | Temporary inconsistency | Most production workloads |
| Canary | Low | Low | Fast | Partial inconsistency | High-traffic apps, ML models |
| Blue-Green | Low | High | Instant | 100% consistent after switch | Critical systems, banking |
14.11.1 Basic Deployment
In a basic deployment, all nodes are updated simultaneously. If there are 12 nodes running version 1.0, at the switch moment (e.g., 12:02 PM), all 12 nodes are replaced with version 2.0 at the same time.
graph LR
subgraph "Before (12:01 PM)"
A1["Node 1: V1"] --- A2["Node 2: V1"] --- A3["Node 3: V1"]
end
subgraph "After (12:02 PM)"
B1["Node 1: V2"] --- B2["Node 2: V2"] --- B3["Node 3: V2"]
end
A1 -->|"All switch at once"| B1
Success scenario: Version 2.0 works perfectly, and all users seamlessly transition.
Failure scenario: Something goes wrong, and you must roll back (revert) to version 1.0 across all nodes. During the rollback, all users experience errors.
This is an "all or nothing" approach. It is suitable for small applications or services where the risk of simultaneous failure is acceptable and rollback is straightforward.
Scope: Basic deployment is the simplest strategy but the riskiest. Use it only for non-critical applications, development environments, or services where brief downtime is acceptable. Never use it for production systems that serve real users.
14.11.2 Ramped (Rolling Update / Incremental) Deployment
The ramped strategy — also called rolling update or incremental — is the default in Kubernetes. Instead of updating all nodes at once, the new version is introduced one node at a time:
graph TD
subgraph "Step 1: All V1"
A1["Node 1: V1"] --- A2["Node 2: V1"] --- A3["Node 3: V1"] --- A4["Node 4: V1"]
end
subgraph "Step 2: 1 node updated"
B1["Node 1: V2"] --- B2["Node 2: V1"] --- B3["Node 3: V1"] --- B4["Node 4: V1"]
end
subgraph "Step 3: 2 nodes updated"
C1["Node 1: V2"] --- C2["Node 2: V2"] --- C3["Node 3: V1"] --- C4["Node 4: V1"]
end
subgraph "Step 4: All V2"
D1["Node 1: V2"] --- D2["Node 2: V2"] --- D3["Node 3: V2"] --- D4["Node 4: V2"]
end
A1 --> B1 --> C1 --> D1
- Initially, all 4 nodes run V1.
- V2 is introduced to 1 node — 3 nodes still run V1, 1 runs V2.
- After a configurable interval (seconds, minutes), V2 spreads to 2 nodes.
- Then 3 nodes, then all 4 nodes run V2.
The interval between updates is configurable — it can be 5 seconds, 10 seconds, one minute, or any duration. The key characteristic: at any point during the rollout, some users are on V1 and some are on V2. This creates temporary inconsistent behavior, but it is not erroneous — users simply see different versions until the rollout completes.
Q: Would there be inconsistent behavior during a rolling update?
A: Yes, definitely. At any point during the rollout, some users are on V1 and others on V2. This inconsistent behavior is expected and temporary — it is not erroneous. Users simply experience different versions until the rollout completes. After some time, every user transitions to the newer version.
Q: What happens if one of the pod creations fails during a rolling update? Does it stop the remaining pod creations?
A: No, the rollout continues. The kubelet relentlessly works to achieve the desired state. When you change the desired state to 6 new pods, the kubelet keeps creating pods until all 6 are running. If a pod cannot be created at all, that requires exception logging and more advanced error handling — covered in DevOps for Cloud courses — but the rollout does not halt for a single failure.
Worked example — rolling update with nginx:
- Create a deployment with 1 replica:
kubectl create deployment nginx-deploy --image=nginx:1.20 - Scale to 7 replicas:
kubectl edit deployment nginx-deploy(changereplicas: 1toreplicas: 7) - Observe all 7 pods running nginx:1.20.
- Update the image:
kubectl set image deployment/nginx-deploy nginx-container=nginx:1.21 - Kubernetes begins the rolling update:
- Creates 1 new pod with nginx:1.21
- Waits for it to become Ready
- Terminates 1 old pod with nginx:1.20
- Repeats until all 7 pods run nginx:1.21
- During the rollout,
kubectl get podsshows a mix of old and new pods.
Pitfall — rolling updates cause temporary inconsistency: If your application has breaking API changes between V1 and V2, a rolling update will cause errors for users who hit V2 pods while V1 pods are still running. For breaking changes, use blue-green deployment instead (switch all at once after validation).
14.11.3 Canary Deployment
The canary strategy releases a new version to a small subset of users first, observes the results, and then rolls out to everyone if everything goes well.
The professor's real-world example — WhatsApp Meta AI rollout: When Meta AI was introduced in WhatsApp (about 8 months before this lecture), it appeared on some devices but not others. One person had the feature on their phone, but family members did not. After about a week, the feature appeared on all devices. This is classic canary deployment — releasing to a selective set of users first, observing real-world behavior, and then doing a full rollout.
Canary deployments can target users by:
- Geography: Only users in India get the feature first.
- User segments: Identified through clustering and analytics — groups of users who are most likely to respond well to the feature.
- Percentage: Typically 10–25% of users receive the new version initially.
The selection of which users get the canary version is often non-technical — it is driven by marketing analytics, user clustering, and business strategy. Data scientists and analysts identify the target segments before the rollout decision.
Multiple versions simultaneously: Canary deployment supports testing multiple versions at once. V2.1 can be released to one subset, V2.2 to another subset, and V2.3 to yet another. After observing which version performs best, a full rollout of the winning version is executed.
Gradual rollout: Canary deployments often follow a graduated pattern — 1% first, then 5%, then 10%, then 20%, and so on — increasing the percentage as confidence grows.
Traffic splitting: Within canary deployment, traffic routing is configured through Kubernetes Services. The same set of pods can receive different percentages of total traffic — for example, 5% of traffic goes to pods running the new version, and 95% goes to the old version. This is configured in the Service portion of the YAML manifest.
A/B testing connection: Canary deployment is closely related to A/B testing. When you have two versions (A and B) and want to determine which performs better, you can use canary deployment to release each version to a subset of users and measure the results. The version with better metrics gets the full rollout. In day-to-day industry practice, canary and A/B testing are often used interchangeably, though there are subtle differences — canary focuses on safe rollout, while A/B testing focuses on measurement and comparison.
Worked example — canary deployment for an ML model:
Suppose you have an ML model serving predictions via a REST API. You have trained a new version (V2) that you believe is more accurate, but you want to validate it in production before full rollout.
- Current state: 10 pods running V1, receiving 100% of traffic.
- Canary phase 1: Deploy 1 pod running V2. Configure the Service to send 10% of traffic to V2 and 90% to V1.
- Observe: Monitor V2's prediction accuracy, latency, and error rate for 24 hours.
- Decision: If V2 performs as well or better than V1, increase to 50% traffic. If V2 has issues, delete the canary pod and investigate.
- Full rollout: If V2 passes all checks, update all 10 pods to V2 and route 100% of traffic.
14.11.4 Blue-Green Deployment
Blue-green maintains two complete, identical environments:
- Blue (Live): The current production environment running V1.1.
- Green (Staging): An exact replica of the production environment running V1.2.
graph TD
A["Users"] -->|"100% traffic"| B["Blue Environment<br/>(V1.1 — Live)"]
C["Green Environment<br/>(V1.2 — Staging)"]
A -.->|"Switch after validation"| C
The staging environment must have the same number of nodes as the live environment. Users access the live (blue) environment. When the green environment is ready and validated, the users are switched from blue to green in one operation — not gradually, but all at once.
Advantages:
- Rollback is straightforward — if the green environment fails, redirect users back to the blue environment.
- Risk is reduced compared to other strategies because the new version is fully tested in an identical environment before the switch.
- Easy to implement.
Disadvantages:
- Cost and complexity: Maintaining two complete production environments is expensive. For microservices architectures with hundreds or thousands of services, replicating the entire environment doubles infrastructure costs.
- Resource-intensive — you are paying for two full environments simultaneously.
Scope: Blue-green deployment is the safest strategy for critical systems (banking, healthcare, e-commerce) but the most expensive. The cost of maintaining two full environments is justified only when downtime has significant financial or safety consequences.
Quality assurance considerations: The staging environment can be validated using either production data or dummy data. For new applications without much production data, dummy data is used. For established applications with months or years of production data, the staging environment can be tested against real production data. Smoke tests are performed on the staging environment before the switch to ensure the new version is functioning correctly.
The switch is one-time: Users are redirected from one environment to the other in a single operation. It is not gradual like a rolling update.
Pitfall — blue-green is not "better" than rolling update: Each strategy has its place. Blue-green is safest but most expensive. Rolling update is cheapest but causes temporary inconsistency. Canary is best for validating changes with real users. Choose based on your risk tolerance, budget, and consistency requirements.
Recap — the four deployment strategies:
| Strategy | How it works | Key characteristic |
|---|---|---|
| Basic | All nodes switch at once | "All or nothing" — highest risk |
| Ramped (Rolling) | Nodes switch one at a time | Default in K8s; temporary inconsistency |
| Canary | Small subset gets new version first | Validates with real users before full rollout |
| Blue-Green | Two identical environments, instant switch | Safest rollback; most expensive |
The choice depends on your application's criticality, budget, and tolerance for temporary inconsistency. For most production workloads, rolling update is the default. For critical systems, blue-green is preferred. For ML model serving, canary is ideal.
14.12 Critical Services and High Availability
Hook: If your application goes down for even 5 minutes, how much money does your company lose? For Amazon, a 5-minute outage costs approximately 300,000 USD in lost revenue. For banking systems, downtime can violate regulatory requirements. This section explains how to design Kubernetes deployments that stay online even when things go wrong.
14.12.1 Three Principles for Zero Downtime
When designing Kubernetes deployments for critical services that require zero downtime, three principles apply:
Q: How do we configure critical services for zero downtime in Kubernetes?
A: Two things matter. First, create more replicas for critical services — if you only have one instance and it goes down, availability is lost. The thumb rule is a higher replica count so that even if some containers fail, others continue serving traffic. Second, distribute replicas across regions — do not put all worker nodes in one region. If an entire AWS region goes down, all pods in that region are affected. Split replicas across regions so the application remains accessible even if one region fails. Also, separate critical from non-critical services: non-critical services do not need many replicas or cross-region duplication.
Principle 1 — More replicas for critical services: If a critical service has only one instance and it goes down, availability is lost. The thumb rule is to have a higher replica count for critical services so that even if some containers fail, others continue serving traffic.
Principle 2 — Distribute across regions: Do not deploy all worker nodes in the same region. If an entire AWS region (e.g., Tokyo) goes down, all pods in that region are affected. Distribute replicas across multiple regions — for example, 3 replicas in one region, 7 in another. Even if one region's availability zones go down, the application remains accessible.
Principle 3 — Separate critical from non-critical: Non-critical services do not need many replicas or cross-region duplication. Wasting resources on non-critical services is unnecessary. Focus replication and distribution efforts on critical services.
Worked example — designing for a critical payment service:
Suppose you have a payment processing service that handles 10,000 transactions per minute. Here is how you would apply the three principles:
Principle 1 — Replicas: Run at least 5 replicas so that if 2 crash, the remaining 3 can handle the load (each pod handles ~3,300 transactions/minute).
Principle 2 — Cross-region distribution:
- Region us-east-1 (Virginia): 3 replicas
- Region eu-west-1 (Ireland): 2 replicas
- If us-east-1 goes down, eu-west-1 handles all traffic (temporarily at reduced capacity).
Principle 3 — Separation: The payment service is critical → 5 replicas across 2 regions. The notification service is non-critical → 2 replicas in 1 region. No need to waste resources on cross-region notification redundancy.
Q: If a container has code listening to events, do all replicas process the same events?
A: Event handling typically uses a message queue or broker component (like Kafka). That broker is itself containerized and running in a pod. The architecture remains the same — application pods, database pods, ML pods, and broker pods are all containers in Kubernetes. The design is fundamentally stateless unless statefulness is explicitly introduced.
Q: For parallel agent setups (e.g., validation agent → review agent → summary agent), should each agent be in a separate pod or all in one pod?
A: If agents are interrelated and every request must flow through all agents sequentially (validation → review → summary), it may make sense to containerize all agents in a single pod. Then, the replica set can be scaled directly — 10 prompts, 1 million prompts, just increase the replica set. This avoids the complexity of coordinating across separate pods. However, if agents are independent, separate pods with orchestration or choreography patterns are appropriate. This connects to distributed transaction concepts — orchestration (centralized control) versus choreography (event-driven coordination).
Recap: Three principles for zero downtime: (1) more replicas for critical services, (2) distribute replicas across regions, (3) separate critical from non-critical services. Event handling uses containerized message brokers. Multi-agent setups can be single-pod (for sequential pipelines) or multi-pod (for independent agents).
14.13 Stateful vs. Stateless in Kubernetes
Hook: Why does Kubernetes assume applications are stateless? Because when any pod can handle any request, you cannot store session data inside a single pod — if that pod dies, the session data dies with it. This section explains the stateless design philosophy, what to do when you need state, and how industries like banking handle the tension between statefulness and zero-downtime deployments.
14.13.1 Stateless Design and StatefulSets
Kubernetes is designed to be stateless by default. Containers should not maintain application state internally. State — such as database contents, session data, or event queues — should be decoupled from the application containers and stored in separate, dedicated containers or external services.
This design is critical because:
- All pod replicas are treated equally by the Service and kube-proxy.
- Any request can be routed to any replica.
- If a pod dies, its replacement has no knowledge of previous requests.
Intuition — the bank teller analogy: Think of pod replicas as bank tellers. When you walk into a bank, you take a number and go to whichever teller is available. You do not expect the teller to remember your last visit. Your account information (state) is stored in the bank's central database, not in the teller's head. If a teller goes home (pod dies), another teller can serve you because they all read from the same database. This is the stateless design — the tellers (pods) are stateless; the database (external service) holds the state.
For stateful requirements (databases, persistent storage), Kubernetes offers StatefulSets — a different resource type with specialized configurations for maintaining identity, stable network names, and persistent storage across pod restarts. However, maintaining stateful systems is significantly more expensive and complex than stateless ones.
Stateless vs. Stateful — the key difference:
| Aspect | Stateless | Stateful |
|---|---|---|
| Pod identity | Pods are interchangeable | Each pod has a unique, stable identity |
| Session data | Stored externally (Redis, database) | Stored inside the pod |
| Pod replacement | New pod is identical to old | New pod must recover state |
| Scaling | Easy — just add replicas | Complex — must coordinate state |
| Example | REST API, web server | Database (PostgreSQL), message queue (Kafka) |
| K8s resource | Deployment | StatefulSet |
Real-world consideration: In industries like banking, sessions cannot simply be killed during deployments. Banks typically schedule downtime windows (often at night) to perform deployments, blocking new sessions and waiting for active sessions to complete before shutting down. They use a "tail" strategy — stop accepting new sessions, wait a buffer period (e.g., 30 minutes) for active sessions to finish, then perform the deployment.
The professor's key insight — the banking deployment pattern: Banks cannot afford to kill sessions mid-transaction. Their deployment process is: (1) stop accepting new sessions, (2) wait 30 minutes for active sessions to drain, (3) deploy the new version, (4) resume accepting sessions. This is the "tail" strategy — you wait for the "tail" of active sessions to complete before switching.
For stateless APIs, broken sessions are acceptable — the kubelet spawns a new pod, fresh sessions start, and whatever was lost is lost. But for databases and financial transactions, stateful configurations with careful deployment strategies are required.
Pitfall — storing state in pods without planning: A common mistake is storing session data or cache inside a pod without externalizing it. When the pod is replaced (during scaling, deployment, or failure), all that data is lost. Always use external stores (Redis, PostgreSQL, S3) for any data that must survive pod replacement.
Recap: Kubernetes favors stateless design — pods are interchangeable and should not store session data internally. Use external services (databases, caches) for state. StatefulSets exist for genuinely stateful workloads but are complex and expensive. Banks use the "tail" strategy to drain sessions before deploying.
14.14 Auto-Scaling
Hook: You have set your replica count to 5. But what happens on Black Friday when traffic jumps from 1,000 to 1,000,000 requests per second? You cannot manually edit the deployment every time traffic changes. Auto-scaling watches your traffic metrics and adjusts the replica count automatically — adding pods when traffic spikes and removing them when traffic drops.
14.14.1 How Auto-Scaling Works
Auto-scaling is an independent component (provided by cloud platforms like AWS, Azure) that ties into monitoring systems (e.g., AWS CloudWatch). It continuously monitors metrics like the number of concurrent users per second and automatically adjusts the replica set based on configurable rules.
Worked example — auto-scaling rule:
# Horizontal Pod Autoscaler (HPA) rule
minReplicas: 1
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
This rule says: "Keep at least 1 pod, scale up to 20 pods, and add pods when average CPU utilization exceeds 70%."
Scenario:
- Normal traffic: 1 pod, CPU at 30% → no scaling.
- Traffic spike: 1 pod, CPU at 85% → auto-scaler creates 2nd pod.
- Traffic keeps rising: 2 pods, CPU at 80% → auto-scaler creates 3rd pod.
- Traffic drops: 3 pods, CPU at 20% → auto-scaler removes 1 pod.
- Back to normal: 1 pod, CPU at 30%.
Example rule: "If concurrent users per second increases from 1 million to 10 million, create 3 additional replicas." Conversely: "If users decrease, remove the extra pods." The default is always 1 pod — additional pods are created only when demand increases and removed when demand decreases.
The relationship between components:
| Component | What it does | Who controls it? |
|---|---|---|
| Kubelet | Restarts crashed containers | Kubernetes (automatic) |
| Replica Set Controller | Maintains N pod replicas | You (via YAML) |
| Auto-scaler | Adjusts N based on traffic | Cloud platform + monitoring |
The kubelet handles container health. The Replica Set Controller maintains the desired count. The auto-scaler changes the desired count based on traffic metrics. They work at different levels of the stack.
Auto-scaling is not managed by the kubelet. The kubelet handles container health; auto-scaling is a higher-level orchestration driven by monitoring data and configurable rules.
Pitfall — auto-scaling requires resource requests: Auto-scaling works by monitoring CPU/memory utilization. If you do not specify resource requests (e.g., "this pod needs 500m CPU"), the auto-scaler cannot calculate utilization percentages. Always set resource requests in your pod spec for auto-scaling to work.
Recap: Auto-scaling adjusts the replica count based on traffic metrics (CPU, memory, concurrent users). It is a cloud platform feature, not a kubelet feature. Set resource requests in your pod spec for auto-scaling to function correctly.
Exam Guidance Summary
Exam note: This is one of the most important lectures for the exam. Kubernetes architecture and deployment strategies are frequently tested. Focus on understanding the concepts (what each component does) and the relationships (how components work together), not memorizing commands.
High-priority topics:
- Kubernetes architecture — Understand all four control plane components (API Server, Scheduler, Controller Manager, etcd) and what each does. Know the three-tier architecture (client, control plane, worker nodes).
- Abstraction hierarchy — Deployment → Replica Set → Pod → Container. Know that you cannot create a pod directly — only a deployment. Understand that the container is the only physical entity.
- Self-healing loop — Current state (etcd) vs. desired state (YAML manifest). How the reconciliation cycle works. What happens when a pod crashes (kubelet restarts) vs. when a node fails (control plane reschedules).
- Deployment strategies — Be familiar with all four: Basic, Ramped (rolling update), Canary, Blue-Green. Know when each is appropriate. Canary and blue-green are the most commonly discussed in industry.
- YAML manifests — Understand the structure: apiVersion, kind, replicas, containers. Know the difference between
kubectl create deployment(imperative) andkubectl apply -f(declarative).
- Practical commands —
kubectl create deployment,kubectl get pods,kubectl get deployment,kubectl edit deployment,kubectl apply -f,kubectl delete deployment.
- Stateless vs. Stateful — Understand why K8s favors stateless design. Know what StatefulSets are and when to use them. The banking "tail" strategy is a good exam example.
Common exam mistakes:
- Confusing the Scheduler (places pods) with kube-proxy (routes traffic).
- Thinking CrashLoopBackOff means K8s is broken — it means K8s is working correctly.
- Trying to create pods directly with
kubectl create pod— this command does not exist. - Confusing rolling update (gradual) with blue-green (instant switch).
- Forgetting that pods are stateless by design — storing state in pods is an anti-pattern.
Key Industry Applications
These are the real-world tools and platforms that implement the concepts covered in this lecture. Understanding how they connect to the architecture helps you apply this knowledge in practice.
Cloud Kubernetes Services:
- AWS EKS (Elastic Kubernetes Service): Amazon's managed Kubernetes. Uses the same architecture (control plane + worker nodes), but AWS manages the control plane for you.
- Azure AKS (Azure Kubernetes Service): Microsoft's managed Kubernetes. Same architecture, same kubectl commands.
- Google GKE (Google Kubernetes Engine): Google's managed Kubernetes (Google created Kubernetes originally). Same architecture.
Monitoring and Observability:
- Prometheus: An observability/monitoring tool that runs as a container in a pod. It continuously scrapes metrics from application pods on specific ports and stores them as time-series data. Used with Grafana for dashboards.
- AWS CloudWatch: Monitoring tool used for auto-scaling decisions. Tracks CPU, memory, and custom metrics across your cluster.
Event-Driven Architecture:
- Kafka: A distributed message broker, containerized and running in pods. Used for event-driven architectures where microservices communicate through events rather than direct API calls.
Continuous Deployment:
- Argo CD: A GitOps CD tool that pulls manifest changes from Git and syncs them with the cluster. Default sync interval: 3 minutes.
- Jenkins: A general-purpose CI/CD tool that can be configured to deploy to Kubernetes.
- Flux CD: Another GitOps CD tool, lighter weight than Argo CD.
Real-World Deployment Examples:
- WhatsApp Meta AI rollout: A classic canary deployment — the Meta AI feature appeared on some devices first, then gradually expanded to all devices over about a week.
- Banking sector: Uses scheduled downtime windows for deployments due to stateful session requirements. Sessions are drained before deployment using the "tail" strategy — stop accepting new sessions, wait for active sessions to complete, then deploy.
SEML Lecture 14 notes · Kubernetes Architecture and Deployment Strategies
Sections Breakdown
Why Docker alone falls short at scale and how Kubernetes adds orchestration
The three-tier architecture: client, control plane components, and worker nodes
The smallest deployable unit, composition patterns, volumes, and scaling
How the kubelet creates, restarts, and monitors containers; CrashLoopBackOff
How replica sets maintain the desired number of pod instances
Deployments, YAML manifests, and imperative vs declarative creation
Stable service IPs and kube-proxy traffic routing to pods
Running a single-node Kubernetes cluster locally for learning
Container, pod, replica set, and deployment as layers of abstraction
The reconciliation loop between current state and desired state
Basic, rolling, canary, and blue-green deployment strategies
Replicas, cross-region distribution, and separation for zero downtime
Stateless design, StatefulSets, and session draining in banking
Automatic replica adjustment based on traffic metrics
Exam strategy and high-priority revision topics
Real-world tools and platforms implementing the lecture concepts
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
From Docker to Kubernetes — Why Orchestration Is Needed
Must-know: Docker creates and runs containers on one machine; Kubernetes orchestrates containers across many machines. They are complementary, not replacements.
⚠️ Top pitfall: Confusing Docker with Kubernetes — K8s uses Docker as its container runtime, it does not replace it.
Self-check: Name three things Docker cannot do that Kubernetes can.
Connects to: 14.2 Kubernetes Architecture — Control Plane and Worker Nodes, 14.3 Pods — The Smallest Deployable Unit
Kubernetes Architecture — Control Plane and Worker Nodes
Must-know: Know all four control plane components and their roles. API Server is the front door, etcd stores current state, Scheduler places pods, Controller Manager enforces desired state.
⚠️ Top pitfall: Confusing the Scheduler (places new pods) with kube-proxy (routes network traffic to pods).
Self-check: What are the four control plane components and what does each do?
Connects to: 14.3 Pods — The Smallest Deployable Unit, 14.4 The Worker Node and Kubelet — Self-Healing in Action, 14.5 Replica Sets and Scaling
Pods — The Smallest Deployable Unit
Must-know: Pod is the smallest deployable unit. Industry guideline: 1 container per pod. Pods get unique IPs. Volumes persist data across container restarts.
⚠️ Top pitfall: Confusing pod-level volumes (survive container restarts) with PersistentVolumes (survive pod deletion).
Self-check: Why can't you run a container directly in Kubernetes?
Connects to: 14.4 The Worker Node and Kubelet — Self-Healing in Action, 14.5 Replica Sets and Scaling, 14.6 Deployments and YAML Manifests
The Worker Node and Kubelet — Self-Healing in Action
Must-know: Kubelet performs container creation, restart, and health monitoring. CrashLoopBackOff is normal retry behavior with exponential backoff.
⚠️ Top pitfall: Thinking CrashLoopBackOff means Kubernetes is broken — it means K8s is doing its job by retrying. Fix the root cause in your app.
Self-check: What are the three functions of the kubelet?
Connects to: 14.3 Pods — The Smallest Deployable Unit, 14.5 Replica Sets and Scaling
Replica Sets and Scaling
Must-know: Default replica count is 1. Scale with kubectl edit deployment. Replica Set Controller maintains desired count; kubelet creates/destroys containers.
⚠️ Top pitfall: Scaling is not instant — there is a 10-60s delay per pod depending on image size and resources.
Self-check: If you change replicas from 1 to 5, how many new pods are created?
Connects to: 14.4 The Worker Node and Kubelet — Self-Healing in Action, 14.6 Deployments and YAML Manifests
Deployments and YAML Manifests
Must-know: Hierarchy: Deployment → Replica Set → Pod → Container. kubectl apply -f is preferred for production (declarative, version-controlled).
⚠️ Top pitfall: Using imagePullPolicy: Never in production — it prevents pulling from registries.
Self-check: What is the difference between kubectl create deployment and kubectl apply -f?
Connects to: 14.5 Replica Sets and Scaling, 14.7 Kube Proxy and Services — Making Pods Accessible
Kube Proxy and Services — Making Pods Accessible
Must-know: Services provide stable IPs. kube-proxy routes traffic to available pods. All replicas are equal — applications should be stateless.
⚠️ Top pitfall: Hard-coding pod IPs instead of using Service IPs. Pod IPs change when pods are recreated.
Self-check: Why do we need Services if pods already have IP addresses?
Connects to: 14.3 Pods — The Smallest Deployable Unit, 14.13 Stateful vs. Stateless in Kubernetes
Minikube — A Single-Node Cluster for Learning
Must-know: Minikube is for local learning. Must use minikube image load before deploying local images. All kubectl commands work the same as production.
⚠️ Top pitfall: Forgetting minikube image load — pods get stuck in ImagePullBackOff.
Self-check: What is the first command you run after building a Docker image for Minikube?
Connects to: 14.6 Deployments and YAML Manifests, 14.8 Minikube — A Single-Node Cluster for Learning
The Layers of Abstraction in Kubernetes
Must-know: Four layers: Container → Pod → Replica Set → Deployment. No 'kubectl create pod' command exists. Always create Deployments.
⚠️ Top pitfall: Trying to create pods directly. There is no kubectl create pod — you must create a Deployment.
Self-check: What are the four abstraction layers in Kubernetes, from bottom to top?
Connects to: 14.3 Pods — The Smallest Deployable Unit, 14.5 Replica Sets and Scaling, 14.6 Deployments and YAML Manifests
Current State vs. Desired State — The Self-Healing Loop
Must-know: The reconciliation loop is the core of K8s. Current state in etcd, desired state in YAML. CD pipelines (Argo CD, Jenkins, Flux CD) sync changes from Git.
⚠️ Top pitfall: Editing the live cluster with kubectl edit instead of updating the YAML in Git.
Self-check: What happens when the current state has 3 pods but the desired state is 5?
Connects to: 14.2 Kubernetes Architecture — Control Plane and Worker Nodes, 14.4 The Worker Node and Kubelet — Self-Healing in Action, 14.11 Deployment Strategies
Deployment Strategies
Must-know: Know all four strategies: Basic (risky), Rolling (default, temporary inconsistency), Canary (subset first), Blue-Green (two environments, expensive, instant rollback).
⚠️ Top pitfall: Confusing rolling update (gradual) with blue-green (instant switch). Using basic deployment in production.
Self-check: Which deployment strategy maintains two identical environments and switches traffic instantaneously?
Connects to: 14.6 Deployments and YAML Manifests, 14.7 Kube Proxy and Services — Making Pods Accessible, 14.12 Critical Services and High Availability
Critical Services and High Availability
Must-know: Three principles: more replicas, cross-region distribution, critical vs non-critical separation.
⚠️ Top pitfall: Deploying all replicas in a single region — one region outage takes down the entire service.
Self-check: What are the three principles for configuring critical services for zero downtime?
Connects to: 14.5 Replica Sets and Scaling, 14.11 Deployment Strategies
Stateful vs. Stateless in Kubernetes
Must-know: K8s is stateless by default. Use external services for state. StatefulSets for databases. Banking uses session draining (tail strategy).
⚠️ Top pitfall: Storing session data inside pods without externalizing it — lost when pod is replaced.
Self-check: Why does Kubernetes favor stateless application design?
Connects to: 14.3 Pods — The Smallest Deployable Unit, 14.7 Kube Proxy and Services — Making Pods Accessible
Auto-Scaling
Must-know: Auto-scaling watches metrics and adjusts replicas. Different from kubelet (restarts containers) and Replica Set Controller (maintains count).
⚠️ Top pitfall: Not setting resource requests — auto-scaler cannot calculate utilization without them.
Self-check: What is the difference between the kubelet and auto-scaling?
Connects to: 14.5 Replica Sets and Scaling, 14.4 The Worker Node and Kubelet — Self-Healing in Action
Exam Guidance Summary
Must-know: Architecture (4 components), hierarchy (Deployment→Replica Set→Pod→Container), reconciliation loop, 4 deployment strategies, YAML structure.
⚠️ Top pitfall: Confusing Scheduler with kube-proxy. Thinking CrashLoopBackOff means K8s is broken.
Self-check: Name the four control plane components.
Connects to: 14.2 Kubernetes Architecture — Control Plane and Worker Nodes, 14.9 The Layers of Abstraction in Kubernetes, 14.10 Current State vs. Desired State — The Self-Healing Loop, 14.11 Deployment Strategies
Key Industry Applications
Must-know: All major cloud platforms use the same K8s architecture. Prometheus for monitoring, Kafka for events, Argo CD for GitOps.
⚠️ Top pitfall: Confusing monitoring (Prometheus) with auto-scaling (CloudWatch).
Self-check: Name three CD tools that sync manifest changes from Git to the cluster.
Connects to: 14.2 Kubernetes Architecture — Control Plane and Worker Nodes, 14.11 Deployment Strategies, 14.14 Auto-Scaling