Skip to content

Kubernetes Deployment Strategies

Advanced deployment strategies for zero-downtime updates, testing, and rollback capabilities in Kubernetes.


Rolling Update (Default, Zero Downtime)

Gradually replace old pods with new ones while maintaining availability.

Initial: [v1] [v1] [v1]  (3 replicas)

Step 1:  [v2] [v1] [v1]  (1 updated)
Step 2:  [v2] [v2] [v1]  (2 updated)
Step 3:  [v2] [v2] [v2]  (complete)

Pros: ✅ Zero downtime, automatic rollback on failure
Cons: ❌ Brief mixed versions, no instant cutover
Time: 3-10 minutes typical

Configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1              # Allow 1 extra pod (total 4)
      maxUnavailable: 0        # Keep all pods ready (zero downtime)
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:v2.0
      # Readiness probe ensures pod is healthy before traffic
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 5

Kubectl commands:

kubectl apply -f deployment.yaml           # Trigger update
kubectl rollout status deployment/app      # Watch progress
kubectl rollout history deployment/app     # See all versions
kubectl rollout undo deployment/app        # Rollback to previous
kubectl rollout undo deployment/app --to-revision=3  # Rollback to specific


Blue-Green Deployment (Instant Cutover)

Maintain two identical production environments and switch instantly between them.

Blue (v1):   [v1] [v1] [v1]  (production, receiving traffic)
Green (v2):  [v2] [v2] [v2]  (staging, fully deployed, no traffic)

Testing on green...
All checks pass...

Switch traffic: Service.selector points from blue → green
Result: Instant cutover, blue still running for instant rollback

Pros: ✅ Instant cutover, instant rollback, binary switch
Cons: ❌ 2x resources during deployment, no gradual testing
Time: Instant switch, 2x resource footprint

Implementation:

# Blue Deployment (v1.0)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: blue
  template:
    metadata:
      labels:
        app: myapp
        version: blue
    spec:
      containers:
      - name: app
        image: myapp:v1.0
        ports:
        - containerPort: 8080

---

# Green Deployment (v2.0)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: app
        image: myapp:v2.0
        ports:
        - containerPort: 8080

---

# Service: Points to blue (production)
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
    version: blue    # Change to "green" to switch traffic
  ports:
  - port: 80
    targetPort: 8080

Workflow:

# 1. Deploy green (v2.0), but service still points to blue
kubectl apply -f app-green.yaml

# 2. Run integration tests against green
kubectl port-forward deployment/app-green 8080:8080
# Test against localhost:8080

# 3. If tests pass, switch traffic to green
kubectl patch service app-service -p '{"spec":{"selector":{"version":"green"}}}'

# 4. If issues detected, instant rollback to blue
kubectl patch service app-service -p '{"spec":{"selector":{"version":"blue"}}}'

# 5. Keep blue running for N hours (or days), then delete
kubectl delete deployment app-blue

Advantages over Rolling Update: - ✅ Zero risk: complete green environment tested before switch - ✅ Instant rollback if production issues - ✅ No mixed versions during update


Canary Deployment (Gradual Traffic Shift)

Gradually shift traffic from old to new version while monitoring metrics.

Initial: [v1: 95%] ← 95% of traffic
         [v2: 5%]  ← 5% of traffic (canary - small test group)

Monitor error rate, latency...
If good:
  Step 1:  [v1: 80%, v2: 20%]
  Step 2:  [v1: 50%, v2: 50%]
  Step 3:  [v1: 0%, v2: 100%]  ← Complete

If error rate > threshold:
  Automatic rollback: [v1: 100%, v2: 0%]

Pros: ✅ Gradual rollout, detect issues early with real traffic
Cons: ❌ Requires service mesh or traffic splitting tool, 1-2 hour rollout
Time: 30-120 minutes typical

Simple Canary (without Service Mesh):

# Deploy both versions
# v1 has 95% of replicas, v2 has 5%
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v1
spec:
  replicas: 19        # 95% traffic (19 out of 20)
  selector:
    matchLabels:
      app: myapp
      version: v1
  template:
    metadata:
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: app
        image: myapp:v1.0

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-v2
spec:
  replicas: 1         # 5% traffic (1 out of 20)
  selector:
    matchLabels:
      app: myapp
      version: v2
  template:
    metadata:
      labels:
        app: myapp
        version: v2
    spec:
      containers:
      - name: app
        image: myapp:v2.0

---

# Service load-balances across both (by replica count)
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp          # No version filter: hits both v1 and v2
  ports:
  - port: 80
    targetPort: 8080

Advanced Canary (with Flagger + Istio):

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: app
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  progressDeadlineSeconds: 3600
  service:
    port: 80
  analysis:
    interval: 1m                        # Check metrics every 1 min
    threshold: 5                        # Rollback if > 5% error rate
    maxWeight: 50                       # Max 50% traffic to canary
    stepWeight: 10                      # Increase 10% per interval
    metrics:
    - name: request-success-rate
      thresholdRange:
        min: 99                         # Must be ≥ 99% success rate
      interval: 1m
    - name: request-duration
      thresholdRange:
        max: 500                        # Max 500ms latency
      interval: 30s
    webhooks:
    - name: integration-tests
      url: http://flagger-loadtester/
      timeout: 30s
      metadata:
        type: smoke
        cmd: "curl -sd 'test' http://app-canary/health | grep ok"
    - name: load-tests
      url: http://flagger-loadtester/
      timeout: 5s
      metadata:
        cmd: "hey -z 1m -q 10 -c 2 http://app-canary/"

Workflow:

# 1. Update image in Deployment
kubectl set image deployment/app app=myapp:v2.0

# 2. Flagger detects change and starts canary analysis
kubectl get canary -w

# 3. Monitor progress
kubectl get canary app -o yaml | grep status

# 4. If analysis passes, promotion is automatic
# If fails, Flagger automatically rolls back


Shadow Deployment (Zero-Risk Testing)

Mirror production traffic to new version (no impact) for testing before promotion.

Production: [v1] ← Real traffic → Production response
            ↓
Mirror:     [v2] ← Same traffic → Test response (ignored)

Compare v1 vs v2 responses: errors, latency, differences
- If v2 looks good: promote to canary/rolling
- If v2 has issues: discard (zero production impact)

Pros: ✅ Test with real traffic, zero impact if bad, early issue detection
Cons: ❌ Requires 2x resources, slow feedback (need sufficient traffic)
Risk: None (shadow doesn't affect production)

Implementation (Istio VirtualService):

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: app
spec:
  hosts:
  - app
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: app
        subset: v1
      weight: 100                   # All traffic to v1
    mirror:
      host: app
      subset: v2                    # Mirror to v2
    mirrorPercent: 100              # Mirror 100% of traffic
    mirrorPercentage:
      value: 100.0
  timeout: 30s
  retries:
    attempts: 3
    perTryTimeout: 10s

---

# Define versions (subsets)
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: app
spec:
  host: app
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 100
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Workflow:

# 1. Deploy v2 (shadowed)
kubectl set image deployment/app app=myapp:v2.0

# 2. Mirror 100% of v1 traffic to v2
# v2 responses are collected but not sent to clients

# 3. Compare logs/metrics between v1 and v2
kubectl logs -l version=v2 | grep error

# 4. If v2 looks good, switch to canary or rolling update
# If bad issues found, just delete v2 (zero impact)


Comparison Table

Strategy Cutover Risk Rollback Speed Testing Resource Time
Rolling Gradual (5-10 min) Low (monitored) Automatic Limited Same 3-10 min
Blue-Green Instant Very Low (full test) Instant (keep old) Full environment 2x Minutes
Canary Gradual (30-120 min) Low (monitored, auto-rollback) Automatic Real traffic 1.2x 30-120 min
Shadow N/A (testing only) None (zero impact) N/A Real traffic 2x Hours

Choosing a Strategy

Scenario Recommendation Reason
Standard deployments Rolling Update Default, simple, automated
High-confidence releases Blue-Green Complete testing before cutover
New features in production Canary Detect issues with real users
Risky changes (DB migrations) Shadow Zero-impact testing
Emergency hotfixes Blue-Green Instant rollback if issues
Performance-critical Canary Monitor latency before full rollout

Rollback Scenarios

# Rolling update auto-rollback on readiness probe failure
# (Pod fails health check → stays in old version)

# Manual rollback
kubectl rollout undo deployment/app

# Rollback to specific revision
kubectl rollout undo deployment/app --to-revision=3

# Pause rollout (mid-way)
kubectl rollout pause deployment/app

# Resume rollout
kubectl rollout resume deployment/app

Interview Talking Points

  • Rolling vs Blue-Green? Rolling: gradual, no extra resources; Blue-Green: instant, 2x resources
  • Why Canary? Detect issues with real traffic before full rollout; automatic rollback
  • Shadow deployment use? Test risky changes (schema updates, algorithm changes) with zero impact
  • Combination strategies? Blue-green for initial cutover + canary for gradual validation = "canary-blue-green"
  • Readiness probe importance? Ensures pod is healthy before traffic; rolling update won't proceed if probes fail
  • Kubectl rollout undo? Revert to previous Deployment revision (reuses old ReplicaSet)
  • Zero-downtime guarantee? maxUnavailable: 0 + readiness probe = no requests to unhealthy pods

See also: Kubernetes Fundamentals, DevOps Overview