Kubernetes - Canary Deployment

 

What is canary ?

Testing out a new feature or upgrade in production is a stressful process. 

You want to roll out changes frequently but without affecting the user experience. 

To minimize downtime during this phase, set up canary deployments to streamline the transition.

When you add the canary deployment to a Kubernetes cluster, it is managed by a service through selectors and labels.

The service routes traffic to the pods that have the specified label. 

This allows you to add or remove deployments easily.

The amount of traffic that the canary gets corresponds to the number of pods it spins up. 

I am going to create a nginx deloyment with the below specification:

1) Nginx image version 1.14.2.

2) Deployment with the labels: app: nginx and version: "1.0"

3) Replicas 3.

4) Updating HTML content as "I am on POD V.10"

apiVersion: apps/v1

kind: Deployment

metadata:

 name: nginx

spec:

 selector:

  matchLabels:

   app: nginx

 replicas: 3

 template:

  metadata:

   labels:

    app: nginx

    version: "1.0"

  spec:

   containers:

    - name: nginx

      image: nginx:1.14.2

root@masterk8s:/docker# kubectl apply -f nginx.yml

deployment.apps/nginx created

root@masterk8s:/docker#

root@masterk8s:/docker# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
nginx-ccc5cb887-2mjj7   1/1     Running   0          47s   10.244.1.29   worker01   <none>           <none>
nginx-ccc5cb887-spjmj   1/1     Running   0          47s   10.244.1.30   worker01   <none>           <none>
nginx-ccc5cb887-ztk7q   1/1     Running   0          48s   10.244.1.31   worker01   <none>           <none>
root@masterk8s:/docker#

Test the pods using curl:

root@masterk8s:/docker# curl 10.244.1.29:80
I am pod1 v1.0
root@masterk8s:/docker# curl 10.244.1.30:80
I am pod2 v1.0
root@masterk8s:/docker# curl 10.244.1.31:80
I am pod3 v1.0
root@masterk8s:/docker#

Now, associating service to the deployment with label app: nginx and version: "1.0"

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
    version: "1.0"
  ports:
    - port: 8888
      targetPort: 80

root@masterk8s:/docker# kubectl apply -f svc.yml
service/nginx-service created
root@masterk8s:/docker#

root@masterk8s:/docker# kubectl get svc | grep -i nginx
nginx-service   NodePort    10.98.233.115   <none>        8888:31382/TCP   24s
root@masterk8s:/docker#

10.98.233.115 is the Service IP. Lets test it by hitting the Service IP.

root@masterk8s:/docker# curl 10.98.233.115:8888
I am pod1 v1.0
root@masterk8s:/docker# curl 10.98.233.115:8888
I am pod2 v1.0
root@masterk8s:/docker# curl 10.98.233.115:8888
I am pod3 v1.0
root@masterk8s:/docker#

We are done with first deployment. I am going to create another deployment with nginx version "LATEST" with the labels app: nginx and version: "2.0"

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-canary-deployment
spec:
 selector:
  matchLabels:
   app: nginx
 replicas: 1
 template:
  metadata:
   labels:
    app: nginx
    version: "2.0"
  spec:
   containers:
    - name: nginx
      image: nginx:latest

The HTML content will be "CANARY TEST POD".

root@masterk8s:/docker# kubectl apply -f nginx_new.yml
deployment.apps/nginx-canary-deployment created
root@masterk8s:/docker#

root@masterk8s:/docker# curl 10.244.1.32:80
CANARY POD
root@masterk8s:/docker#

Now, We are done with the CANARY deployment.


To add canary deployment to service, We need to remove the label version:1.0.

Post removing that SVC is created/mapped to the deployments with the labels "app":"nginx".

Since, deployment1 and 2 are having the same label SVC will be taking traffic on both the deployments.

Lets curl.
















Comments

Popular posts from this blog

SRE/DevOps Syllabus

AWS Code Commit - CI/CD Series Part 1

Docker - Preventing IP overlapping