KubernetesXV · DeploymentsDeployments
Deployment anatomy and ReplicaSet — the controller chain
What you'll learn
- Explain the controller chain Deployment -> ReplicaSet -> Pod
- Distinguish Deployment from ReplicaSet and StatefulSet
- Read the Deployment's ReplicaSet and Pod history
- Reason about why Deployments are the right abstraction for stateless workloads
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
A Deployment is the standard controller for stateless workloads. It manages ReplicaSets, which manage Pods. This lesson explains the controller chain, the Deployment API, and why Deployments are the right abstraction for most production workloads.
The controller chain
flowchart LR
User[Operator] -->|apply| Dep[Deployment]
Dep -->|creates| RS1[ReplicaSet 1<br/>revision: old]
Dep -->|creates| RS2[ReplicaSet 2<br/>revision: new]
RS1 -->|manages| Pod1[Pod]
RS1 -->|manages| Pod2[Pod]
RS2 -->|manages| Pod3[Pod]
RS2 -->|manages| Pod4[Pod]
Three layers:
- Deployment: declarative spec (image, replicas, strategy). Manages ReplicaSets.
- ReplicaSet: maintains a stable set of Pods at the desired replicas. Manages Pods.
- Pod: the actual workload.
The Deployment creates ReplicaSets; each ReplicaSet manages Pods. When you update the Deployment’s image, the Deployment creates a new ReplicaSet; the old ReplicaSet is scaled down.
A Deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: team-a-prod
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27.2
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
The fields:
replicas: desired number of Pods.selector: labels that identify the Pods this Deployment owns.strategy: how to roll out changes (RollingUpdate or Recreate).template: the Pod spec; the Deployment creates ReplicaSets that manage Pods from this template.
How a Deployment works
The Deployment controller:
- Reads the Deployment’s spec (replicas, image, strategy).
- Compares to the current state (existing ReplicaSets and their Pods).
- Creates new ReplicaSets or scales existing ones to match the spec.
- Each ReplicaSet maintains its Pod count at the desired level (via Pod creation/deletion).
sequenceDiagram
participant D as Deployment controller
participant RS as ReplicaSet controller
participant K as Kubelet
D->>D: observe spec (3 replicas, image v2)
D->>RS: create new RS with image v2
D->>RS: scale old RS to 0
RS->>K: create 3 Pods with image v2
K-->>RS: Pods running
The Deployment controller and the ReplicaSet controller both observe and reconcile. The Deployment owns ReplicaSets; the ReplicaSet owns Pods.
Reading the Deployment status
kubectl get deployment web -o yaml
Output (status section):
status:
replicas: 3
updatedReplicas: 3
readyReplicas: 3
availableReplicas: 3
unavailableReplicas: 0
conditions:
- type: Available
status: "True"
- type: Progressing
status: "True"
reason: NewReplicaSetAvailable
The status fields:
replicas: total Pods (old + new).updatedReplicas: Pods at the latest spec.readyReplicas: Pods that are Ready.availableReplicas: Pods that are Ready for at leastminReadySeconds(default 0).conditions: Available, Progressing, ReplicaFailure.
Rolling updates
The Deployment’s strategy field controls how updates roll
out:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
maxSurge: how many Pods can be created above the desired replicas during the rollout.maxUnavailable: how many Pods can be unavailable during the rollout.
For 3 replicas with maxSurge: 25%, maxUnavailable: 25%:
- The rollout can scale up to 4 (3 + surge of 25% = 1).
- The rollout can scale down to 2 (3 - unavailable of 25% = 1).
The Deployment rolls forward by creating new Pods and deleting old Pods in steps, respecting the surge and unavailable constraints.
Deployment vs ReplicaSet vs StatefulSet
| Deployment | ReplicaSet | StatefulSet | |
|---|---|---|---|
| Use case | Stateless | Low-level | Stateful |
| Rollout strategy | Yes | No | Yes (ordered) |
| Revision history | Yes | No | Yes |
| Stable network identity | No | No | Yes (per Pod) |
| Stable storage | No | No | Yes (per Pod) |
For most production stateless workloads, Deployment is the right choice. For stateful workloads (databases, message queues with stable identity), StatefulSet. For node-wide workloads (log shippers, monitoring agents), DaemonSet.
Production patterns
Stateless web service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 5
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27.2
Deployment with anti-affinity for high availability:
spec:
replicas: 5
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: web
The Pods prefer to be on different nodes (anti-affinity). Combined with multiple replicas, the Deployment survives node failures.
Cross-course references
- The Linux course part
XXXVII-Linux-Resourcescovers process management; Deployments are the cluster-level equivalent of long-running services. - The Ansible course part
XXXV-Ansible-Scriptingcovers service configuration; Deployments are the cluster-level equivalent. - The Docker course part
XXXIV-Docker-Productioncovers container orchestration; Deployments are the cluster-level extension.
Quiz
Knowledge check · 4 questions
Q1. In what order does the Deployment controller chain work?
Q2. It is acceptable to manage Pods directly via a ReplicaSet for production stateless workloads.
Q3. A Deployment's rollout has been `Progressing=False` for 30 minutes. The Deployment has 3 replicas, all at the old version. The rollout image change should have created a new ReplicaSet. Diagnose.
Deployment `web` has `Progressing=False` for 30 minutes. `kubectl rollout status deployment/web` shows `deployment "web" successfully rolled out` — but only the old version. The Deployment's image was updated to v2 yesterday; no new ReplicaSet exists.
Q4. Why is a Deployment the right abstraction for production stateless workloads?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Always use Deployments for stateless workloads. Not bare ReplicaSets or direct Pods.
- Read
status.conditions[].type=Availablefor production readiness. This is the signal that the Deployment is fully rolled out. - Configure
strategydeliberately.maxSurgeandmaxUnavailableshould be sized for the workload’s tolerance. - Use podAntiAffinity for high availability. Spread Pods across nodes; combined with multiple replicas.
- Audit Deployment history regularly.
kubectl rollout history deployment/webshows what changed and when.