Day 4: ReplicaSets and Deployments
What You'll Learn Today
- How ReplicaSets maintain Pod redundancy
- Managing applications with Deployments
- Rolling updates and rollbacks
- Basic scaling operations
Why Not Create Pods Directly?
In Day 3, we created Pods directly. In production, you almost never do this.
| Problem | Description |
|---|---|
| Single point of failure | One Pod means service outage on failure |
| No self-healing | Directly created Pods don't come back when deleted |
| No scaling | Must manually create Pods one by one |
| Difficult updates | Application updates cause downtime |
ReplicaSets and Deployments solve these problems.
flowchart TB
DEP["Deployment"] --> RS["ReplicaSet"]
RS --> P1["Pod 1"]
RS --> P2["Pod 2"]
RS --> P3["Pod 3"]
style DEP fill:#8b5cf6,color:#fff
style RS fill:#3b82f6,color:#fff
style P1 fill:#22c55e,color:#fff
style P2 fill:#22c55e,color:#fff
style P3 fill:#22c55e,color:#fff
ReplicaSet
A ReplicaSet ensures a specified number of Pod replicas are always running.
How ReplicaSets Work
flowchart LR
RS["ReplicaSet\nreplicas: 3"] -->|"monitor"| CHECK{"Current Pod count?"}
CHECK -->|"2 (too few)"| CREATE["Create 1 Pod"]
CHECK -->|"3 (correct)"| OK["Do nothing"]
CHECK -->|"4 (too many)"| DELETE["Delete 1 Pod"]
CREATE --> RS
OK --> RS
DELETE --> RS
style RS fill:#3b82f6,color:#fff
style CREATE fill:#22c55e,color:#fff
style DELETE fill:#ef4444,color:#fff
ReplicaSet YAML
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
| Field | Description |
|---|---|
replicas |
Number of Pods to maintain |
selector |
Label selector to identify managed Pods |
template |
Template for creating Pods |
Important:
selector.matchLabelsandtemplate.metadata.labelsmust match.
Self-Healing in Action
# Create ReplicaSet
kubectl apply -f web-rs.yaml
# Check Pods (3 running)
kubectl get pods
# Delete one Pod
kubectl delete pod web-rs-abc12
# A new Pod is created immediately!
kubectl get pods
# web-rs-xyz78 appears with AGE: 5s
Deployment
In practice, you use Deployments instead of creating ReplicaSets directly. Deployments manage ReplicaSets and provide rolling updates and rollbacks.
Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
Creating and Verifying
# Create Deployment
kubectl apply -f web-deployment.yaml
# Check Deployments
kubectl get deployments
# ReplicaSet is auto-created
kubectl get replicasets
# 3 Pods running
kubectl get pods
flowchart TB
D["Deployment\nweb-deployment"] --> RS["ReplicaSet\nweb-deployment-7f8b9c6d4"]
RS --> P1["Pod\nweb-deployment-7f8b9c6d4-abc12"]
RS --> P2["Pod\nweb-deployment-7f8b9c6d4-def34"]
RS --> P3["Pod\nweb-deployment-7f8b9c6d4-ghi56"]
style D fill:#8b5cf6,color:#fff
style RS fill:#3b82f6,color:#fff
Rolling Updates
The biggest advantage of Deployments is zero-downtime application updates.
Performing an Update
# Update the image
kubectl set image deployment/web-deployment web=nginx:1.27-alpine
# Or edit YAML and apply
kubectl apply -f web-deployment.yaml
# Watch the rollout progress
kubectl rollout status deployment/web-deployment
Rolling Update Flow
flowchart TB
subgraph Step1["Step 1"]
RS1a["Old ReplicaSet\n(3 Pods)"]
RS2a["New ReplicaSet\n(0 Pods)"]
end
subgraph Step2["Step 2"]
RS1b["Old ReplicaSet\n(2 Pods)"]
RS2b["New ReplicaSet\n(1 Pod)"]
end
subgraph Step3["Step 3"]
RS1c["Old ReplicaSet\n(1 Pod)"]
RS2c["New ReplicaSet\n(2 Pods)"]
end
subgraph Step4["Step 4"]
RS1d["Old ReplicaSet\n(0 Pods)"]
RS2d["New ReplicaSet\n(3 Pods)"]
end
Step1 --> Step2 --> Step3 --> Step4
style RS1a fill:#f59e0b,color:#fff
style RS1b fill:#f59e0b,color:#fff
style RS1c fill:#f59e0b,color:#fff
style RS1d fill:#f59e0b,color:#fff
style RS2a fill:#22c55e,color:#fff
style RS2b fill:#22c55e,color:#fff
style RS2c fill:#22c55e,color:#fff
style RS2d fill:#22c55e,color:#fff
Update Strategy Configuration
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Extra Pods allowed during update
maxUnavailable: 1 # Pods that can be unavailable during update
| Parameter | Description | Default |
|---|---|---|
maxSurge |
Pods allowed beyond replicas (count or %) | 25% |
maxUnavailable |
Pods that can be unavailable (count or %) | 25% |
Rollbacks
If an update causes issues, easily revert to a previous version.
# View rollout history
kubectl rollout history deployment/web-deployment
# Details of a specific revision
kubectl rollout history deployment/web-deployment --revision=2
# Rollback to previous version
kubectl rollout undo deployment/web-deployment
# Rollback to specific revision
kubectl rollout undo deployment/web-deployment --to-revision=1
# Pause/resume rollout
kubectl rollout pause deployment/web-deployment
kubectl rollout resume deployment/web-deployment
Scaling
Manual Scaling
# Change replica count
kubectl scale deployment/web-deployment --replicas=5
# Verify
kubectl get deployment web-deployment
Scaling via YAML
spec:
replicas: 5 # Changed from 3 to 5
kubectl apply -f web-deployment.yaml
Complete Deployment Example
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
version: v1.0
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5
| Setting | Value | Meaning |
|---|---|---|
replicas: 3 |
3 | Always maintain 3 Pods |
maxSurge: 1 |
1 | Allow up to 4 Pods during updates |
maxUnavailable: 0 |
0 | Zero downtime during updates |
Summary
| Concept | Description |
|---|---|
| ReplicaSet | Maintains a specified number of Pod replicas |
| Deployment | Manages ReplicaSets with rolling updates and rollbacks |
| Rolling Update | Gradually updates Pods for zero downtime |
| Rollback | Reverts to a previous version when issues arise |
| Scaling | Adjusts the number of Pod replicas |
Key Takeaways
- In production, use Deployments instead of creating Pods directly
- Rolling updates enable zero-downtime application updates
- Setting
maxUnavailable: 0ensures service continuity during updates
Practice Exercises
Exercise 1: Basics
Create a Deployment YAML with:
- Name:
api-server - Image:
node:20-alpine - Replicas: 3
- CPU request: 200m, limit: 500m
Exercise 2: Updates
Update the Deployment image to node:22-alpine, watch the rollout, then perform a rollback.
Challenge
Compare the behavior of maxSurge: 0, maxUnavailable: 1 vs. maxSurge: 1, maxUnavailable: 0 during updates.
References
Next up: In Day 5, you'll learn about "Networking with Services" β managing Pod-to-Pod communication and external access through Services.