canary deployment in kubernetes

Canary deployment is an upgraded version of an existing deployment, with all the required application code and dependencies. It is used to test out new features and upgrades to see how they handle the production environment.


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. In most cases, you start by routing a smaller percentage of traffic to the canary and increase the number over time.

Step 1: Pull Docker Image

*Download the image with

# docker pull nginx

Status: Downloaded newer image for nginx:latest

once we did we get the output like above.


*Verify you have it by listing all local images:

# docker image ls

REPOSITORY             TAG           IMAGE ID       CREATED         SIZE

19_04_react            latest        3457c011a6   2 days ago      1.11GB

centos1_ansible        latest        20af1303e   5 days ago      1.05GB

nginx                  latest        62d49f9b  7 days ago      133MB


Step 2: Create the Kubernetes Deployment

Create the deployment definition using a yaml file. Use a text editor of your choice and provide a name for the file

#vi nginx-deployment.yaml

*Add the following content to the file

# cat nginx-deployment.yaml

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:alpine

      resources:

      limits:

       memory: "128Mi"

       cpu: "50m"

      ports:

      - containerPort: 80

      volumeMounts:

      - mountPath: /usr/share/nginx/html

        name: index.html

      volumes:

      - name: index.html

        hostPath:

          path: /Users/sofija/Documents/nginx/v1


We created 3 replicas of Nginx pods for the Kubernetes cluster. All the pods have the label version: “1.0”. Additionally, they have a host volume containing the index.html mounted to the container. The sample HTML file consisting of

Hello World!

This is version 1

*Save and exit the file.

*Create the deployment by running below command

# kubectl apply -f nginx-deployment.yaml

*Check whether we have successfully deployed the pods with:

# kubectl get pods -o wide

The output should display three running Nginx pods.


Step 3: Create the Service

The next step is to create a service definition for the Kubernetes cluster. The service will route requests to the specified pods.

Create a new yaml file with

# cat nginx-deployment.service.yaml

apiVersion: v1

kind: Service

metadata:

 name: nginx-service

spec:

 type: LoadBalancer

selector:

 app: nginx

 version: "1.0"

ports:

- port: 8888

  targetPort: 80

*Save and exit the service file.

*Let's create the service:

# kubectl apply -f nginx-deployment.service.yaml


Step 4: Check First Version of Cluster

To verify the service is running, open a web browser, and navigate to the IP and port number defined in the service file.

To see the external IP address of the service, use the command:

# kubectl get service

If you are running Kubernetes locally, use localhost as the IP.

The browser should display a Hello World message from version 1


Step 5: Create a Canary Deployment

With version 1 of the application in place, we deploy version 2, the canary deployment.

*Start by creating the yaml file for the canary deployment.

# cat nginx-canary-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

 name: nginx-canary-deployment

spec:

 selector:

  matchLabels:

   app: nginx

 replicas: 3

 template:

  metadata:

   labels:

    app: nginx

    version: "2.0"

  spec:

   containers:

    - name: nginx

      image: nginx:alpine

      resources:

      limits:

       memory: "128Mi"

       cpu: "50m"

      ports:

      - containerPort: 80

      volumeMounts:

      - mountPath: /usr/share/nginx/html

        name: index.html

      volumes:

      - name: index.html

        hostPath:

          path: /Users/sofija/Documents/nginx/v2

*Save and exit the file.

The content of the canary deployment file differs by three important parameters:

*The name in the metadata is nginx-canary-deployment.

*It has the label version: “2.0”.

*It is linked to an HTML file index.html which consists of

Hello World!

This is version 2


*Create the canary deployment with the below command

# kubectl apply -f nginx-canary-deployment.yaml


*Verify that successfully deployed the three additional pods

# kubectl get pods -o wide

The output should display the Nginx canary deployment pods, along with the original Nginx pods.


Step 6: Run the Canary Deployment

To test out the updated pods, we need to modify the service file and direct part of the traffic to version: “2.0”

*To do so, open the yaml file with, Find and remove the line version: “1.0”

# cat nginx-deployment.service.yaml

apiVersion: v1

kind: Service

metadata:

 name: nginx-service

spec:

 type: LoadBalancer

selector:

 app: nginx

 version: "2.0"

ports:

- port: 8888

  targetPort: 80

*Save the changes and exit the file


*Create the updated service with the below command:

# kubectl apply -f nginx-deployment.service.yml

The traffic is now split between version 1 and version 2 pods. If we refresh the web page a few times, we see different results depending on where the service redirects your request.


Roll Back Canary Deployment

If we notice the canary is not performing as expected, we can roll back the deployment and delete the upgraded pods with:

# kubectl delete deployment.apps/nginx-canary-deployment

The service continues load balancing the traffic to the initial version 1 pods.


Roll Out Upgraded Deployment

If we conclude the canary deployment is performing as expected, we can route all incoming traffic to the upgraded version. There are three ways to do so:

*Upgrade the first version by modifying the Docker image and building a new deployment. Then, remove the canaries with

#kubectl delete deployment.apps/nginx-canary-deployment

*we can keep the upgraded pods and remove the ones with the version 1 label

#kubectl delete deployment.apps/nginx

we can also modify the service.yaml file and add the version specifier to the selector label. This instructs the load balancer to only route traffic to version 2 pods.




Relevant Blogs:

Secrets 

Multi container pod

Kubernetes cluster provisioning in lxc  

Nagios installation and configuration

Recent Comments

No comments

Leave a Comment