Back to Deployment Strategies
Q5Question 5 of 5

Deployment Strategies: Rolling Update, Blue-Green, and Canary

Key Concepts
  • A rolling update replaces pods gradually, a few at a time, with no downtime but both versions run together briefly.
  • Blue-green keeps two full environments and flips all traffic at once for instant switch and instant rollback.
  • Canary shifts a small percentage of traffic to the new version first, ramps only if metrics stay healthy, and aborts on degradation.
  • All three require backward-compatible database schema changes (expand-and-contract) because old and new code coexist.
  • Readiness and liveness probes are what make these strategies safe by preventing traffic to unhealthy pods.
  • Automated canary analysis with Argo Rollouts or Flagger can roll back a bad release without human intervention.

Definition

Rolling swaps instances gradually, blue-green flips all traffic between two full environments instantly, and canary shifts a small percentage first and ramps only if metrics stay healthy.
  • Rolling update – replaces pods gradually, a few at a time, so there is always capacity serving traffic; both versions run together during the roll.
  • Blue-green – two complete environments; deploy and test the new one (green) fully, then flip the router to switch all traffic instantly; rollback is flipping back.
  • Canary – deploy the new version alongside the old but route only a small slice of traffic to it; watch metrics and ramp to 100% only if healthy, abort to 0% otherwise.
  • Expand-and-contract – the backward-compatible database migration pattern required by all three strategies because old and new code coexist.

Think of upgrading teller counters at a National Bank of India branch. A rolling update is closing one counter at a time, upgrading it, and reopening it before the next. Blue-green is building a second identical branch, fully fitting it out, then redirecting customers overnight with one sign change. Canary is sending a handful of customers to the new counter first and watching closely; if they are served well you send more, but if they complain you pull the counter before most customers saw it.

Understanding the Concepts

What is a rolling update?

A rolling update is the Kubernetes default strategy. It replaces pods gradually using maxUnavailable and maxSurge to control how many pods can be down and how many extra can be created.

YAML
# Kubernetes Deployment with rolling update strategy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: transfer-service
  namespace: prod
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1   # At most 1 pod down at a time
      maxSurge: 1          # At most 1 extra pod during roll
  template:
    spec:
      containers:
      - name: transfer-service
        image: registry.bank.local/transfer-service:v2.0.0
        readinessProbe:
          httpGet: { path: /actuator/health, port: 8080 }
          initialDelaySeconds: 10

Kubernetes brings up new-version pods, waits for them to pass readiness, then terminates old-version pods.

What is a blue-green deployment?

Blue-green uses two full environments. Blue runs the current version; green is deployed and tested with no customer traffic. When green is verified, the router switches all traffic at once.

YAML
# Blue environment (current production)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: transfer-service-blue
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: transfer-service
        image: registry.bank.local/transfer-service:v1.0.0
---
# Green environment (new version, tested but not serving)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: transfer-service-green
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: transfer-service
        image: registry.bank.local/transfer-service:v2.0.0
---
# Service: flip the selector to switch traffic
apiVersion: v1
kind: Service
metadata:
  name: transfer-service
spec:
  selector:
    version: blue     # Change to 'green' to switch
  ports:
  - port: 80
    targetPort: 8080
BASH
# Switch traffic from blue to green
kubectl patch svc transfer-service \
  -p '{"spec":{"selector":{"version":"green"}}}' -n prod

# Rollback: switch back to blue
kubectl patch svc transfer-service \
  -p '{"spec":{"selector":{"version":"blue"}}}' -n prod

What is a canary deployment?

Canary releases the new version to a small slice of traffic, watches metrics, and ramps only if healthy.

YAML
# Istio VirtualService: 5% to canary, 95% to stable
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: transfer-service
spec:
  hosts: [transfer-service]
  http:
  - route:
    - destination:
        host: transfer-service
        subset: stable
      weight: 95
    - destination:
        host: transfer-service
        subset: canary
      weight: 5
BASH
# Ramp up canary to 25%
kubectl patch virtualservice transfer-service \
  --type merge -p '{"spec":{"http":[{"route":[
    {"destination":{"host":"transfer-service","subset":"stable"},"weight":75},
    {"destination":{"host":"transfer-service","subset":"canary"},"weight":25}
  ]}]}}'

# Abort: set canary to 0%
kubectl patch virtualservice transfer-service \
  --type merge -p '{"spec":{"http":[{"route":[
    {"destination":{"host":"transfer-service","subset":"stable"},"weight":100},
    {"destination":{"host":"transfer-service","subset":"canary"},"weight":0}
  ]}]}}'

How do the three strategies compare?

| Aspect | Rolling Update | Blue-Green | Canary |
|---|---|---|---|
| Traffic switch | Gradual, pod by pod | All-at-once | Percentage-based |
| Downtime | None | None | None |
| Version overlap | Yes, during the roll | Yes, during overlap | Yes, by traffic weight |
| Rollback speed | Slow (roll back) | Instant (flip back) | Fast (set weight to 0%) |
| Infrastructure cost | Normal | Double capacity | Slightly more |
| Blast radius | Gradually increasing | All or nothing | Smallest (controlled %) |
| Tooling needed | Kubernetes default | Service selector | Service mesh or ingress |
| Best for | Stateless, low-risk | All-or-nothing releases | High-risk, high-traffic |

What is expand-and-contract for database changes?

All three strategies require backward-compatible schema changes because old and new code coexist during the rollout.

SQL
-- WRONG: dropping a column while old code still reads it.
ALTER TABLE account DROP COLUMN account_type;
-- Old pods that reference account_type will crash!

-- CORRECT: expand-and-contract in steps.
-- Step 1 (expand): add the new column.
ALTER TABLE account ADD COLUMN account_category VARCHAR(20);

-- Step 2: deploy code that writes BOTH old and new columns.
-- UPDATE account SET account_category = account_type;

-- Step 3: deploy code that reads only the new column.

-- Step 4 (contract): drop the old column after full rollout.
ALTER TABLE account DROP COLUMN account_type;

How does Argo Rollouts automate canary analysis?

Argo Rollouts integrates with Prometheus to automatically analyze metrics and decide whether to promote or abort a canary.

YAML
# Argo Rollouts: automated canary with metric analysis
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: transfer-service
spec:
  strategy:
    canary:
      steps:
      - setWeight: 5
      - pause: { duration: 5m }
      - analysis:
          templates:
          - templateName: success-rate
      - setWeight: 25
      - pause: { duration: 5m }
      - setWeight: 100
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  metrics:
  - name: transfer-success-rate
    successCondition: result[0] >= 0.99
    provider:
      prometheus:
        address: http://prometheus:9090
        query: |
          sum(rate(transfer_success_total{service="canary"}[5m]))
          / sum(rate(transfer_total{service="canary"}[5m]))

When should you use each strategy?

  • Rolling is the sensible default for stateless services where brief version overlap is fine.
  • Blue-green suits releases where you want a clean, instant, all-or-nothing switch and can afford double capacity.
  • Canary suits high-traffic, high-risk changes where you need real production signal before full exposure.
BASH
# Rolling: just update the image, Kubernetes handles the rest.
kubectl set image deployment/transfer-service \
  transfer-service=registry.bank.local/transfer-service:v2.0.0

# Blue-green: patch the service selector.
kubectl patch svc transfer-service \
  -p '{"spec":{"selector":{"version":"green"}}}'

# Canary: adjust the traffic weight.
kubectl patch virtualservice transfer-service \
  -p '{"spec":{"http":[{"route":[...weight:5...]}]}}'

What should a senior engineer know?

  • Readiness probes are what make these strategies safe. Without an accurate readiness probe, Kubernetes sends traffic to pods that are not ready.
  • For canary, automated metric analysis with Argo Rollouts or Flagger can roll back without a human in the loop.
  • The database compatibility rule applies to all three: old and new code always coexist, so migrations must be backward-compatible.
  • Blue-green is attractive for a core banking service during a tightly controlled release window because the switch and rollback are both instant.

Visual Overview

DIAGRAM
  Rolling Update:
  Pod v1  Pod v1  Pod v1
    │       │       │
    ▼       │       │
  Pod v2  Pod v1  Pod v1   (1 replaced)
    │       ▼       │
  Pod v2  Pod v2  Pod v1   (2 replaced)
    │       │       ▼
  Pod v2  Pod v2  Pod v2   (all replaced)

  Blue-Green:
  ┌──────────┐  ┌──────────┐
  │  BLUE    │  │  GREEN   │
  │  v1.0    │  │  v2.0    │
  │ (active) │  │ (tested) │
  └────┬─────┘  └────┬─────┘
       │              │
  ───Router───────────┘
       │
  Flip to green (instant switch)
  Flip to blue  (instant rollback)

  Canary:
  ┌──────────┐  ┌──────────┐
  │  STABLE  │  │  CANARY  │
  │  v1.0    │  │  v2.0    │
  │  95%     │  │   5%     │
  └──────────┘  └──────────┘
       │              │
  Watch metrics: error rate, latency
  Healthy → ramp to 25% → 50% → 100%
  Degraded → abort to 0%

Key Takeaway

A deployment strategy controls how you replace a running version with a new one while managing risk and downtime. A rolling update replaces pods gradually so there is always capacity serving traffic, with the trade-off that both versions run together during the roll. Blue-green keeps two complete environments and flips all traffic at once, giving instant switch and instant rollback at the cost of double capacity. Canary releases to a small percentage first, watches metrics, and ramps only if healthy, giving the smallest possible blast radius.

I choose based on risk and infrastructure. Rolling is the default for stateless services. Blue-green suits a tightly controlled release where instant rollback is essential. Canary suits high-risk changes like a new fraud-scoring model where real production signal is needed before full exposure.

The one point that applies to all three is database compatibility. Since old and new versions coexist during the roll, schema changes must be done in backward-compatible expand-and-contract steps. Readiness probes are what make all three strategies safe, because they prevent traffic from reaching pods that are not truly ready.

Remember one sentence: rolling swaps gradually, blue-green flips instantly, and canary ramps only when metrics prove the new version is safe.

---

Share
Use ← → arrow keys to navigate