Sling Academy
Home/DevOps/How to Implement Canary Deployments in Kubernetes

How to Implement Canary Deployments in Kubernetes

Last updated: February 01, 2024

Introduction to Canary Deployments

Canary deployments are a strategy for rolling out releases to a subset of users or servers. The goal is to test in the production environment with a small, almost unnoticed, user base to mitigate any impact of new releases. In Kubernetes, canary deployments can provide valuable feedback on the health of your new version with minimal risk to the stability of your application.

Prerequisites

  • A Kubernetes cluster
  • kubectl, the command line tool for Kubernetes
  • Knowledge of Kubernetes concepts like pods, services, deployments

Step-by-Step Instructions

Step 1: Define the Initial Deployment

Before you can implement a canary, you need a baseline deployment. Here is an example of a simple deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myapp:1.0.0

Step 2: Create a Service

Create a service to route traffic to your deployment:

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

This service will act as the entry point for traffic, directing it to the available pods.

Step 3: Deploy the Canary Version

Deploy your canary version by changing the image version:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      track: canary
  template:
    metadata:
      labels:
        app: myapp
        track: canary
    spec:
      containers:
      - name: myapp-container
        image: myapp:2.0.0-canary

Adjust the replica count prevent the canary from receiving too much traffic.

Step 4: Automate Traffic Splitting

You’ll need to define how to split traffic:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - myapp
  http:
  - route:
    - destination:
        host: myapp-deployment
      weight: 90
    - destination:
        host: myapp-canary
      weight: 10

With Istio’s VirtualService, you can direct 10% of the traffic to the canary.

Step 5: Monitor Your Canary

Use Kubernetes’ liveness and readiness probes to monitor your canary’s health:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-canary
spec:
  template:
    spec:
      containers:
      - name: myapp-container
        image: myapp:2.0.0-canary
        ports:
        - containerPort: 9376
        livenessProbe:
          httpGet:
            path: /health
            port: 9376
          initialDelaySeconds: 3
          periodSeconds: 3
        readinessProbe:
          httpGet:
            path: /readiness
            port: 9376
          initialDelaySeconds: 5
          periodSeconds: 5

These probes help ensure the canary is ready to serve traffic and stays healthy.

Step 6: Automate Rollback or Progression

In case of failure, you’ll need to rollback:

kubectl rollback deployment myapp-canary

But if everything goes well, you can gradually shift more traffic:

kubectl set image deployment.v1.apps/myapp-deployment myapp-container=myapp:2.0.0

Then, update the weights in your VirtualService to shift 100% traffic to the new version.

Conclusion

Canary deployments are an essential tool for deploying new software versions with confidence. Implementing them in Kubernetes with precision and planning can help you achieve a higher standard of reliability and continuous delivery.

Next Article: How to Automate Compliance Checks in Kubernetes

Previous Article: How to Use Kubernetes with Vault for Secret Management

Series: Kubernetes Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide