Kubernetes Deployment Strategies: Rolling, Canary, and Blue-Green
Introduction
Deploying to production is the moment of maximum risk. The wrong strategy can mean downtime, degraded performance, or a frantic rollback at 2am. Kubernetes gives you three primary deployment strategies, each with different risk profiles, rollback speeds, and resource costs.
Strategy 1: Rolling Update (Default)
Gradually replaces old pods with new ones. Zero downtime. Low resource overhead.
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 6
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # At most 8 pods running during update
maxUnavailable: 1 # At most 1 pod unavailable at any time
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: ghcr.io/myorg/api:v2.1.0
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
The readinessProbe is critical — Kubernetes won't route traffic to new pods until they pass, preventing downtime from slow-starting containers.
Rollback:
kubectl rollout undo deployment/api-server
kubectl rollout status deployment/api-server
Strategy 2: Blue-Green Deployment
Run two identical environments — blue (current) and green (new). Switch traffic instantly.
# Blue deployment (currently serving traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-blue
spec:
replicas: 4
selector:
matchLabels:
app: api
version: blue
template:
metadata:
labels:
app: api
version: blue
spec:
containers:
- name: api
image: ghcr.io/myorg/api:v1.9.0
---
# Green deployment (new version, not yet live)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-green
spec:
replicas: 4
selector:
matchLabels:
app: api
version: green
template:
metadata:
labels:
app: api
version: green
spec:
containers:
- name: api
image: ghcr.io/myorg/api:v2.0.0
---
# Service — switch version label to flip traffic
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
version: blue # Change to 'green' to flip
ports:
- port: 80
targetPort: 3000
# Run smoke tests on green
kubectl port-forward deployment/api-green 3000:3000
# Flip traffic (instant, zero downtime)
kubectl patch service api-service -p '{"spec":{"selector":{"version":"green"}}}'
# If something goes wrong — instant rollback (seconds, not minutes)
kubectl patch service api-service -p '{"spec":{"selector":{"version":"blue"}}}'
Cost: Double the resources while both environments run.
Strategy 3: Canary Release
Send a small percentage of real traffic to the new version. Observe metrics. Gradually increase.
# Stable deployment: 9 pods = ~90% of traffic
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-stable
spec:
replicas: 9
template:
metadata:
labels:
app: api
track: stable
spec:
containers:
- name: api
image: ghcr.io/myorg/api:v1.9.0
---
# Canary deployment: 1 pod = ~10% of traffic
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-canary
spec:
replicas: 1
template:
metadata:
labels:
app: api
track: canary
spec:
containers:
- name: api
image: ghcr.io/myorg/api:v2.0.0
---
# Single service routes to both — traffic split is proportional to replica count
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api # Matches both stable and canary pods
With Argo Rollouts you can automate the canary progression based on Prometheus metrics:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 10m } # Observe metrics
- setWeight: 30
- pause: { duration: 10m }
- setWeight: 60
- pause: { duration: 10m }
- setWeight: 100
analysis:
templates:
- templateName: error-rate
args:
- name: service-name
value: api-service
Decision Matrix
| Strategy | Risk | Rollback Speed | Resource Cost | Best For |
|---|---|---|---|---|
| Rolling | Medium | ~5 min | 1x | Most deployments |
| Blue-Green | Low | Instant | 2x | Breaking changes, DB migrations |
| Canary | Very Low | Instant | 1.1x | High-traffic, risky changes |
Conclusion
Use rolling updates for routine deployments, blue-green when you have database migrations or breaking API changes, and canary when you want real-traffic validation before full rollout. The readinessProbe is the single most important thing to get right — without it, all three strategies can cause downtime.