KubernetesXV · DeploymentsDeployments
Deployment strategies — Recreate, Rolling, Blue-Green, Canary
What you'll learn
- Distinguish Recreate and RollingUpdate strategies
- Implement blue-green deploys using Deployments and Services
- Implement canary deploys using label selectors and Service weights
- Reason about when each strategy is the right choice
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
The Deployment’s strategy field offers two options
(Recreate, RollingUpdate); production teams often need
additional patterns (blue-green, canary). This lesson
covers the built-in strategies and the patterns that go
beyond.
The built-in strategies
strategy:
type: Recreate
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
Two strategies:
- Recreate: the Deployment scales the old ReplicaSet to 0 (terminating all old Pods), waits for termination, then creates the new ReplicaSet at the desired replicas. Result: downtime during the rollout.
- RollingUpdate: the Deployment scales up the new ReplicaSet while scaling down the old. Result: no downtime (assuming enough capacity and the right maxSurge/maxUnavailable).
gantt
title Recreate strategy
dateFormat X
section Old Pods
Old running :a1, 0, 5s
Old terminating :a2, 5, 5s
section New Pods
New pending :b1, 0, 5s
New pending :b2, 5, 5s
New running :b3, 10, 5s
gantt
title RollingUpdate strategy
dateFormat X
section Old Pods
Old :a1, 0, 10s
section New Pods
New :b1, 5, 10s
For most production stateless workloads, RollingUpdate is the right choice. Recreate is appropriate when:
- The workload cannot run two versions concurrently (database migrations, schema changes).
- The new version requires resources only available after the old version is gone.
- Brief downtime is acceptable (dev environments, batch workloads).
Blue-green deploys
A blue-green deploy uses two Deployments: blue (current
production) and green (new version). A Service selects
one or the other; switching the cutover is a Service
selector change.
# Blue Deployment (current production)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-blue
spec:
replicas: 3
selector:
matchLabels:
app: web
version: blue
template:
metadata:
labels:
app: web
version: blue
spec:
containers:
- name: nginx
image: nginx:1.27.2
---
# Green Deployment (new version, scaled up but not selected)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-green
spec:
replicas: 3
selector:
matchLabels:
app: web
version: green
template:
metadata:
labels:
app: web
version: green
spec:
containers:
- name: nginx
image: nginx:1.27.3
---
# Service selects blue
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
version: blue # change to 'green' to cutover
ports:
- port: 80
The cutover:
# Update Service to select green
kubectl patch service web -p '{"spec":{"selector":{"version":"green"}}}'
The Service’s Endpoints controller updates the Endpoints list immediately. Traffic shifts to green; blue keeps running (in case rollback is needed).
sequenceDiagram
participant U as User
participant S as Service
participant B as Blue Deployment
participant G as Green Deployment
U->>G: deploy green (3 replicas, not selected)
G-->>U: green Pods running, not serving traffic
U->>S: change selector to green
S->>G: route traffic to green
Note over B: blue still running (rollback target)
U->>B: if green fails, change selector back to blue
Blue-green trade-offs:
- Pros: instant cutover; easy rollback; full pre-production validation (green can be smoke-tested before cutover).
- Cons: 2x capacity during deploy (both blue and green running); more complex to manage.
Canary deploys
A canary deploy gradually rolls out the new version to a small fraction of traffic, then increases the fraction if the new version is healthy.
# Stable Deployment (90% of traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-stable
spec:
replicas: 9 # 90% of 10
selector:
matchLabels:
app: web
track: stable
template:
metadata:
labels:
app: web
track: stable
spec:
containers:
- name: nginx
image: nginx:1.27.2
---
# Canary Deployment (10% of traffic)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-canary
spec:
replicas: 1 # 10% of 10
selector:
matchLabels:
app: web
track: canary
template:
metadata:
labels:
app: web
track: canary
spec:
containers:
- name: nginx
image: nginx:1.27.3
---
# Service selects both (all versions)
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # matches both stable and canary
ports:
- port: 80
The Service’s Endpoints list includes both stable and canary Pods. Traffic is split based on replica count (round-robin): 9 stable + 1 canary = 90/10 split.
flowchart LR
Service[Service: web] --> Stable[9 stable Pods<br/>nginx 1.27.2]
Service --> Canary[1 canary Pod<br/>nginx 1.27.3]
The canary progression:
# 1. Deploy canary (1 replica, 10% traffic)
kubectl apply -f web-canary.yaml
# 2. Monitor canary metrics (error rate, latency)
# If healthy, increase canary:
# 3. Scale canary to 3 replicas (30% traffic)
kubectl scale deployment/web-canary --replicas=3
# 4. Continue monitoring; scale to 5, 7, 10
kubectl scale deployment/web-canary --replicas=5
# 5. When canary is 100%, retire stable
kubectl scale deployment/web-stable --replicas=0
kubectl scale deployment/web-canary --replicas=10
# 6. Rename canary to stable (or remove the canary label)
Canary trade-offs:
- Pros: gradual rollout; rollback is easy (scale canary to 0); risk is bounded by the canary’s traffic share.
- Cons: more complex; requires monitoring; traffic splitting is approximate (depends on replica counts).
For more sophisticated traffic splitting (e.g., 5% canary), use a service mesh (Istio, Linkerd) or a load balancer that supports weighted routing.
A/B testing
A/B testing is similar to canary but for feature comparison rather than safe rollout:
# Two Deployments, each with a different version
# Service selects both
# Users are routed to one or the other based on a cookie or
# header (requires a service mesh or ingress controller)
A/B testing requires:
- A service mesh (Istio VirtualService with weight, Linkerd TrafficSplit).
- Or an ingress controller with weighted routing (NGINX, Traefik).
Without these, A/B testing is the same as canary (round-robin via replica count).
Production patterns
Default: RollingUpdate with strict settings:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0% # never lose capacity
Stateful workload with schema change: Recreate:
strategy:
type: Recreate
Accept the downtime for safe schema transitions.
High-stakes change: blue-green:
Two Deployments, instant cutover via Service selector. Rollback by switching the selector back.
Gradual rollout: canary:
Two Deployments with different track labels. Service
selects both; traffic split by replica count. Monitor and
scale.
Choosing the right strategy
| Strategy | Use case | Trade-off |
|---|---|---|
| RollingUpdate | Default for stateless | Zero-downtime if configured right |
| Recreate | Stateful with schema change | Downtime required |
| Blue-green | High-stakes change | 2x capacity; instant cutover |
| Canary | Gradual rollout; risk-averse | More complex; approximate split |
For most production stateless workloads, RollingUpdate is the right choice. Blue-green and canary are for high-stakes or risk-averse deployments.
Cross-course references
- The Docker course part
XXXIV-Docker-Productioncovers blue-green and canary deploys at the container level; Kubernetes Deployments implement the same patterns. - The Ansible course part
XXXV-Ansible-Scriptingcovers rolling restarts; Deployments are the cluster-level equivalent. - The Observability course part
LXXXV-Kubernetes-Observabilitycovers metrics that drive canary decisions (error rate, latency).
Quiz
Knowledge check · 4 questions
Q1. Which deployment strategy causes downtime during the rollout?
Q2. A canary Deployment with 1 replica and a stable Deployment with 9 replicas sends exactly 10% of traffic to the canary.
Q3. A team uses blue-green for a high-stakes deploy. The Service selector is changed to green. Traffic immediately shifts. Some users report errors. Walk through the rollback.
Blue Deployment: `web-blue` (v1, current production). Green Deployment: `web-green` (v2, new). Service selector changed from blue to green. Within 5 minutes, error rate on green is 5% (vs 0.1% on blue). The team needs to roll back.
Q4. When is blue-green deploy the right choice over RollingUpdate?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Default to RollingUpdate for stateless workloads. The simplest zero-downtime strategy.
- Use Recreate only when two versions cannot coexist. Stateful schema changes, resource-constrained clusters.
- Blue-green for high-stakes deploys. Instant cutover, easy rollback; costs 2x capacity.
- Canary for gradual rollout. Monitor and scale; approximate traffic split.
- Test the strategy in staging. A team that has never tested blue-green will struggle during an incident.