Menu Octopus Deploy

Kubernetes blue/green deployments: the basics and a quick tutorial

What is blue/green deployment in Kubernetes?

Blue/green deployment is a release strategy that minimizes downtime and risk by running two identical environments: blue (current) and green (new). In Kubernetes, this is implemented using multiple deployments and services that represent each environment. The live version (blue) handles production traffic, while the new version (green) is deployed alongside it but receives no user traffic until it’s validated.

Kubernetes enables this model by allowing you to manage pod replicas, label selectors, and services independently for each environment. The switch from blue to green is typically done by updating a service’s selector to point from the old deployment’s label to the new one. This re-routes traffic instantly without restarting pods or requiring downtime. If the new version encounters issues, traffic can be redirected back just as quickly by reversing the service selector.

This is part of a series of articles about Kubernetes management.

Pros and cons of blue/green deployment in Kubernetes

Blue/green deployment offers a reliable way to update applications in Kubernetes with minimal risk and downtime. However, it comes with trade-offs in complexity and resource usage.

Pros:

  • Safe production testing: Green deployments can be tested in a live cluster without exposing them to users, allowing detection of environment-specific issues before a release.
  • Immediate rollbacks on failure: If a problem is found after switching to green, traffic can be quickly redirected back to blue without downtime, minimizing disruption.
  • Downtime-free release promotion: Switching production traffic to a validated green deployment can be done without interrupting user access or restarting services.
  • Operational resilience: The blue/green strategy keeps the stable version live throughout the process, offering a reliable recovery path if needed.
  • Simple traffic control with Kubernetes services: Traffic redirection can be achieved by updating a service selector, which is a native Kubernetes mechanism and requires no external tools.
  • Controlled deployment cycle: Each release runs in isolation, reducing the chance that a deployment affects production unexpectedly.

Cons:

  • All-or-nothing traffic exposure: Blue/green deployments only allow switching all users to the new version; there’s no built-in way to expose features to a subset of users like canary releases do.
  • Schema migration risks: If database schema changes are needed, downtime might still be required unless you implement complex compatibility logic.
  • High resource usage: Running two full versions of the application doubles resource consumption, increasing infrastructure costs.
  • Traffic routing complexity: Mistakes during manual service or ingress updates can cause routing issues or service interruptions.
  • Not ideal for complex systems: Applications with intricate infrastructure requirements may require additional tooling or configuration to make blue/green work effectively.

Quick tutorial: setting up blue/green deployments in Kubernetes using services

Below is a step-by-step guide to setting up a blue/green deployment, including YAML configurations, using Kubernetes services for traffic management.

Step 1: create the blue deployment and service

The blue deployment represents the currently running version of the application. The following YAML file creates a Kubernetes deployment with three replicas running version 1.0 of the application:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      env: blue
  template:
    metadata:
      labels:
        app: nginx
        env: blue
    spec:
      containers:
      - name: nginx
        image: nginx:1.20
        ports:
        - containerPort: 80

Let’s store the above YAML code in a file called blue.yaml. We can deploy it using the following command:

kubectl apply -f blue.yaml

Applying the blue deployment

Some important details about this configuration:

  • The deployment creates three replicas of the nginx:1.20 container.
  • It applies the label { app: nginx, env: blue } to identify the blue environment.
  • It exposes the application on port 80.

Now let’s see how to create a Kubernetes Service to route traffic to the blue deployment. The following YAML defines the blue service:

apiVersion: v1
kind: Service
metadata:
  name: blue
spec:
  selector:
    app: nginx
    env: blue
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Let’s store the above code in a file called blue_service.yaml. We can deploy it using the following command:

kubectl apply -f blue_service.yaml

Applying the blue service

Some important details about the service configuration:

  • This service selects pods with { app: nginx, env: blue }.
  • It routes external requests on port 80 to the blue deployment.

After deploying, verify that the blue environment is running using:

kubectl get pods -l app=nginx,env=blue

Listing the blue deployment pods

This should return a list of running pods for the blue deployment.

Step 2: create the green deployment and service

The green deployment represents the new version of the application but starts with zero replicas:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: green
spec:
  replicas: 0
  selector:
    matchLabels:
      app: nginx
      env: green
  template:
    metadata:
      labels:
        app: nginx
        env: green
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

Let’s store the above YAML code in a file called green.yaml. We can deploy it using the following command:

kubectl apply -f green.yaml

Applying the green deployment

Like the blue service, the green service is defined separately:

apiVersion: v1
kind: Service
metadata:
  name: green
spec:
  selector:
    app: nginx
    env: green
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Store the above code in green_service.yaml. We can deploy it using the following command:

kubectl apply -f green_service.yaml

Note that the green service selects { app: nginx, env: green } to route traffic to green when activated.

Finally, run the following command to verify the green deployment (expected output: zero replicas):

kubectl get pods -l app=nginx,env=green

Verifying the green deployment has zero replicas

Step 3: scale the green deployment

To start serving the new version, scale the green deployment:

kubectl scale deployment green --replicas=3

Scaling the green deployment

This creates three running instances of the green environment.

Before switching, confirm traffic is still directed to the blue deployment:

kubectl describe service blue | grep Endpoints

Checking the blue service endpoints

Before scaling green, you can retrieve the IP address of the blue pods using the following command (once you scale green pods, you will also see the IP addresses of the green pods as well):

kubectl get pods -o custom-columns=POD:metadata.name,IP:status.podIP

Listing pod IP addresses

This should return the IP addresses of the blue deployment pods.

Step 4: switch traffic to the green deployment

Now, update the service to route traffic to the green deployment:

kubectl apply -f green_service.yaml

Switching traffic to the green deployment

Alternatively, update the Ingress or service selector manually:

kubectl patch service blue -p '{"spec": {"selector": {"app": "nginx", "env": "green"}}}'

This command modifies the blue service to point to green, effectively switching all traffic to the new version.

Confirm that requests are now routed to the green deployment:

kubectl describe service green | grep Endpoints

Checking the green service endpoints

The output should display the green deployment’s pod IPs.

Step 5: roll back if needed

If issues arise, roll back by re-routing traffic back to the blue environment:

kubectl patch service blue -p '{"spec": {"selector": {"app": "nginx", "env": "blue"}}}'

This instantly restores traffic to the previous stable version.

Step 6: decommission the blue deployment

Once the green environment is confirmed stable, remove the blue deployment to free resources in your cluster:

kubectl delete deployment blue

Deleting the blue deployment

5 best practices for blue/green deployment in Kubernetes

Here are some useful practices to consider when using blue/green deployments in Kubernetes.

1. Use a service mesh for traffic management

A service mesh like Istio or Linkerd provides fine-grained control over traffic routing, enabling gradual traffic shifts between blue and green environments. Instead of switching traffic all at once, you can use virtual services and destination rules to incrementally direct a percentage of traffic to the green environment. This helps reduce risk and gives teams time to validate the behavior of the new version under real-world load.

Service meshes also enhance observability during deployments by collecting metrics, traces, and logs across environments. These insights allow you to detect anomalies early and take corrective actions before completing the full switchover. Using a service mesh ensures that your deployment process remains controlled, reversible, and transparent.

2. Implement canary releases for rolling updates

Blue/green deployments can be enhanced by incorporating canary releases, which send a small fraction of traffic to the green environment before routing everything. This approach enables you to test the new version with live traffic on a limited scale, helping you detect potential failures without affecting all users. As confidence increases, you can expand the traffic share gradually.

In Kubernetes, this can be managed manually or automated using a service mesh or progressive delivery tools. When combined with monitoring, this method allows teams to spot performance regressions or bugs early, providing an additional safety net before the full traffic switch.

3. Use custom Kubernetes operators

Custom Kubernetes operators can automate many repetitive tasks involved in blue/green deployments, such as spinning up new environments, performing health checks, and switching traffic. These operators extend Kubernetes’ native behavior by encoding deployment logic specific to your applications, ensuring consistency and reducing manual intervention.

By using custom controllers, you can define reconciliation loops that automatically enforce state, manage rollbacks, and integrate with monitoring tools. This is especially useful in large-scale environments, where managing blue/green workflows manually would introduce risk and inefficiency.

4. Conduct load testing

Before routing production traffic to the green environment, it’s critical to perform load testing to validate performance under real conditions. Load testing helps confirm that the new version can handle peak traffic levels and scale appropriately when needed. Without this step, there’s a risk of service degradation after the switch.

Run these tests in the green environment before it goes live, using tools that simulate typical and worst-case usage scenarios. This helps ensure that your application responds predictably, that autoscalers function correctly, and that system behavior under load won’t impact user experience during rollout.

5. Ensure separation with labels and namespaces

Clearly separating blue and green environments using labels or namespaces simplifies management and reduces the risk of accidental misrouting. Labels allow services and ingresses to target the correct pods, while namespaces provide logical isolation for resources such as secrets, configs, and policies.

This separation supports consistent CI/CD pipelines and makes it easier to monitor, debug, and clean up deployments. It also enables parallel testing and rollout, giving teams confidence in their ability to validate changes before exposing them to users.

Related content: Read our guide to Kubernetes rolling deployment (coming soon)

Help us continuously improve

Please let us know if you have any feedback about this page.

Send feedback

Categories:

Next article
Kubernetes in the cloud