Kubernetes: How Blue-Green Deployment works?
- Ingress now
- Jun 27, 2023
- 4 min read
Updated: Apr 29, 2024

Blue-green deployment involves simultaneously operating two application environments within a production cluster. In this deployment approach, the stable version of the application is deployed in the first environment (blue), while the new version is deployed in the second environment (green).
Kubernetes Blue Green Deployments
By default, Kubernetes performs a rolling update of a deployment. As part of the rollout process, the old version is replaced with the new version once the new version is up and running successfully. This happens without any interruption or very minimal impact. For specific applications, it may be necessary to maintain the old version in a “standby” mode for a period of time following the rollout of the new version. So that you can quickly switch to the older version in fraction of seconds.
In Kubernetes, you can achieve blue-green deployment by creating two identical environments, each with its own set of pods and services, and using a load balancer to route traffic between them. You can then deploy the new version of your software to the green environment and test it. Once you are satisfied that the new version is working correctly, you can switch the load balancer to route traffic to the green environment and make it the new live production environment. The blue environment then becomes the new test environment for future updates.
1. Let’s deploy a new service in kubernetes. Create a manifest to deploy the nginx service.
uxpro-$ kubectl create deploy app1-blue --image=nginx:1.22.0 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: app1
name: app1-blue
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: app1
spec:
containers:
- image: nginx:1.22.0
name: nginx
resources: {}
status: {}
we can redirect the manifest to the file to edit it later.
uxpro-$ kubectl create deploy app1-blue --image=nginx --dry-run=client -o yaml > app1_deploy.yaml
2. Update the label like below. [ track: blue]
uxpro-$ cat app1_deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: app1
track: bluename: app1-blue
spec:
replicas: 1
selector:
matchLabels:
app: app1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: app1
spec:
containers:
- image: nginx:1.22.0
name: nginx
resources: {}
status: {}
3. Deploy the service using the updated manifest.
uxpro-$ kubectl create -f app1_deploy.yaml
deployment.apps/app1-blue created
uxpro-$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
app1-blue 1/1 1 1 2m1s
uxpro-$
uxpro-$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/app1-blue-58b85b46d9-5gkzp 1/1 Running 0 90s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/app1 NodePort 10.96.96.163 <none> 80:31288/TCP 68m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/app1-blue 1/1 1 1 90s
NAME DESIRED CURRENT READY AGE
replicaset.apps/app1-blue-58b85b46d9 1 1 1 90s
uxpro-$
4. Expose the nginx service to nodeport. In real production environment, you will have ingress setup to do that.
uxpro-$ kubectl expose --type=NodePort deployment app1 --port 80
service/app1 exposed
uxpro-$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app1 NodePort 10.96.96.163 <none> 80:31288/TCP 8s
uxpro-$
5. Try to access the “nginx” instance from the node IP & port 31288.
root@k8s119-worker:/# curl 172.18.0.2:31288
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<h1> You are viewing Blue Deployment </h1>
</body>
</html>
6. Create a green deployment manifest like below.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: app1
track: green
name: app1-green
spec:
replicas: 1
selector:
matchLabels:
app: app1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: app1
spec:
containers:
- image: nginx:1.22.1
name: nginx
resources: {}
status: {}
7. Create a green deployment with an updated image version.
uxpro-$ kubectl create -f app1_deploy_v2.yaml
deployment.apps/app1-green created
uxpro-$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/app1-blue-58b85b46d9-5gkzp 1/1 Running 0 8m55s
pod/app1-green-584f6b67c4-v88lb 1/1 Running 0 3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/app1 NodePort 10.96.96.163 <none> 80:31288/TCP 75m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/app1-blue 1/1 1 1 8m55s
deployment.apps/app1-green 1/1 1 1 3s
NAME DESIRED CURRENT READY AGE
replicaset.apps/app1-blue-58b85b46d9 1 1 1 8m55s
replicaset.apps/app1-green-584f6b67c4 1 1 1 3s
8. Currently we have two deployments up and running. But traffic is going to the blue deployments. To route the traffic to green deployment, we need to update the service.
uxpro-$ kubectl edit service/app1
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2023-03-26T01:16:56Z"
labels:
app: app1
track: green
name: app1
namespace: default
resourceVersion: "949529"
selfLink: /api/v1/namespaces/default/services/app1
uid: ab2c9599-fa53-4798-85ee-66eb49210c88
spec:
clusterIP: 10.96.96.163
externalTrafficPolicy: Cluster
ports:
- nodePort: 31288
port: 80
protocol: TCP
targetPort: 80
selector:
app: app1
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
uxpro-$ kubectl edit service/app1
service/app1 edited
uxpro-$
9. Try to access the “nginx” instance from the node IP & port 31288.
root@k8s119-worker:/# curl 172.18.0.2:31288
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<h1> You are viewing GREEN Deployment </h1>
</body>
</html>
root@k8s119-worker:/#
We have successfully re-routed the traffic from blue deployments to green deployments. Kubernetes doesn’t support blue-green natively and we have duplicated the deployments to achieve this strategy. By using the blue-green deployment model, we can quickly re-route the traffic to the old deployment in case of any issues.
The drawback of this deployment strategy is resource duplication. It requires more resources since we are running two versions in parallel.
Comments