Progressive Canary Release with Traffic Segmentation¶
You will create the following resources in this tutorial.
- Knative services implementing an app with
- An Istio virtual service which routes requests based on an HTTP header called
country. All requests are routed to the
baseline, except those with their
countryheader field set to
wakanda; these may be routed to the
- Two curl-based traffic generators which simulate user requests; one of them sets the
countryHTTP header field in its requests to
wakanda, and the other sets it to
- An Iter8 experiment which verifies that the
candidatesatisfies mean latency, 95th percentile tail latency, and error rate
objectives, and progressively increases the proportion of traffic with
country: wakandaheader that is routed to the
Before you begin, you will need...
Kubernetes cluster with Iter8, Knative and Istio: Ensure that you have a Kubernetes cluster with Iter8, Knative with the Istio networking layer, Prometheus add-on, and Iter8's sample metrics for Knative installed. You can do so by following Steps 1, 2, 3 and 6 of the quick start tutorial for Knative, and selecting Istio during Step 3.
Cleanup: If you ran an Iter8 tutorial earlier, run the associated cleanup step.
ITER8 environment variable: Ensure that
ITER8 environment variable is set to the root directory of your cloned Iter8 repo. See Step 2 of the quick start tutorial for Knative for example.
iter8ctl: This tutorial uses
1. Create versions¶
kubectl apply -f $ITER8/samples/knative/traffic-segmentation/services.yaml
Look inside services.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
2. Create Istio virtual service¶
kubectl apply -f $ITER8/samples/knative/traffic-segmentation/routing-rule.yaml
Look inside routing-rule.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
3. Generate traffic¶
TEMP_DIR=$(mktemp -d) cd $TEMP_DIR curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.8.2 sh - istio-1.8.2/bin/istioctl kube-inject -f $ITER8/samples/knative/traffic-segmentation/curl.yaml | kubectl create -f - cd $ITER8
Look inside curl.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
4. Create Iter8 experiment¶
kubectl wait --for=condition=Ready ksvc/sample-app-v1 kubectl wait --for=condition=Ready ksvc/sample-app-v2 kubectl apply -f $ITER8/samples/knative/traffic-segmentation/experiment.yaml
Look inside experiment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
5. Observe experiment¶
Observe the experiment in realtime. Paste commands from the tabs below in separate terminals.
while clear; do kubectl get experiment request-routing -o yaml | iter8ctl describe -f - sleep 4 done
The output will look similar to the iter8ctl output in the quick start instructions.
As the experiment progresses, you should eventually see that all of the objectives reported as being satisfied by both versions. The candidate is identified as the winner and is recommended for promotion. When the experiment completes (in ~ 2 mins), you will see the experiment stage change from
kubectl get experiment request-routing --watch
The output will look similar to the kubectl get experiment output in the quick start instructions.
When the experiment completes (in ~ 2 mins), you will see the experiment stage change from
kubectl get vs routing-for-wakanda -o json --watch | jq .spec.http.route
The output shows the traffic split for the wakanda as defined in the
As the experiment progresses, you should see traffic progressively shift from host
sample-app-v1.default.svc.cluster.local to host
sample-app-v2.default.svc.cluster.local. When the experiment completes, the traffic remains split; this experiment has no finish action to promote the winning version.
Understanding what happened
You configured two Knative services corresponding to two versions of your app in
example.comas the HTTP host in this tutorial.
- Note: In your production cluster, use domain(s) that you own in the setup of the virtual service.
You set up an Istio virtual service which mapped the Knative services to this custom domain. The virtual service specified the following routing rules: all HTTP requests to
example.comwith their Host header or :authority pseudo-header not set to
wakandawould be routed to the
baseline; those with
wakandaHost header or :authority pseudo-header may be routed to
The percentage of
wakandanrequests sent to
candidateis 0% at the beginning of the experiment.
You generated traffic for
curl-job with two
curl-containers to simulate user requests. You injected Istio sidecar injected into it to simulate traffic generation from within the cluster. The sidecar was needed in order to correctly route traffic. One of the
curl-containers sets the
countryheader field to
wakanda, and the other to
- Note: You used Istio version 1.8.2 to inject the sidecar. This version of Istio corresponds to the one installed in Step 3 of the quick start tutorial. If you have a different version of Istio installed in your cluster, change the Istio version during sidecar injection appropriately.
You created an Iter8
Progressivedeployment pattern to evaluate the
candidate. In each iteration, Iter8 observed the mean latency, 95th percentile tail-latency, and error-rate metrics collected by Prometheus, and verified that the
candidateversion satisfied all the
objectivesspecified in the experiment. It progressively increased the proportion of traffic with
country: wakandaheader that is routed to the
kubectl delete -f $ITER8/samples/knative/traffic-segmentation/experiment.yaml kubectl delete -f $ITER8/samples/knative/traffic-segmentation/curl.yaml kubectl delete -f $ITER8/samples/knative/traffic-segmentation/routing-rule.yaml kubectl delete -f $ITER8/samples/knative/traffic-segmentation/services.yaml