Skip to content

Latest commit

 

History

History
124 lines (87 loc) · 7.73 KB

canary_ab_deployment.md

File metadata and controls

124 lines (87 loc) · 7.73 KB

Model deployment to AKS cluster with Canary deployment

Build Status

If your target deployment environment is a Kubernetes cluster and you want to implement Canary and/or A/B testing deployment strategies you can follow this sample guide.

Prerequisites

Before continuing with this guide, you will need:

Install Istio on a K8s cluster

You'll be using the Istio service mesh implementation to control traffic routing between model versions. Follow the instructions at Install and use Istio in Azure Kubernetes Service (AKS).

After Istio is installed, figure out the Istio gateway endpoint on your K8s cluster:

GATEWAY_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

You don't need to create any Istio resources (e.g. Gateway or VirtualService) at this point. It will be handled by the AzDo pipeline that builds and deploys a scoring image.

Set up variables

There are some extra variables that you need to setup in devopsforai-aml-vg variable group (see getting started):

Variable Name Suggested Value Short Description
K8S_AB_SERVICE_CONNECTION mlops-aks Name of the service connection to your Kubernetes cluster
K8S_AB_NAMESPACE abtesting Kubernetes namespace for model deployment
IMAGE_REPO_NAME [Your ACR's DNS name] Image reposiory name (e.g. mlopspyciamlcr.azurecr.io)

Configure a pipeline to build and deploy a scoring Image

Import and run the abtest.yml multistage deployment pipeline.

After the pipeline completes successfully, you will see a registered Docker image in the ACR repository attached to the Azure ML Service:

scoring image

The pipeline creates Istio Gateway and VirtualService and deploys the scoring image to the Kubernetes cluster.

kubectl get deployments --namespace abtesting
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
model-green   1/1     1            1           19h

Build a new Scoring Image

Change value of the SCORE_SCRIPT variable in the abtest.yml to point to scoring/scoreA.py and merge it to the master branch.

Note: scoreA.py and scoreB.py files used in this tutorial are just mockups returning either "New Model A" or "New Model B" respectively. They are used to demonstrate the concept of testing two scoring images with different models or scoring code. In real life you would implement a scoring file similar to score.py (see the Getting Started guide).

It will automatically trigger the pipeline and deploy a new scoring image with the following stages implementing Canary deployment strategy:

Stage Green Weight Blue Weight Description
Blue_0 100 0 New image (blue) is deployed.
But all traffic (100%) is still routed to the old (green) image.
Blue_50 50 50 Traffic is split between old (green) and new (blue) images 50/50.
Blue_100 0 100 All traffic (100%) is routed to the blue image.
Blue_Green 0 100 Old green image is removed. The new blue image is copied as green.
Blue and Green images are equal.
All traffic (100%) is routed to the blue image.
Green_100 100 0 All traffic (100%) is routed to the green image.
The blue image is removed.

Note: The pipeline performs the rollout without any pausing. You may want to configure Approvals and Checks for the stages on your environment for better experience of the model testing. The environment abtestenv will be added automatically to your AzDo project after the first pipeline run.

At each stage you can verify how the traffic is routed sending requests to $GATEWAY_IP/score with Postman or with curl:

curl $GATEWAY_IP/score

You can also emulate a simple load test on the gateway with the load_test.sh:

./charts/load_test.sh 10 $GATEWAY_IP/score

The command above sends 10 requests to the gateway. So if the pipeline has completed stage Blue_50, the result will look like this:

"New Model A"
"New Model A"
"New Model A"
"New Model B"
"New Model A"
"New Model B"
"New Model B"
"New Model A"
"New Model A"
"New Model A"

Regardless of the blue/green weight values set on the cluster, you can perform A/B testing and send requests directly to either blue or green images:

curl --header "x-api-version: blue" $GATEWAY_IP/score
curl --header "x-api-version: green" $GATEWAY_IP/score

or with a load_test.sh script:

./charts/load_test.sh 10 $GATEWAY_IP/score blue
./charts/load_test.sh 10 $GATEWAY_IP/score green

In this case the Istio Virtual Service analyzes the request header and routes the traffic directly to the specified model version.