Kubernetes - Blue/Green Deployment


This deployment is widely used across the companies. Its based on ACTIVE/PASSIVE concept.

We are going to create a deployment with the image - rajasekar/node-web-v1 of 3 replicas and bind to a service IP.

Next, We are going to create another deployment with the image rajasekar/node-web-v2 and enable this deployment in the service IP - aka IP cutover.

Make a note of the labels I am using in the deployment: app: nodejs and version: "1.0"


apiVersion: apps/v1

kind: Deployment

metadata:

  name: node-app-v1

  labels:

    app: node-app

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nodejs

      version: "1.0"

  template:

    metadata:

      labels:

        app: nodejs

        version: "1.0"

    spec:

      containers:

      - name: nodejs-v1

        image: rajasekar/node-web-v1:latest

        imagePullPolicy: Never

        ports:

        - containerPort: 8080


root@masterk8s:/kube# kubectl get pods

NAME                           READY   STATUS    RESTARTS   AGE

node-app-v1-66945646db-9q78p   1/1     Running   0          69s

node-app-v1-66945646db-lh5q6   1/1     Running   0          69s

node-app-v1-66945646db-qvkp4   1/1     Running   0          69s

root@masterk8s:/kube#


Lets bind a service IP of type NodePort to it.


root@masterk8s:/kube# kubectl expose deployment node-app-v1 --type NodePort --port 8080 --target-port 8080 --name node-svc

service/node-svc exposed

root@masterk8s:/kube#


root@masterk8s:/kube# kubectl describe svc node-svc

Name:                     node-svc

Namespace:                default

Labels:                   app=node-app

Annotations:              <none>

Selector:                 app=nodejs,version=1.0

Type:                     NodePort

IP Family Policy:         SingleStack

IP Families:              IPv4

IP:                       10.99.189.136

IPs:                      10.99.189.136

Port:                     <unset>  8080/TCP

TargetPort:               8080/TCP

NodePort:                 <unset>  30080/TCP

Endpoints:                10.244.1.25:8080,10.244.1.26:8080,10.244.1.27:8080

Session Affinity:         None

External Traffic Policy:  Cluster

Events:                   <none>

root@masterk8s:/kube#


Lets test the endpoint:


root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v1-66945646db-lh5q6

root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v1-66945646db-9q78p

root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v1-66945646db-qvkp4

root@masterk8s:/kube# 


Now, Lets move on to GREEN deployment with the image: rajasekar/node-web-v2.

Here I have changed the version to 2.0 and referring to new image.


apiVersion: apps/v1

kind: Deployment

metadata:

  name: node-app

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nodejs

  template:

    metadata:

      labels:

        app: nodejs

        version: "2.0"

    spec:

      containers:

      - name: nodejs-v2

        image: rajasekar/node-web-v2:latest

        imagePullPolicy: Never

        ports:

        - containerPort: 8080


root@masterk8s:/kube# kubectl get pods

NAME                           READY   STATUS    RESTARTS   AGE

node-app-v1-66945646db-9q78p   1/1     Running   0          4m19s

node-app-v1-66945646db-lh5q6   1/1     Running   0          4m19s

node-app-v1-66945646db-qvkp4   1/1     Running   0          4m19s

node-app-v2-78c686cc57-bm287   1/1     Running   0          4s

node-app-v2-78c686cc57-q2wpt   1/1     Running   0          4s

node-app-v2-78c686cc57-q68dv   1/1     Running   0          4s

root@masterk8s:/kube#


root@masterk8s:/kube# kubectl get deployment

NAME          READY   UP-TO-DATE   AVAILABLE   AGE

node-app-v1   3/3     3            3           4m33s

node-app-v2   3/3     3            3           18s

root@masterk8s:/kube#


root@masterk8s:/kube# kubectl describe deployment node-app-v1 | grep -i selector

Selector:               app=nodejs,version=1.0

root@masterk8s:/kube# kubectl describe deployment node-app-v2 | grep -i selector

Selector:               app=nodejs,version=2.0

root@masterk8s:/kube#


Now, Lets to the cutover.


root@masterk8s:/kube# kubectl patch service node-svc -p '{"spec": {"selector":{"version":"2.0"}}}'

service/node-svc patched

root@masterk8s:/kube# kubectl get ep

NAME         ENDPOINTS                                            AGE

kubernetes   192.168.45.128:6443                                  23h

node-svc     10.244.1.28:8080,10.244.1.29:8080,10.244.1.30:8080   5m46s

root@masterk8s:/kube#


Lets to curl:


root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v2-78c686cc57-q68dvThis is a secure link of version 99.99%

root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v2-78c686cc57-q2wptThis is a secure link of version 99.99%

root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v2-78c686cc57-q2wptThis is a secure link of version 99.99%

root@masterk8s:/kube# curl 10.99.189.136:8080

You've hit node-app-v2-78c686cc57-bm287This is a secure link of version 99.99%

root@masterk8s:/kube#


Nice. We have successfully did a cutover. If anything happens with the new code, then edit the service pointing to version 1.0.

If all works fine. Then scale down Version1.0 deployment and delete it.


Comments

Popular posts from this blog

SRE/DevOps Syllabus

AWS Code Commit - CI/CD Series Part 1

Docker - Preventing IP overlapping