dissected.io
Lesson 6 of 15
Intermediatedeploymentsrolling-updatescanaryblue-greenrollbacks10 min read

Deployments and Rolling Updates

Deploying a new version of your application should not require downtime. Kubernetes Deployments give you fine-grained control over how new versions roll out, how many pods can be unavailable during the transition, and how to undo a bad release in seconds. But the default strategy isn't always the right one — sometimes you want a full traffic cutover (blue-green), and sometimes you want to test on a fraction of users first (canary). Understanding the tradeoffs between these strategies is what separates a deploy-and-pray workflow from a controlled release pipeline.

Kubernetes Release Strategies — Rolling, Blue-Green & Canary

Ingress / Service RouterTraffic DistributorReplicaSet v1 (Old)image: webapp:1.0v1 Pod 1Activev1 Pod 2Activev1 Pod 3ActiveReplicaSet v2 (New)image: webapp:2.0 (maxSurge: 1)v1.0 serving 100% of user traffic across 3 pods.

Rolling Update Strategy

The default Deployment strategy is RollingUpdate. Kubernetes creates a new ReplicaSet with the updated pod spec, scales it up, and scales the old ReplicaSet down — one batch at a time. Two parameters control the pace:

maxSurge: how many extra pods (above the desired count) can exist during the update. A value of 1 means Kubernetes creates one new pod before removing an old one. Set it higher for faster rollouts.

maxUnavailable: how many pods can be unavailable during the update. A value of 0 means every old pod stays running until a new pod is Ready. Set it to 0 for zero-downtime updates; set it higher to speed things up at the cost of capacity.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
        - name: web
          image: myapp:v2
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

The readiness probe is critical here. Kubernetes won't route traffic to a new pod or remove an old pod until the new one passes its readiness check. Without a readiness probe, Kubernetes assumes the pod is ready immediately — which means users could hit a container that's still loading.

Recreate Strategy

The Recreate strategy is the nuclear option — kill all old pods, then start all new pods. There's a window of downtime. Use this only when your application can't tolerate two versions running simultaneously (e.g., database schema migrations that break backward compatibility).

strategy:
  type: Recreate

Blue-Green Deployments

Blue-green isn't a native Kubernetes strategy — you implement it with two Deployments and a Service. The idea: run the full new version alongside the full old version, then flip the Service selector to point at the new version all at once.

# Blue deployment (current)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-blue
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: web
        version: blue
---
# Green deployment (new)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-green
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: web
        version: green
---
# Service — flip the selector to switch
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
    version: blue  # Change to "green" to switch

The advantage: instant rollback — just flip the selector back. The cost: you need double the resources during the transition.

Canary Releases

Canary deployments route a small percentage of traffic to the new version. In basic Kubernetes, you can approximate this by running a small canary Deployment alongside the main one, both behind the same Service. If you have 9 v1 pods and 1 v2 pod, roughly 10% of traffic goes to v2.

For precise traffic splitting (e.g., exactly 5% to canary), you need a service mesh like Istio or Linkerd, or a Gateway API implementation with traffic weights.

Rollbacks

Every Deployment update creates a new revision. Kubernetes keeps a revision history (default: 10 revisions). If something goes wrong:

# Check rollout status
kubectl rollout status deployment/web-app

# View revision history
kubectl rollout history deployment/web-app

# Undo to previous revision
kubectl rollout undo deployment/web-app

# Undo to a specific revision
kubectl rollout undo deployment/web-app --to-revision=3

The revisionHistoryLimit field controls how many old ReplicaSets are kept. Set it too low and you lose the ability to roll back far enough. Set it too high and you accumulate unused ReplicaSets.

Deployment Status Conditions

Monitor your rollout with kubectl rollout status. A Deployment can be in one of three states:

  • Progressing: rolling out new pods
  • Available: minimum required pods are ready
  • Failed: timed out (controlled by progressDeadlineSeconds, default 600s)

If a new pod keeps crashing or failing readiness probes, the rollout stalls. It won't automatically roll back — you need to intervene with kubectl rollout undo or fix the issue.

Key Takeaways

  • Rolling updates are the default — use maxSurge and maxUnavailable to control rollout speed vs. availability
  • Always set readiness probes — without them, Kubernetes can't tell if your new pods are actually ready for traffic
  • Blue-green gives instant cutover and rollback, but costs double the resources during deploy
  • Canary releases limit blast radius — start with a small percentage before going full rollout
  • kubectl rollout undo is your emergency brake — know your revision history
  • Failed rollouts don't auto-rollback — set progressDeadlineSeconds and monitor rollout status in CI/CD

Enjoyed this breakdown?

Get notified when new lessons go live.