πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Deployments intermediate ⏱ 12 minutes K8s 1.28+

K8s Deployment Rolling Update Strategy

Configure Kubernetes Deployment rolling updates with maxSurge and maxUnavailable. Rollback, revision history, blue-green, and canary deployment patterns.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Kubernetes rolling updates replace pods gradually: maxSurge: 25% allows 25% extra pods during update, maxUnavailable: 25% allows 25% pods to be unavailable. Default strategy creates new pods before killing old ones. Rollback with kubectl rollout undo deployment/<name>. Set revisionHistoryLimit: 10 to keep rollback history.

The Problem

Updating a deployment without downtime requires careful orchestration:

  • All pods updated at once = downtime
  • No rollback capability = stuck with broken versions
  • Slow rollouts waste time; fast rollouts risk stability
  • Need to verify new version before fully committing

The Solution

Rolling Update Strategy

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 10
  revisionHistoryLimit: 10    # Keep 10 rollback versions
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%           # Allow 25% extra pods (3 extra)
      maxUnavailable: 25%     # Allow 25% unavailable (2 down)
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: myapp:v2
        ports:
        - containerPort: 8080
        readinessProbe:           # Critical for safe rollouts
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

How Rolling Update Works

Initial state (10 replicas, v1):
v1 v1 v1 v1 v1 v1 v1 v1 v1 v1

Step 1: Create 3 new (maxSurge 25%), kill 2 old (maxUnavailable 25%):
v1 v1 v1 v1 v1 v1 v1 v1 v2 v2 v2  (13 total, 2 terminating)

Step 2: As v2 pods become Ready, more v1 are terminated:
v1 v1 v1 v1 v1 v2 v2 v2 v2 v2 v2  (continuing...)

Step 3: Complete:
v2 v2 v2 v2 v2 v2 v2 v2 v2 v2

Trigger and Monitor Rollouts

# Update image (triggers rolling update)
kubectl set image deployment/web-app web=myapp:v2

# Or edit directly
kubectl edit deployment web-app

# Watch rollout progress
kubectl rollout status deployment/web-app
# Waiting for deployment "web-app" rollout to finish: 5 of 10 updated replicas are available...
# deployment "web-app" successfully rolled out

# Check rollout history
kubectl rollout history deployment/web-app
# REVISION  CHANGE-CAUSE
# 1         kubectl set image deployment/web-app web=myapp:v1
# 2         kubectl set image deployment/web-app web=myapp:v2

# Pause rollout (for manual verification)
kubectl rollout pause deployment/web-app

# Resume rollout
kubectl rollout resume deployment/web-app

Rollback

# Rollback to previous version
kubectl rollout undo deployment/web-app

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

# Check what's in a specific revision
kubectl rollout history deployment/web-app --revision=2

maxSurge and maxUnavailable Patterns

# Zero-downtime (slower): extra pods before killing old
maxSurge: 1
maxUnavailable: 0
# Never below 10 pods, creates 1 extra at a time

# Fast rollout: allow some downtime
maxSurge: 50%
maxUnavailable: 50%
# Quick update, but 5 of 10 pods may be unavailable

# Absolute values
maxSurge: 3
maxUnavailable: 2
# At most 13 pods total, at least 8 available

# Recreate strategy (NOT rolling β€” full downtime)
strategy:
  type: Recreate
# All old pods killed, then all new pods created
# Use for: databases, stateful apps that can't run two versions

Canary Deployment Pattern

# Manual canary: scale down main, create canary
kubectl scale deployment web-app --replicas=9
kubectl create deployment web-app-canary --image=myapp:v2 --replicas=1

# Both deployments behind same service (matching labels)
# Monitor canary metrics, then promote:
kubectl set image deployment/web-app web=myapp:v2
kubectl delete deployment web-app-canary

Common Issues

Rollout stuck β€” new pods not becoming Ready

Readiness probe failing on new version. Check: kubectl describe pod <new-pod>. Rollback: kubectl rollout undo deployment/web-app.

β€œdeadline exceeded” error

Set progressDeadlineSeconds (default 600s). If rollout takes longer, it’s marked failed but continues.

Old ReplicaSets consuming resources

Set revisionHistoryLimit to limit kept ReplicaSets. Old pods are already scaled to 0 but ReplicaSet objects remain.

Best Practices

  • Always set readinessProbe β€” rolling updates rely on Ready status
  • Start with maxSurge: 25%, maxUnavailable: 0 β€” zero-downtime default
  • Use Recreate for databases β€” two versions of a DB can corrupt data
  • Set revisionHistoryLimit: 5-10 β€” keep rollback options without clutter
  • Annotate changes β€” kubectl annotate deployment web-app kubernetes.io/change-cause="v2 security patch"

Key Takeaways

  • Rolling updates replace pods gradually with configurable surge and unavailability
  • maxSurge controls how many extra pods; maxUnavailable controls minimum available
  • kubectl rollout undo rolls back to previous revision instantly
  • Readiness probes are essential β€” without them, bad pods receive traffic
  • Use Recreate strategy for stateful apps that can’t run two versions simultaneously
#deployments #rolling-update #rollback #canary #cka
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens