How Do You Implement a Blue-Green Deployment in Kubernetes?

advanced|deploymentsdevopssreCKACKAD
TL;DR

Blue-green deployments run two identical environments (blue and green) side by side. Traffic is routed entirely to one version, and you switch instantly by updating the Service selector. This eliminates the risk of partial rollouts.

Detailed Answer

Kubernetes does not have a built-in "blue-green" deployment type. Instead, you implement the pattern using two Deployments and a Service. The key idea is that you run both versions simultaneously, but the Service only routes traffic to one of them at a time.

The Blue-Green Pattern

                    ┌─────────────────┐
                    │    Service       │
                    │  selector:       │
                    │   version: blue  │
                    └────────┬────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
         ┌────▼────┐   ┌────▼────┐   ┌────▼────┐
         │ blue-0  │   │ blue-1  │   │ blue-2  │
         └─────────┘   └─────────┘   └─────────┘

         ┌─────────┐   ┌─────────┐   ┌─────────┐
         │ green-0 │   │ green-1 │   │ green-2 │  (idle)
         └─────────┘   └─────────┘   └─────────┘

Step 1 -- Deploy the Blue Version

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
      version: blue
  template:
    metadata:
      labels:
        app: web-app
        version: blue
    spec:
      containers:
        - name: web-app
          image: web-app:1.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

Step 2 -- Create the Service Pointing to Blue

apiVersion: v1
kind: Service
metadata:
  name: web-app
spec:
  selector:
    app: web-app
    version: blue     # Routes to blue only
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

All production traffic goes to web-app-blue Pods.

Step 3 -- Deploy the Green Version

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
      version: green
  template:
    metadata:
      labels:
        app: web-app
        version: green
    spec:
      containers:
        - name: web-app
          image: web-app:2.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

At this point, both Deployments are running, but the Service only sends traffic to blue.

Step 4 -- Validate Green

Before switching traffic, test the green environment:

# Port-forward to a green Pod for manual testing
kubectl port-forward deployment/web-app-green 8081:8080

# Run smoke tests against localhost:8081
curl http://localhost:8081/healthz

# Or create a temporary test Service
kubectl expose deployment web-app-green --name=web-app-test --port=80 --target-port=8080

Step 5 -- Switch Traffic

Once validation passes, update the Service selector:

kubectl patch service web-app -p '{"spec":{"selector":{"version":"green"}}}'

Traffic immediately shifts to the green Pods. No rolling update, no partial state -- it is an atomic switch.

Step 6 -- Rollback if Needed

If something is wrong with green, switch back:

kubectl patch service web-app -p '{"spec":{"selector":{"version":"blue"}}}'

This is instantaneous because the blue Pods are still running.

Step 7 -- Cleanup

Once you are confident in the green deployment:

# Delete the old blue Deployment
kubectl delete deployment web-app-blue

# Optionally, for the next release, blue becomes the new version
# and green becomes the current production

Automating with a Script

#!/bin/bash
set -euo pipefail

NEW_VERSION="green"
OLD_VERSION="blue"
SERVICE_NAME="web-app"
DEPLOYMENT_NAME="web-app-${NEW_VERSION}"

echo "Waiting for ${DEPLOYMENT_NAME} to be ready..."
kubectl rollout status deployment/${DEPLOYMENT_NAME} --timeout=300s

echo "Running smoke tests..."
# Add your test logic here

echo "Switching traffic to ${NEW_VERSION}..."
kubectl patch service ${SERVICE_NAME} \
  -p "{\"spec\":{\"selector\":{\"version\":\"${NEW_VERSION}\"}}}"

echo "Traffic switched. Monitoring for 60 seconds..."
sleep 60

echo "Cleaning up ${OLD_VERSION} deployment..."
kubectl delete deployment web-app-${OLD_VERSION}

echo "Blue-green deployment complete."

Tradeoffs

| Advantage | Disadvantage | |---|---| | Instant traffic switch | Double resource usage during transition | | Instant rollback | More complex orchestration than rolling updates | | No mixed versions serving traffic | Database schema changes need careful handling | | Full pre-release testing in production environment | Not built into Kubernetes natively |

Tools That Simplify Blue-Green

  • Argo Rollouts: Provides a BlueGreen strategy as a custom resource, automating the switch and cleanup.
  • Flagger: Works with service meshes to automate blue-green and canary patterns.
  • Istio/Linkerd: Provide traffic shifting at the network layer for more granular control.
# Argo Rollouts blue-green example
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: web-app
spec:
  replicas: 3
  strategy:
    blueGreen:
      activeService: web-app
      previewService: web-app-preview
      autoPromotionEnabled: false
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web-app
          image: web-app:2.0

Summary

Blue-green deployments in Kubernetes use two separate Deployments and switch traffic by updating the Service selector. This gives you an instant, atomic cutover with equally instant rollback. The tradeoff is double resource usage and more operational complexity. For teams that need stronger guarantees than rolling updates provide, blue-green is a proven pattern -- especially when enhanced by tools like Argo Rollouts.

Why Interviewers Ask This

Blue-green is a classic deployment strategy. Interviewers want to know if you can implement it in Kubernetes and understand the tradeoffs compared to rolling updates.

Common Follow-Up Questions

What is the main disadvantage of blue-green deployments?
Resource cost. You need double the infrastructure during the transition because both the old and new versions run simultaneously at full capacity.
How does blue-green differ from canary deployments?
Blue-green switches 100% of traffic at once. Canary gradually shifts a small percentage of traffic to the new version, allowing incremental validation.
Can you use Istio or a service mesh for blue-green deployments?
Yes. A service mesh provides traffic splitting at the network layer, letting you do weighted routing without modifying Kubernetes Service selectors.

Key Takeaways

  • Blue-green uses two full Deployments with traffic switched via the Service selector.
  • It provides instant rollback by switching the selector back.
  • It costs more resources but eliminates partial rollout risk.

Related Questions