At the end of this tutorial, you will learn how to;
- Deploy multiple versions of a microservice unto a Kubernetes cluster
- Use Istio Service Mesh to control traffic to various versions of the deployed microservice.
The tutorial assumes that you have provisioned an Ubuntu 20.04 server on Azure. The server should have an 8Gb RAM.
With canary deployment, DevOps Engineers roll out a new version of an application only to a selected group of users. The selected group of users may test and provide feedback to the development team. The update is later rolled out to the remaining group of users once the team is confident the release won't cause issues.
In this tutorial we will demonstrate canary deployment using BookInfo Application. The Bookinfo application is broken into four separate microservices:
- productpage. The productpage microservice calls the details and reviews microservices to populate the page.
- details. The details microservice contains book information.
- reviews. The reviews microservice contains book reviews. It also calls the ratings microservice.
- ratings. The ratings microservice contains book ranking information that accompanies a book review.
There are 3 versions of the reviews microservice:
- Version v1 doesn’t call the ratings service.
- Version v2 calls the ratings service, and displays each rating as 1 to 5 black stars.
- Version v3 calls the ratings service, and displays each rating as 1 to 5 red stars.
Install the latest version of MicroK8s using the command
sudo snap install microk8s --classic
sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube
# Reload user groups
newgrp microk8s
Enable Istio with the following command:
sudo microk8s enable community
sudo microk8s.enable istio
newgrp microk8s
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.15.3
export PATH=$PWD/bin:$PATH
Add a namespace label to instruct Istio to automatically inject Envoy sidecar proxies when you deploy your application later:
microk8s kubectl label namespace default istio-injection=enabled
sudo microk8s kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
sudo microk8s kubectl get pods
sudo microk8s kubectl get services
microk8s kubectl exec "$(microk8s kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
microk8s kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
microk8s kubectl get svc istio-ingressgateway -n istio-system
Get INGRESS_PORT
export INGRESS_PORT=$(microk8s kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
Set the SECURE_INGRESS_PORT
export SECURE_INGRESS_PORT=$(microk8s kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
Because our application is running on a remote server, Azure, we have to use the public IP address of the server we provisioned.
export INGRESS_HOST=<your-vm-IP>
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
echo $GATEWAY_URL
Now, we want to make sure that our application is available to the public. To do this, we have to open certain ports on the VM we provisioned. We will only open the INGRESS_PORT for security purposes.
Navigate to the VM created. Under Settings , select Networking. Add a new inbound rule. Destination port should be your INGRESS_PORT. Finally, click on Add.
echo $GATEWAY_URL should give you the IP address and Port your application is running on. In your browser, navigate to htt://$GATEWAY_URL/productpage. You should find your application running.
sudo microk8s kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
After running the above code, go back to your browser and refresh the page several times. You should notice that the Book Reviews section changes certain times you reload the page. This is because there are three versions of the review microservice running.
In a scenario where the DevOps team have just made a new release and would only want to direct a small fraction of the traffic to a particular version of the application, say V3, one can create custom routing rules. For instance, one can configure Istio in such a way that only 10% of the traffic is directed to the latest version of the application.
nano myMeshConfig.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- name: "BookInfo Custom Routing"
route:
- destination:
host: reviews
subset: v1
weight: 70
- destination:
host: reviews
subset: v2
weight: 20
- destination:
host: reviews
subset: v3
weight: 10
Save and close the editor.
In the above configuration, we are sending 70% of the traffic to version 1, 20% to version 2 and 10% to version 3 of the review application.
sudo microk8s kubectl apply -f myMeshConfig.yaml
- V1 No ratings/stars
- V2 Rating with Black stars
- V3 Rating with Red stars