How to organize rolling update in Kubernetes
A Rolling Update is the default deployment strategy for Kubernetes Deployment workloads. It incrementally replaces old Pod instances with new ones progressively in small batches...
🟢 Junior Level
30-Second Summary
A Rolling Update is the default deployment strategy for Kubernetes Deployment workloads. It incrementally replaces old Pod instances with new ones progressively in small batches, ensuring continuous service availability with Zero Downtime.
- Instead of terminating all running containers simultaneously (the destructive
Recreatestrategy), Kubernetes spins up one or more new pods. - It waits until the new pods pass their
readinessProbe. - Only after new replicas are verified ready does Kubernetes begin gracefully terminating older pods.
- Throughout the entire process, client traffic is continuously served without disruption.
Real-World Analogy
A Rolling Update is like changing tires on a moving multi-axle freight truck or train:
- The truck has 8 wheels.
- Mechanics elevate one axle, unbolt the old wheel, mount the new tire, verify torque wrench tension (
readinessProbe), and lower it back onto the highway. - Then they proceed to the next axle.
- The truck never stops moving and continues delivering cargo. The alternative (
Recreate) is cutting the engine, removing all 8 wheels at once, and leaving the truck propped on cinder blocks (total business outage).
Basic Deployment Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-service
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Allow at most 1 temporary extra pod (up to 4 + 1 = 5 pods)
maxUnavailable: 0 # Zero pods allowed unavailable (at least 4 healthy pods at all times)
selector:
matchLabels:
app: payment
template:
metadata:
labels:
app: payment
spec:
containers:
- name: payment-app
image: payment-service:2.1.0 # Specific semantic version tag (NEVER :latest!)
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
periodSeconds: 5
🟡 Middle Level
The Mathematics of maxSurge and maxUnavailable
Workload rollout behavior is governed by two parameters expressed as integers or percentages:
Baseline Replicas: spec.replicas = 4
maxSurge: 1 -> Peak allowed pods during rollout: 4 + 1 = 5 pods
maxUnavailable: 0 -> Minimum required responsive pods: 4 - 0 = 4 pods
Step-by-Step Rollout Progression:
- Step 1: Kubernetes spawns 1 new Pod running version
v2. Total cluster pods = 5 (4v1+ 1v2). - Step 2: The
v2Pod passes itsreadinessProbe. The Service adds it toEndpoints, routing live traffic to it. - Step 3: The controller terminates 1 old
v1Pod. Total cluster pods return to 4 (3v1+ 1v2). - Step 4: This batch cycle repeats iteratively until all 4 pods run
v2, leaving 0 pods onv1.
Lifecycle Management via kubectl rollout
Kubernetes provides built-in commands to monitor, pause, and revert deployments:
# 1. Trigger an update by updating the container image:
kubectl set image deployment/payment-service payment-app=payment-service:2.2.0
# 2. Stream real-time rollout status:
kubectl rollout status deployment/payment-service
# 3. Pause an ongoing rollout (e.g., to validate telemetry on a canary pod):
kubectl rollout pause deployment/payment-service
# 4. Resume deployment rollout:
kubectl rollout resume deployment/payment-service
# 5. Inspect revision history:
kubectl rollout history deployment/payment-service
# 6. INSTANT ROLLBACK to the previous stable revision during an outage:
kubectl rollout undo deployment/payment-service
Under the Hood: The Role of ReplicaSets
A Deployment does not manage individual Pods directly; it orchestrates underlying ReplicaSet objects:
- When the
spec.templatechanges, the Deployment controller creates a new ReplicaSet (e.g.,payment-78d4f8). - It progressively increments
replicasin the new ReplicaSet while decrementingreplicasin the old ReplicaSet (payment-59c6b8). - Once finished, the previous ReplicaSet remains preserved at
replicas: 0. This enableskubectl rollout undoto revert traffic in less than a second simply by re-scaling the preserved ReplicaSet!
🔴 Senior Level
Version Coexistence & The “Expand / Contract” Pattern
During a rolling update, Version 1 (old) and Version 2 (new) execute concurrently against the database for several minutes:
- Request A may hit
v1, while Request B hitsv2. - If a developer drops a table column or renames a JSON property in
v2, remainingv1pods will immediately throw runtime exceptions and crash.
Database Evolution: The Expand and Contract Pattern:
- Phase 1 (Expand): Execute a Liquibase/Flyway migration: ADD the new column as NULLABLE. Version
v1continues running normally, ignoring the new column. - Phase 2 (Rollout): Execute the Rolling Update for
v2. Versionv2dual-writes to both the old and new columns. - Phase 3 (Contract): After 100% rollout verification, execute a cleanup migration to drop the obsolete column.
Production Stalling Pitfalls: Quotas and PDBs
1. Deadlock via ResourceQuota Limits
If a Namespace has a hard quota of 10 pods, and replicas: 10 is active:
- Deploying with
maxSurge: 2instructs Kubernetes to spawn an 11th and 12th pod. - The admission controller rejects pod creation with
exceeded quota. - New pods sit permanently in
Pending, freezing the rollout untilprogressDeadlineSecondsexpires. - Solution: In quota-constrained namespaces, configure
maxSurge: 0,maxUnavailable: 1(evicts an old pod first to free quota before creating a new one).
2. Deadlock via PodDisruptionBudget (PDB)
If a PDB requires minAvailable: 100% on a 4-replica deployment while maxUnavailable: 25% is declared:
- The Deployment controller cannot terminate an old pod because doing so violates the PDB constraint. The rollout deadlocks completely.
The 4-Pillar Zero-Downtime Architecture for Java/Spring Boot
To guarantee zero 502 Bad Gateway errors during rollouts:
maxUnavailable: 0: Never terminate an old pod until a replacement replica is confirmed operational.- Robust
readinessProbe: Route traffic to Spring Boot only after bean wiring and cache priming are complete. preStop: sleep 10: DelaysSIGTERMby 10 seconds to allow cluster-widekube-proxyiptables propagation to drain.- Spring Boot Graceful Shutdown: Enable
server.shutdown: gracefuland configurespring.lifecycle.timeout-per-shutdown-phase: 20sso Tomcat completes active transactions before container death.
4 Tricky Questions
1. Why does using the Docker image tag :latest (e.g., image: my-app:latest) completely break Kubernetes automated Rolling Updates?
Answer:
The Deployment controller detects updates by hashing the spec.template (generating the pod-template-hash label):
- If you push a new image build to your registry using the existing tag
my-app:latestand runkubectl apply -f deployment.yaml, the text content of the manifest remains byte-for-byte identical. - Because the pod template hash has not changed, the Deployment controller determines that no configuration change occurred and does not trigger a Rolling Update.
- Active pods continue running the stale code. To trigger automated rollouts reliably, always specify unique semantic version tags (
:2.1.0) or immutable container digest hashes (@sha256:...).
2. What happens to ConfigMap and Secret resources when you run kubectl rollout undo?
Answer: They do NOT roll back! This is a major operational trap:
- Kubernetes Deployment revision history tracks changes made exclusively to the Pod template specification (
spec.template). - External resources like
ConfigMapandSecretare independent objects without native revision linkage to the Deployment. - Running
kubectl rollout undorolls the container image back to the previous revision, but the container will mount the CURRENT, modifiedConfigMap! If the old application binary is incompatible with the new configuration schema, it will crash immediately. - Mitigation: Use GitOps tooling (Helm, ArgoCD) or append content hashes to ConfigMap names (e.g.,
app-config-a8f3d1), updating the Deployment’s volume reference on each change (Immutable ConfigMaps).
3. What is the purpose of spec.progressDeadlineSeconds, and what happens if a deployment exceeds it during a failed rollout?
Answer:
progressDeadlineSeconds(default: 600 seconds / 10 minutes) specifies the maximum time Kubernetes waits for an update to demonstrate verifiable progress (pods launching, passing readiness checks).- If new pods become trapped in
CrashLoopBackOfforImagePullBackOfffor longer than this duration:- The Deployment controller updates its status condition
ProgressingtoFalsewith the reasonProgressDeadlineExceeded. - Kubernetes DOES NOT perform an automated rollback! The rollout halts in its current intermediate state (retaining healthy old pods and broken new pods), signaling alerts to Prometheus or CI/CD pipelines to initiate manual or scripted intervention.
- The Deployment controller updates its status condition
4. How does the RollingUpdate strategy differ between a Deployment and a StatefulSet?
Answer:
- In a
Deployment: Pods are stateless and interchangeable. The controller can create extra pods beyond the baseline usingmaxSurge, updating them in parallel without order constraints. - In a
StatefulSet:maxSurgeis not supported; replica counts can never exceed the declared number because each Pod is bound to a dedicated, non-shareablePersistentVolume.- Updates execute in strict reverse ordinal order (from $N-1$ down to 0). In a 3-replica set (
pod-0,pod-1,pod-2),pod-2is terminated, updated, and verifiedReadybeforepod-1is touched. - The replacement pod preserves its exact ordinal number, stable network hostname, and storage volume.
🎯 Interview Cheat Sheet
Core Rolling Update Architecture
- Default Strategy: Zero-downtime progressive replacement of old pods with new ones.
maxSurge: Extra pods allowed abovereplicasduring deployment (headroom).maxUnavailable: Maximum number of pods permitted unavailable during deployment.- Zero-Downtime Rule:
maxUnavailable: 0+readinessProbe+preStop: sleep 10+ Spring Boot Graceful Shutdown. - ReplicaSet Mechanism: Creates a new ReplicaSet, scales it up, scales old ReplicaSet down to 0 for instant
rollout undo. - Database Compatibility: Always employ the Expand/Contract pattern; both versions run concurrently during rollouts.
- Tag Anti-Pattern: Never deploy with
:latest; unchanging YAML hashes prevent rollouts from triggering.
Kubernetes Deployment Strategies Comparison
| Strategy | Downtime | Resource Overhead | Rollback Speed | Concurrency |
| :— | :—: | :—: | :—: | :— |
| RollingUpdate | 🟢 Zero | Within maxSurge limit | Fast (rollout undo) | Old and new versions run concurrently |
| Recreate | 🔴 Incurred | None (terminates all first) | Slow (full restart) | Single version at a time |
| Blue-Green | 🟢 Zero | +100% capacity duplication | Instant (Service switch) | Completely isolated environments |
| Canary | 🟢 Zero | Small canary allocation | Instant | Small percentage of live users on new version |
Red Flags (What NOT to Say)
- ❌ “We trigger deployments by pushing new code to the :latest image tag.” — Kubernetes detects no manifest diff and ignores the update.
- ❌ “Running
kubectl rollout undoautomatically reverts database migrations and Secret changes.” — Only the pod spec is rolled back; configs and DB remain forward. - ❌ “Rolling updates guarantee that v1 and v2 never execute at the same time.” — They run concurrently by design throughout the rollout window.
Related Topics
- What is readiness probe — Rollout health verification
- What is ReplicaSet — Pod replica management
- What is StatefulSet and when to use it — Ordered stateful rollouts
- What is Pod in Kubernetes — Pod lifecycle and graceful termination