Table of Contents
- What Are Blue/Green Deployments?
- Why Kubernetes for Blue/Green Deployments?
- Prerequisites
- Step 1: Set Up the “Blue” Environment (Current Live Version)
- Step 2: Deploy the “Green” Environment (New Version)
- Step 3: Switch Traffic from Blue to Green
- Rollback Strategy: Switching Back to Blue
- Best Practices for Blue/Green Deployments in Kubernetes
- References
1. What Are Blue/Green Deployments?
Blue/Green Deployments are a release strategy that uses two identical environments:
- Blue: The current production environment running the stable version of the application. All user traffic is routed here initially.
- Green: A parallel environment where the new version of the application is deployed and tested. No live traffic reaches Green until it is validated.
Once Green is confirmed to be stable (via testing, monitoring, or manual approval), traffic is switched from Blue to Green in a single step. If issues arise with Green, traffic can be immediately rolled back to Blue, minimizing downtime.
2. Why Kubernetes for Blue/Green Deployments?
Kubernetes provides native tools to simplify Blue/Green deployments:
- Deployments: Manage identical Blue and Green replica sets.
- Services: Use label selectors to route traffic to either Blue or Green.
- Orchestration: Automate scaling, self-healing, and rollouts/rollbacks.
- Declarative Configuration: Define environments as YAML manifests for consistency.
This combination makes Kubernetes ideal for implementing low-risk, high-velocity Blue/Green deployments.
3. Prerequisites
Before starting, ensure you have:
- A running Kubernetes cluster (local clusters like Minikube, kind, or a cloud cluster like EKS/GKE/AKS).
kubectlconfigured to access the cluster.- A sample application (we’ll use a simple Node.js app serving a version string for demonstration).
4. Step 1: Set Up the “Blue” Environment (Current Live Version)
First, we’ll deploy the “Blue” environment—the current stable version of the application.
4.1 Deploy the Blue Deployment
Create a deployment manifest for the Blue environment (blue-deployment.yaml):
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
labels:
app: my-app
version: blue # Unique label for Blue environment
spec:
replicas: 3 # 3 replicas for high availability
selector:
matchLabels:
app: my-app
version: blue # Matches pods with these labels
template:
metadata:
labels:
app: my-app
version: blue # Pod labels (critical for service routing)
spec:
containers:
- name: my-app
image: nginx:1.21 # Replace with your app (e.g., your-node-app:v1)
ports:
- containerPort: 80
# Optional: Add health checks to ensure pods are ready
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Explanation:
labels:version: blueuniquely identifies the Blue environment.replicas: 3: Ensures high availability.readinessProbe: Ensures pods are only marked “ready” after passing health checks (critical for traffic routing).
Deploy Blue:
kubectl apply -f blue-deployment.yaml
Verify pods are running:
kubectl get pods -l version=blue # -l filters by label
Output should show 3 running pods:
NAME READY STATUS RESTARTS AGE
app-blue-7f9b5c4d9c-2xqzv 1/1 Running 0 2m
app-blue-7f9b5c4d9c-5k7p8 1/1 Running 0 2m
app-blue-7f9b5c4d9c-9r2s7 1/1 Running 0 2m
4.2 Expose Blue with a Kubernetes Service
A Kubernetes Service routes traffic to pods using label selectors. We’ll create a service to expose Blue initially.
Create app-service.yaml:
# app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
type: NodePort # Use LoadBalancer for cloud clusters; NodePort for local (e.g., Minikube)
selector:
app: my-app
version: blue # Routes traffic to Blue pods initially
ports:
- port: 80 # Service port
targetPort: 80 # Pod port (matches containerPort in deployment)
nodePort: 30080 # Optional: Fixed port for NodePort (30000-32767 range)
Explanation:
selector: version: blue: Ensures traffic flows to Blue pods.type: NodePort: Exposes the service on a node port (accessible viaminikube ip:30080for local clusters).
Deploy the service:
kubectl apply -f app-service.yaml
Verify the service:
kubectl get service my-app-service
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-app-service NodePort 10.96.231.123 <none> 80:30080/TCP 1m
Test access to Blue (if using Minikube):
minikube ip # Get Minikube node IP (e.g., 192.168.99.100)
curl http://<minikube-ip>:30080 # Should return Blue app content
5. Step 2: Deploy the “Green” Environment (New Version)
Now, deploy the Green environment with the updated application version. Green will run in parallel with Blue but will not receive traffic until validated.
5.1 Create the Green Deployment
Create green-deployment.yaml (similar to Blue, but with version: green and the new app image):
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
labels:
app: my-app
version: green # Unique label for Green environment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: green
template:
metadata:
labels:
app: my-app
version: green # Pod labels for Green
spec:
containers:
- name: my-app
image: nginx:1.23 # New version (e.g., your-node-app:v2)
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Key Difference: version: green and image: nginx:1.23 (the new version).
Deploy Green:
kubectl apply -f green-deployment.yaml
Verify Green pods are running (no traffic yet!):
kubectl get pods -l version=green
Output:
NAME READY STATUS RESTARTS AGE
app-green-6d8f7c2e4a-1b2c3 1/1 Running 0 1m
app-green-6d8f7c2e4a-4d5e6 1/1 Running 0 1m
app-green-6d8f7c2e4a-7g8h9 1/1 Running 0 1m
5.2 Validate Green Before Switching Traffic
Before routing traffic to Green, validate it thoroughly (e.g., smoke tests, integration tests, or manual checks).
Test Green locally using kubectl port-forward (bypasses the service to directly access Green pods):
# Get a Green pod name (replace with your pod name)
GREEN_POD=$(kubectl get pods -l version=green -o jsonpath='{.items[0].metadata.name}')
# Forward port 8080 on your machine to port 80 on the Green pod
kubectl port-forward $GREEN_POD 8080:80
In a new terminal, test:
curl http://localhost:8080 # Should return Green app content (new version)
Alternatively, check logs to ensure no errors:
kubectl logs $GREEN_POD
Critical: Only proceed to switch traffic if Green passes all tests!
6. Step 3: Switch Traffic from Blue to Green
Once Green is validated, update the service’s label selector to route traffic from Blue to Green. This is the “switch” moment—fast and atomic.
6.1 Update the Service Selector
Edit the my-app-service to point to version: green instead of version: blue.
Option 1: Edit the service directly (interactive):
kubectl edit service my-app-service
In the editor, find the spec.selector section and update version: blue to version: green:
spec:
selector:
app: my-app
version: green # Changed from "blue"
ports:
- port: 80
targetPort: 80
nodePort: 30080
Save and exit the editor.
Option 2: Apply an updated service manifest (declarative):
Update app-service.yaml with version: green and reapply:
kubectl apply -f app-service.yaml # Now with selector: version: green
6.2 Verify Traffic Routing
Check that the service now routes to Green pods by inspecting its endpoints (Kubernetes automatically updates endpoints when selectors change).
kubectl describe service my-app-service | grep Endpoints
Output should show Green pod IPs (not Blue):
Endpoints: 10.244.0.15:80,10.244.0.16:80,10.244.0.17:80 # Green pod IPs
Test access again (same URL as before):
curl http://<minikube-ip>:30080 # Now returns Green app content (new version)
Success! Traffic is now fully routed to Green. The Blue environment is still running but idle (no traffic).
7. Rollback Strategy: Switching Back to Blue
If issues are detected with Green (e.g., errors, performance problems), roll back immediately by switching the service selector back to Blue.
Repeat Step 6.1, but set version: blue in the service selector:
kubectl edit service my-app-service # Change selector to version: blue
Verify endpoints switch back to Blue pods:
kubectl describe service my-app-service | grep Endpoints # Should show Blue pod IPs
Traffic is now routed to Blue again—downtime is minimized (typically a few seconds).
8. Best Practices for Blue/Green Deployments in Kubernetes
- Use Distinct Labels: Always use unique labels (e.g.,
version: blue/green) to avoid accidental traffic leakage. - Test Green Thoroughly: Validate Green with the same traffic patterns as Blue (e.g., load testing, canary tests) before switching.
- Monitor Both Environments: Use tools like Prometheus/Grafana to monitor metrics (latency, error rates) for Blue and Green during deployment.
- Automate with GitOps: Use tools like ArgoCD or Flux to automate deployment of Blue/Green environments and selector updates.
- Clean Up Idle Environments: After confirming Green is stable, delete the Blue deployment to free resources (unless you need it for rollback).
- Idempotent Deployments: Ensure deployments are repeatable (e.g., use immutable image tags like
v2.1.0instead oflatest).
9. References
- Kubernetes Services Documentation
- Kubernetes Deployments Documentation
- Blue/Green Deployments on Kubernetes (AWS Blog)
- ArgoCD Rollouts (Blue/Green Automation)
- Kubernetes Label Selectors
By following this tutorial, you’ve implemented a robust Blue/Green deployment pipeline in Kubernetes, enabling safe, low-downtime releases and quick rollbacks. Let us know in the comments if you have questions or tips! 🚀