Site icon UnixArena

Kubernetes: How Blue-Green Deployment works?

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.

In this article, we will walk you through how blue-green deployments works using Kubernetes primitives.

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: blue
  name: 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.

Hope this article is informative to you.

Exit mobile version