Day 16 of my 90-Day Devops Project: Implementing Canary Deployment

Abigeal AfolabiAbigeal Afolabi
4 min read

Today, I focused on setting up the basics for canary deployment.

Project Overview

In my day 16 project, I established a canary deployment for a simple web app with Docker and kubernetes (minikube). This method basically enables a phased feature rollout minimizing the risks associated with new releases.

My Folder Structure

Day15-canarydeployment/
│
├── app/
│   ├── app.py
│   ├── requirements.txt
│   └── Dockerfile
│
├── canary/
│   ├── canary.py
│   ├── requirements.txt
│   └── Dockerfile
│
├── deployment/
│   └── k8s/
│       ├── deployment.yaml
│       └── service.yaml
│
└── scripts/
    ├── deploy.sh
    └── monitor.sh

Steps to Complete the Project

Step 1: Application Setup

  1. Create the Main Application

    • File: app/app.py
     from flask import Flask

     app = Flask(__name__)

     @app.route('/')
     def home():
         return "Main Application is running!"

     if __name__ == '__main__':
         app.run(host='0.0.0.0', port=5000)
  • Dependencies: Create app/requirements.txt

       Flask==2.0.3
    
  • Dockerize the Application: Create app/Dockerfile

       FROM python:3.9
    
       WORKDIR /app
    
       COPY requirements.txt .
       RUN pip install --no-cache-dir -r requirements.txt
    
       COPY app.py .
    
       EXPOSE 5000
       CMD ["python", "app.py"]
    

Step 2: Canary Application Setup

  1. Create the Canary Application

    • File: canary/canary.py
     from flask import Flask

     app = Flask(__name__)

     @app.route('/')
     def home():
         return "Canary Application is running!"

     if __name__ == '__main__':
         app.run(host='0.0.0.0', port=5001)
  • Dependencies: Create canary/requirements.txt

       Flask==2.0.3
    
  • Dockerize the Canary Application: Create canary/Dockerfile

       FROM python:3.9-slim
    
       WORKDIR /app
    
       COPY requirements.txt .
       RUN pip install --no-cache-dir -r requirements.txt
    
       COPY canary.py .
    
       EXPOSE 5001
       CMD ["python", "canary.py"]
    

Step 3: Kubernetes Deployment

  1. Define all Kubernetes Resources

    • Deployments: Create deployment/k8s/deployment.yaml
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: main-app
     spec:
       replicas: 3
       selector:
         matchLabels:
           app: main-app
       template:
         metadata:
           labels:
             app: main-app
         spec:
           containers:
           - name: main-app
             image: your-docker-repo/main-app:latest
             ports:
             - containerPort: 5000

     ---
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: canary-app
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: canary-app
       template:
         metadata:
           labels:
             app: canary-app
         spec:
           containers:
           - name: canary-app
             image: your-docker-repo/canary-app:latest
             ports:
             - containerPort: 5001
  • Services: Create deployment/k8s/service.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: main-app-service
       spec:
         type: ClusterIP
         selector:
           app: main-app
         ports:
           - port: 80
             targetPort: 5000
    
       ---
       apiVersion: v1
       kind: Service
       metadata:
         name: canary-app-service
       spec:
         type: ClusterIP
         selector:
           app: canary-app
         ports:
           - port: 81
             targetPort: 5001
    

Step 4: Deployment Scripts

  1. Create Deployment Script

    • File: scripts/deploy.sh
     #!/bin/bash

     docker build -t your-docker-repo/main-app:latest ./app
     docker build -t your-docker-repo/canary-app:latest ./canary

     docker push your-docker-repo/main-app:latest
     docker push your-docker-repo/canary-app:latest

     kubectl apply -f deployment/k8s/
  1. Monitoring Script

    • File: scripts/monitor.sh
     #!/bin/bash

     kubectl logs -l app=main-app
     kubectl logs -l app=canary-app
     kubectl get deployments

Note: kindly replace all placeholders with your actual details

Challenges and Solutions

Challenges Encountered

  1. Minikube Not Installed:

    • Initially, the system didn't recognize Minikube because of a PATH issue. To resolve this, I needed to configure the system PATH properly to ensure Minikube was accessible.
  2. Existing Minikube Instance:

    • Minikube detected an existing instance, which prevented me from starting a new cluster. To resolve this, I use the command minikube delete to remove the existing instance, and then I could start a new Minikube cluster using minikube start.
  3. kubectl Configuration:

    • To ensure kubectl could communicate with the Minikube cluster, I needed to configure the kubectl context to use Minikube by running the command kubectl config use-context minikube.

Solutions

  1. Verify Minikube Installation:

    • I used the command "minikube version" to check the Minikube version and ensure its proper installation.
  2. Delete Existing Minikube Cluster:

    • The command minikube delete helped to remove the existing Minikube instance, which allowed me to start a new cluster.
  3. Check VirtualBox:

    • In addition, I confirmed that VirtualBox was properly installed and operational since Minikube relies on its virtual machine.
  4. Start Minikube:

    • After resolving the previous issues, I could start the Minikube cluster using the command minikube start.
  5. Access Logs:

    • To troubleshoot any remaining issues, I checked the Minikube logs using the command minikube logs.

These steps helped me to resolve the challenges I faced during the setup of the Minikube environment for this project.

Expected Results

  • Main Application: When you visit http://localhost:80, you should see the message:
  Main Application is running!
  • Canary Application: When you visit http://localhost:81, you should see the message:
  Canary Application is running!

Conclusion

Canary deployment ensures a gradual rollout of new application features, allowing teams to collect feedback and
Monitor performance before the full release. By addressing challenges with effective solutions, you can reduce risks and maintain stability.
I think it's a great approach, as it helps identify areas for improvement and allows for changes to be made before a complete release.

0
Subscribe to my newsletter

Read articles from Abigeal Afolabi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abigeal Afolabi
Abigeal Afolabi

🚀 Software Engineer by day, SRE magician by night! ✨ Tech enthusiast with an insatiable curiosity for data. 📝 Harvard CS50 Undergrad igniting my passion for code. Currently delving into the MERN stack – because who doesn't love crafting seamless experiences from front to back? Join me on this exhilarating journey of embracing technology, penning insightful tech chronicles, and unraveling the mysteries of data! 🔍🔧 Let's build, let's write, let's explore – all aboard the tech express! 🚂🌟 #CodeAndCuriosity