Kubernetes Deployment Strategies: Rolling, Blue-Green, and Canary Explained
When you push a new version of your app, how it gets deployed matters. The wrong strategy means downtime, or worse — breaking production for all users.
Here are the three main strategies and when to use each.
1. Rolling Deployment (Kubernetes Default)
Gradually replaces old pods with new ones. At any point, some pods run the old version and some run the new.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # At most 1 pod down at a time
maxSurge: 1 # At most 1 extra pod during update
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v2
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
Pros: Simple, zero downtime, built-in
Cons: Both versions run simultaneously (can cause issues if DB schema changes are incompatible)
Use when: Backward-compatible changes, standard deploys
2. Blue-Green Deployment
Run two identical environments (blue = current, green = new). Switch traffic atomically when green is ready.
# Blue deployment (current)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-blue
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: blue
template:
metadata:
labels:
app: my-app
version: blue
spec:
containers:
- name: my-app
image: my-app:v1
---
# Service points to blue initially
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
version: blue # Switch to "green" to cut over
ports:
- port: 80
targetPort: 3000
Deploy green:
kubectl apply -f green-deployment.yaml
# Wait for green to be healthy
kubectl wait --for=condition=available deployment/my-app-green --timeout=120s
# Switch traffic (edit service selector)
kubectl patch service my-app -p '{"spec":{"selector":{"version":"green"}}}'
# Verify
kubectl rollout status deployment/my-app-green
# If good: delete blue
# If bad: switch back immediately
kubectl patch service my-app -p '{"spec":{"selector":{"version":"blue"}}}'
Pros: Instant cutover, instant rollback, no mixed versions
Cons: Requires double the resources during transition
Use when: Major changes, DB migrations, when you need instant rollback
3. Canary Deployment
Route a small percentage of traffic to the new version. Gradually increase if metrics look good.
# Canary: 1 replica vs 9 stable = 10% canary traffic
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-canary
spec:
replicas: 1 # 1 out of 10 total = 10%
selector:
matchLabels:
app: my-app
track: canary
template:
metadata:
labels:
app: my-app
track: canary
spec:
containers:
- name: my-app
image: my-app:v2 # New version
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-stable
spec:
replicas: 9 # 9 out of 10 = 90%
selector:
matchLabels:
app: my-app
track: stable
# Monitor canary error rate
kubectl logs -l track=canary --since=10m | grep ERROR | wc -l
# If good, increase canary replicas
kubectl scale deployment my-app-canary --replicas=5
kubectl scale deployment my-app-stable --replicas=5
# When confident: full rollout
kubectl scale deployment my-app-canary --replicas=10
kubectl scale deployment my-app-stable --replicas=0
Pros: Real production traffic testing, limits blast radius
Cons: Complex, both versions must coexist
Use when: High-risk changes, performance-sensitive updates
Quick Decision Guide
| Scenario | Strategy |
|---|---|
| Normal feature deploy | Rolling |
| DB schema change | Blue-Green |
| Performance-sensitive change | Canary |
| Emergency hotfix | Blue-Green (fast rollback) |
| A/B testing | Canary |
I built ARIA to solve exactly this.
Try it free at step2dev.com — no credit card needed.
Top comments (0)