Canary deployments using Argo Rollouts and Istio

how to rollout software releases safely

Overview

In the modern software continuous delivery practices canary deployments is one of the most adopted strategic tactic which reduces the risk involved with releasing new software versions.

Implementation

We will refer appAand appB as two example mirco-services and both are running inside Istio service mesh under namespace nsA and nsB respectively. Application appA receives public traffic i.e via internet and also, it receives internal traffic i.e within mesh from application appB .

Prerequisite

There are two prerequisite steps which needs to be done as explained below:

apiVersion: v1
kind: Service
metadata:
name: appA-stable-service
labels:
...
annotations:
...
spec:
ports:
...
---

apiVersion: v1
kind: Service
metadata:
name: appA-canary-service
labels:
...
annotations:
...
spec:
ports:
...
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-appA
namespace: nsA
spec:
hosts:
- appA.nsA.svc.cluster.local
- appA.domain.com
exportTo:
- "*"
gateways:
- appA-ingress-gateway.nsA.svc.cluster.local
- mesh
http:
- name: appA-http-route
match:
- uri:
prefix: /
route:
- destination:
host: appA-stable-service
port:
number: 80
weight: 100
- destination:
host: appA-canary-service
port:
number: 80
weight: 0
  • exportTo : Being set to * represents that this virtual service configuration should be exposed to all namespaces.
  • gateways : virtual service configuration will be applied on the traffic emerges from the list of gateways or envoy proxies of Istio mentioned under gateways given hostname is one of the domains mentioned under hosts .
    We have appA-ingress-gateway.nsA.svc.cluster.local which is ingress gateway for public traffic and mesh which applies to all istio sidecars within mesh.
  • In httproutes, traffic being diverted to stable k8s service with weight 100% and 0% set on canary k8s service.

Configure Argo Rollout object

Now we have both k8s services and istio virtual service ready, its time to see how Argo Rollout object is configured.
A Rollout is Kubernetes workload resource which is equivalent to a Kubernetes Deployment object. Here, we are going to configure canary style as strategy and by using Istio as traffic shaping/switching between stable vs canary version of application.

apiVersion: argoproj.io/v1alpha1 
kind: Rollout
metadata:
...
spec:
...
template:
metadata:
...
spec:
...
strategy:
canary:
maxUnavailable: 0
maxSurge: 3
steps:
- setWeight: 20
- pause: {duration: 1m}
- setWeight: 40
- pause: {duration: 1m}
- setWeight: 60
- pause: {duration: 1m}
- setWeight: 80
- pause: {duration: 1m}
stableService: appA-stable-service # stable k8 service
canaryService: appA-canary-service # canary k8 service
trafficRouting:
istio:
virtualService:
name: virtual-service-appA # istio virtual service
routes:
- appA-http-route # route name
  • stableService : Stable k8s service pointing to stable replica set.
  • canaryService : Canary k8s service pointing to canary replica set.
  • trafficRouting : To use Istio virtual service and its routes to divert the traffic between stable and canary replica set.

What Argo Rollouts Controller does during deployment

When the new deployment is triggered for application appA, the following things happens in the given order:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-appA
namespace: nsA
spec:
hosts:
...
exportTo:
- "*"
gateways:
...
http:
- name: appA-http-route
match:
- uri:
prefix: /
route:
- destination:
host: appA-stable-service
port:
number: 80
weight: 80
- destination:
host: appA-canary-service
port:
number: 80
weight: 20

SRE and Platform Engineering @ rokt.com | Sydney | Australia

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store