Canary deployment with Istio

This post describes how to create canary deployment use Istio service mesh. This is a first post about service mesh in kubernetes cluster. After reading you’ll know how to create a canary deployment in Istio service mesh.

Why canary deployment?

Deployment is a common task for DevOps engineer. During my career I created a lot of deployment pipelines. Usually I used two most popular deployment methods, blue – green and rolling release. Rolling release is a deployment method when services are replaced service by service. Sometimes I want to deploy new version of application and change traffic to new one.
In one of my project developers ask me to provide more complex deployment method. They want to show new version to group of users before full upgrade. I decided to use canary deployment, that means split traffic between two versions based on probability.

Image shows how to canary deployment works, 90% of traffic goes to version v1, 10% to v2.

Canary deployment implementation with Istio

This is very simple scenario for testing purposes. 🙂

First of all, of course we need a service and deployment. I’ve created sample app esio with two deployments, one for version v1, one for v2.
Application yaml:

After deployed app.yaml I have a service and two deployments esio-v1 and esio-v2 with different versions of my app. I use my debug_server application that is very good for demonstration. Instead of different app versions I use v1 and v2 application name.
When application is up and running I can move forward to Istio specific part.

I create a Gateway, VirtualService and DestinationRule. There are important Istio networking components.
Gateway is a load balancer on the edge of service mesh. In most cases default Istio controller is enough . I can decide which traffic comes to Istio mesh using servers definitions.
VirtualService is using for choose which traffic comes to specific virtual service. This is something like kubernetes ingress but with a lot of additional features.
DestinationRule describes what happens with traffic for specific destination. I use it to select application version connected to specific subset.

Lets analyze my example code hosted on gitlab:
I created Gateway that allows inbound traffic on port 80 and VirtualService that listens on “/” and “/esio” endpoints. Both are connected to the same host.

kind: VirtualService
  name: esio
  - "*"
  - esio-gateway
  - match:
    - uri:
        prefix: /
    - uri:
        prefix: /esio
    - destination:
        host: esio-svc
        subset: v1
          number: 8080
      weight: 90
    - destination:
        host: esio-svc
        subset: v2
          number: 8080
      weight: 10

I use weight and subset to decide which part of traffic should come to specific subset. In DestinationRule I described subset and version relation.

Finally I can test my solution using curl.

Looks like everything is working and sometimes (I hope in 10% of cases) I get v2 version.

Code repository:

Leave a Reply

Your email address will not be published. Required fields are marked *