πŸ“š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 ⏱ 15 minutes K8s 1.28+

Blue-Green Deployment in Kubernetes

Implement blue-green deployments in Kubernetes for instant rollback. Covers Service selector switching, Argo Rollouts blue-green, and comparison with canary

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

πŸ’‘ Quick Answer: Run two identical environments β€” blue (current) and green (new) β€” behind one Service. Switch traffic instantly by patching the Service selector: kubectl patch svc web -p '{"spec":{"selector":{"version":"green"}}}'. Rollback is the same command in reverse. Costs 2x resources while both run.

The Problem

You want to deploy a new version with the ability to instantly switch back to the old version if something goes wrong β€” without the slow, gradual exposure of a rolling update.

The Solution

Native Blue-Green with Service Selector

# Blue deployment (current production)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      version: blue
  template:
    metadata:
      labels:
        app: web
        version: blue
    spec:
      containers:
        - name: web
          image: my-app:v1
---
# Green deployment (new version)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      version: green
  template:
    metadata:
      labels:
        app: web
        version: green
    spec:
      containers:
        - name: web
          image: my-app:v2
---
# Switch traffic by updating selector
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
    version: blue     # ← Change to "green" to switch
  ports:
    - port: 80
# Deploy green alongside blue
kubectl apply -f web-green.yaml

# Test green (port-forward to green directly)
kubectl port-forward deployment/web-green 8080:80

# Switch traffic: blue β†’ green
kubectl patch svc web -p '{"spec":{"selector":{"version":"green"}}}'

# Instant rollback: green β†’ blue
kubectl patch svc web -p '{"spec":{"selector":{"version":"blue"}}}'

# Clean up old version after confirming
kubectl delete deployment web-blue

Full Walkthrough: Test Before Switching, Then Roll Back or Clean Up

# 1. Deploy green alongside the running blue version
kubectl apply -f web-green.yaml
kubectl rollout status deployment/web-green

# 2. Test green directly before it takes production traffic β€”
#    create a throwaway Service pointed only at green
kubectl expose deployment web-green --name=web-test --port=80 --target-port=8080
kubectl run test-pod --rm -it --image=curlimages/curl -- curl http://web-test/health
kubectl delete service web-test

# 3. Switch production traffic: blue β†’ green
kubectl patch svc web -p '{"spec":{"selector":{"version":"green"}}}'
kubectl describe service web | grep Selector   # confirm the switch

# 4. Instant rollback if something's wrong: green β†’ blue
kubectl patch svc web -p '{"spec":{"selector":{"version":"blue"}}}'

# 5. Once confident, remove the old version
kubectl delete deployment web-blue

Automate the switch/rollback with a small script so it’s a single, auditable command instead of hand-typed patches:

#!/bin/bash
# blue-green-switch.sh <service> <blue|green>
SERVICE_NAME=${1:-web}
TARGET_VERSION=${2:-green}
kubectl patch service "$SERVICE_NAME" -p "{\"spec\":{\"selector\":{\"version\":\"$TARGET_VERSION\"}}}"
kubectl get endpoints "$SERVICE_NAME"
kubectl get service "$SERVICE_NAME" -o jsonpath='{.spec.selector}'

Blue-Green vs Canary vs Rolling

StrategyRollback SpeedResource CostRisk
Blue-GreenInstant (switch selector)2x (both versions running)Low
CanaryFast (scale down canary)~10% extraVery low
Rolling UpdateSlow (rollout undo)~25% extraMedium
graph TD
    A[Service: web] -->|selector: version=blue| B[Blue: v1 - 3 pods]
    C[Green: v2 - 3 pods] -->|Ready and tested| D[Switch selector]
    D --> E[Service: web β†’ version=green]
    E --> C
    F[Problem?] --> G[Switch back to blue - instant]

Frequently Asked Questions

Blue-green vs rolling update?

Blue-green: run both versions fully, switch traffic instantly, instant rollback. Costs 2x resources during deployment. Rolling update: gradually replace pods, lower resource cost, slower rollback.

Best Practices

  • Keep both environments identical β€” same resource requests/limits, ConfigMaps, Secrets, and env vars, so the only difference is the image version
  • Always test green before switching β€” verify readiness and run smoke tests against it directly, not through the production Service
  • Watch pods and logs after switching β€” kubectl get pods -l app=web -w and kubectl logs -l version=green --tail=100 catch problems the switch itself won’t surface
  • Plan for database migrations separately β€” blue-green swaps traffic instantly, but schema changes usually can’t be rolled back as cleanly as the Service selector
  • Automate the switch β€” a script removes typos from a high-stakes kubectl patch command

Key Takeaways

  • Blue-green gives instant rollback: switching back is the same kubectl patch command in reverse
  • Requires 2x resources temporarily β€” both versions run at full replica count during the cutover
  • Test the green environment directly (port-forward or a throwaway Service) before it takes production traffic
  • Database migrations need their own handling β€” they don’t roll back with the Service selector
  • More complex and resource-hungry than rolling updates, but avoids serving mixed versions during the rollout
#blue-green #deployment-strategy #zero-downtime #rollback #kubernetes
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