LFCE 139 ๐ง Kubernetes โ Deployments
A Deployment is the standard way to run a stateless application on Kubernetes. It does not manage Pods directly. It manages a ReplicaSet, and the ReplicaSet manages the Pods. The Deployment declares the desired stateโthe container image, the number of replicas, the resource limits, and the update strategyโand the Deployment controller continuously reconciles the actual state to match it . When the image changes, the Deployment creates a new ReplicaSet and gradually shifts traffic from the old Pods to the new ones, without downtime. When something goes wrong, it can roll back to the previous ReplicaSet in seconds.
This chapter covers the Deployment abstraction: the hierarchy of Deployment โ ReplicaSet โ Pod, the rolling update strategy and its two parameters (maxSurge and maxUnavailable), the rollback mechanism that makes a bad release recoverable, and the scaling and self-healing behavior that makes a Deployment the production default for stateless workloads.
Key point: Never create a bare Pod in production. A Pod that is deleted or whose node fails is not recreated. A Deployment-managed Pod is replaced automatically by the controller, and the Deployment provides rolling updates and rollbacks that a bare Pod cannot.
Why Deployments exist
The bare Pod problem. A Pod is ephemeral. If it is deleted, if its node fails, or if the container crashes in a way that the kubelet cannot restart, the Pod is gone and nothing brings it back . A Deployment creates a ReplicaSet, and the ReplicaSet watches the Pod count. When a Pod disappears, the ReplicaSet creates a replacement. The Deployment adds the update strategy on top: when the desired state changes, the transition from the old state to the new state is controlled, observable, and reversible.
The update problem. Replacing a running application with a new version requires stopping the old containers and starting the new ones. If all old containers are stopped first, the application is unavailable during the transition. A Deployment’s default strategy is RollingUpdate, which starts new Pods before stopping old ones, keeps a minimum number available, and only retires an old Pod when its replacement passes the readiness probe . The result is zero-downtime deployment.
The recovery problem. A new version can be broken. A container can crash-loop, a readiness probe can fail, or a configuration change can cause errors. The Deployment retains a history of previous ReplicaSets, and kubectl rollout undo scales the previous ReplicaSet back up while scaling the current one down. The rollback is near-instant because the previous ReplicaSet and its Pod template already exist .
a. The Deployment hierarchy and the manifest
The hierarchy is Deployment โ ReplicaSet โ Pod. The Deployment owns one or more ReplicaSets, and each ReplicaSet owns a set of Pods. During a rolling update, two ReplicaSets coexist: the old one being scaled down and the new one being scaled up .
A minimal Deployment manifest declares the image, the replica count, and the selector that matches the Pod template’s labels.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-backend
spec:
replicas: 3
selector:
matchLabels:
app: api-backend
template:
metadata:
labels:
app: api-backend
spec:
containers:
- name: api
image: my-registry/api:v1.2.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
The selector.matchLabels must match template.metadata.labels. If the selector does not match the Pod template, the Deployment will not manage the Pods, and the failure is silent . The readiness probe is what makes a rolling update safe: the Deployment does not count a new Pod as available until the probe succeeds, so traffic is not routed to a container that is not ready .
b. The rolling update strategy
The default strategy is RollingUpdate. It is controlled by two parameters that define the update’s concurrency and availability floor.
maxUnavailable is the maximum number of Pods that can be unavailable during the update. It defaults to 25%. maxSurge is the maximum number of additional Pods that can be created above the desired replica count. It also defaults to 25% .
For a Deployment with four replicas and the default 25%, maxUnavailable rounds down to 1, and maxSurge rounds up to 1. The controller ensures at least three Pods are available while allowing up to five Pods to exist during the transition . The update proceeds by scaling the new ReplicaSet up and the old ReplicaSet down, one Pod at a time within those bounds. An old Pod is not terminated until its replacement is ready.
The alternative strategy is Recreate, which terminates all existing Pods before creating new ones. It is appropriate only when the application cannot run two versions simultaneously, such as a schema migration that is not backward-compatible. It causes downtime .
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
c. Rollback, history, and scaling
The Deployment retains a configurable number of old ReplicaSets, controlled by revisionHistoryLimit (default 10) . Each ReplicaSet corresponds to a revision in kubectl rollout history. The CHANGE-CAUSE column is populated only if the kubernetes.io/change-cause annotation is set; the old --record flag is deprecated .
kubectl rollout undo reverts to the previous revision. --to-revision=N reverts to a specific revision. The rollback scales the old ReplicaSet back up and the current one down. It is near-instant because the old ReplicaSet already exists . The rollback restores the Pod template only. It does not revert ConfigMaps, Secrets, database schema changes, or external state .
Scaling is done through the Deployment, not the ReplicaSet. kubectl scale deployment/api-backend --replicas=5 changes the replica count, and the Deployment passes the change to the ReplicaSet . Changing spec.replicas in the manifest and reapplying it is the declarative approach, which is preferred for version control . A HorizontalPodAutoscaler can adjust the replica count automatically based on CPU or memory utilization, but it requires resource requests to be defined in the manifest .
Complete Example Session
# ============================================
# PART 1: THE DEPLOYMENT MANIFEST
# ============================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-backend
spec:
replicas: 3
selector:
matchLabels:
app: api-backend
template:
metadata:
labels:
app: api-backend
spec:
containers:
- name: api
image: my-registry/api:v1.2.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
# ============================================
# PART 2: APPLY AND OBSERVE
# ============================================
kubectl apply -f deployment.yaml
kubectl get deployments
# NAME READY UP-TO-DATE AVAILABLE
# api-backend 3/3 3 3
kubectl get rs
# NAME DESIRED CURRENT READY
# api-backend-7d8f9c6b5 3 3 3
# ============================================
# PART 3: THE HIERARCHY
# ============================================
kubectl get deploy,rs,pods -l app=api-backend
# Deployment โ ReplicaSet โ Pods
# The Deployment owns the ReplicaSet.
# The ReplicaSet owns the Pods.
# ============================================
# PART 4: TRIGGER A ROLLING UPDATE
# ============================================
kubectl set image deployment/api-backend api=my-registry/api:v1.3.0
# The Deployment creates a new ReplicaSet.
# The old ReplicaSet is scaled down gradually.
# The new ReplicaSet is scaled up gradually.
# ============================================
# PART 5: TRACK THE ROLLOUT
# ============================================
kubectl rollout status deployment/api-backend
# Waiting for deployment "api-backend" rollout to finish:
# 1 out of 3 new replicas have been updated...
# deployment "api-backend" successfully rolled out
# ============================================
# PART 6: ROLLBACK
# ============================================
kubectl rollout undo deployment/api-backend
# The previous ReplicaSet is scaled back up.
# The current ReplicaSet is scaled down.
# ============================================
# PART 7: HISTORY
# ============================================
kubectl rollout history deployment/api-backend
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
# 3 <none>
# ============================================
# PART 8: SCALE
# ============================================
kubectl scale deployment/api-backend --replicas=5
kubectl get deployment api-backend
# READY UP-TO-DATE AVAILABLE
# 5/5 5 5
# ============================================
# PART 9: PAUSE AND RESUME
# ============================================
kubectl rollout pause deployment/api-backend
kubectl set image deployment/api-backend api=my-registry/api:v1.4.0
kubectl rollout resume deployment/api-backend
# ============================================
# PART 10: THE ROLLOUT COMMANDS
# ============================================
# status track progress
# history view revisions
# undo rollback
# restart restart Pods without changing the template
# pause suspend a rollout
# resume continue a paused rollout
The ten parts covered the manifest, apply and observe, the hierarchy, triggering an update, tracking the rollout, rollback, history, scaling, pause/resume, and the rollout command summary.
Quick Reference
The hierarchy
| Object | Responsibility |
|---|---|
| Deployment | Manages ReplicaSets, provides updates and rollbacks |
| ReplicaSet | Maintains the desired Pod count |
| Pod | Runs the containers |
Strategy parameters
| Parameter | Default | Meaning |
|---|---|---|
maxUnavailable | 25% | Maximum Pods unavailable during update |
maxSurge | 25% | Maximum extra Pods above replica count |
revisionHistoryLimit | 10 | Old ReplicaSets retained for rollback |
kubectl rollout commands
| Command | Purpose |
|---|---|
kubectl rollout status deploy/X | Track rollout progress |
kubectl rollout history deploy/X | List revisions |
kubectl rollout undo deploy/X | Rollback to previous |
kubectl rollout undo deploy/X --to-revision=N | Rollback to specific revision |
kubectl rollout restart deploy/X | Restart Pods without changing template |
kubectl rollout pause deploy/X | Suspend rollout |
kubectl rollout resume deploy/X | Resume paused rollout |
Scaling
| Method | Command |
|---|---|
| Imperative | kubectl scale deployment/X --replicas=N |
| Declarative | Change spec.replicas and kubectl apply |
| Automatic | HorizontalPodAutoscaler |
Best Practices
โ Do This:
# Set a readiness probe so rolling updates wait for readiness
readinessProbe:
httpGet:
path: /health
port: 8080 # โ
# Set resource requests so the scheduler can place Pods
resources:
requests: { cpu: 100m, memory: 128Mi } # โ
# Use the declarative approach for scaling
# Change spec.replicas and kubectl apply # โ
# Rollback with rollout undo when a release fails
kubectl rollout undo deployment/api-backend # โ
โ Don’t Do This:
# Create a bare Pod for a long-running service
kubectl run nginx --image=nginx # โ
# Manipulate the ReplicaSet directly
kubectl scale rs/api-backend-7d8f9c6b5 --replicas=5 # โ
# Use Recreate for a stateless app that can run two versions
strategy:
type: Recreate # โ (causes downtime)
# Assume rollback reverts everything
# It reverts the Pod template only # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Deployment does not manage Pods | selector.matchLabels does not match template.labels | Align the selector and the template labels |
| Rolling update stalls | Readiness probe never succeeds | Fix the probe or the application |
| Rollback does not restore the old version | revisionHistoryLimit is too low | Increase the limit |
| Pods stay Pending during update | Insufficient cluster capacity for maxSurge | Reduce maxSurge or add capacity |
| Rollback does not fix the problem | The problem is in a ConfigMap or Secret | Roll back those resources separately |
Real-World Examples
1. Minimal Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: nginx
image: nginx:1.27
2. Rolling update parameters
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
3. Update the image
kubectl set image deployment/web nginx=nginx:1.28
4. Track the rollout
kubectl rollout status deployment/web
5. Rollback
kubectl rollout undo deployment/web
6. Rollback to a specific revision
kubectl rollout undo deployment/web --to-revision=2
7. History
kubectl rollout history deployment/web
8. Scale
kubectl scale deployment/web --replicas=5
9. Restart without changing the template
kubectl rollout restart deployment/web
10. Pause and resume
kubectl rollout pause deployment/web
kubectl rollout resume deployment/web
Visual
The hierarchy
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DEPLOYMENT โ
โ โโโ ReplicaSet (current) โ
โ โโโ Pod 1 โ
โ โโโ Pod 2 โ
โ โโโ Pod 3 โ
โ โโโ ReplicaSet (previous, 0 replicas) โ
โ โ
โ The Deployment owns the ReplicaSets. โ
โ The ReplicaSets own the Pods. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The rolling update
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ROLLING UPDATE โ
โ โ
โ Old ReplicaSet: 3 Pods โ
โ New ReplicaSet: 0 Pods โ
โ โ โ
โ โผ โ
โ New Pod 1 created, waits for readiness โ
โ โ โ
โ โผ โ
โ New Pod 1 ready โโโบ Old Pod 1 terminated โ
โ โ โ
โ โผ โ
โ New Pod 2 created, waits for readiness โ
โ โ โ
โ โผ โ
โ ... until the new ReplicaSet has all replicas โ
โ โ
โ No moment where all Pods are unavailable. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
maxUnavailable and maxSurge
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4 replicas, maxUnavailable: 1, maxSurge: 1 โ
โ โ
โ Minimum available: 3 โ
โ Maximum total: 5 โ
โ โ
โ During update: โ
โ At least 3 Pods available at all times โ
โ At most 5 Pods exist at any moment โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Rollback
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ROLLBACK โ
โ โ
โ Current ReplicaSet: v1.3.0, 3 replicas โ
โ Previous ReplicaSet: v1.2.0, 0 replicas โ
โ โ โ
โ โผ โ
โ kubectl rollout undo โ
โ โ โ
โ โผ โ
โ Current ReplicaSet scaled to 0 โ
โ Previous ReplicaSet scaled to 3 โ
โ โ โ
โ โผ โ
โ Near-instant because the ReplicaSet already exists. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Default strategy | RollingUpdate |
maxUnavailable default | 25% |
maxSurge default | 25% |
| Rollback retention | revisionHistoryLimit (default 10) |
| Rollback command | kubectl rollout undo deployment/X |
| Specific revision | --to-revision=N |
| Scaling | kubectl scale deployment/X --replicas=N |
| Restart without template change | kubectl rollout restart deployment/X |
| Self-healing | ReplicaSet replaces failed Pods |
Key takeaways:
- A Deployment manages ReplicaSets, and a ReplicaSet manages Pods. The Deployment is the object that declares the desired state and controls updates. The ReplicaSet is the object that maintains the Pod count. Never manipulate the ReplicaSet directly; the Deployment orchestrates the transitions .
- The default strategy is
RollingUpdate. It replaces Pods incrementally, keeps a minimum number available, and does not retire an old Pod until its replacement passes the readiness probe.maxUnavailableandmaxSurgecontrol the concurrency and the availability floor . - Rollback is near-instant. The previous ReplicaSet and its Pod template already exist.
kubectl rollout undoscales the old ReplicaSet back up and the current one down.revisionHistoryLimitcontrols how many old ReplicaSets are retained . - Rollback restores the Pod template only. It does not revert ConfigMaps, Secrets, database schema changes, or external state. Those must be rolled back separately .
- Scaling is done through the Deployment.
kubectl scale deployment/X --replicas=Nchanges the replica count, and the Deployment passes the change to the ReplicaSet. Changingspec.replicasin the manifest and reapplying is the declarative approach . - A bare Pod is not a production workload. A Pod that is deleted or whose node fails is not recreated. A Deployment-managed Pod is replaced automatically. The Deployment is the production default for stateless applications .
Remember: A Deployment is the production wrapper around a ReplicaSet, which is the wrapper around Pods. The Deployment declares the desired state, the ReplicaSet maintains the Pod count, and the Pods run the containers. The rolling update strategy is what makes a new version deployable without downtime, and the rollback is what makes a bad version recoverable. The two parameters that control the update are maxUnavailable and maxSurge. The two commands that control the lifecycle are kubectl rollout status and kubectl rollout undo. Never create a bare Pod for a long-running service. Always use a Deployment.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!