This section describes the Canary Deployment Tutorial for Istio
Canary deployments help introduce new versions of services because they provide a way to deploy new features gradually. When an update rolls out, it’s released to a small subset of users in stages. This allows developers to see how the update is performing before making it available to everyone.
How Do I Perform a Canary Deployment on Istio? Kubernetes is designed to perform canary deployments locally. However, the downside of this approach is that throttling traffic for Canary deployments (by changing the replica ratio) needs to be done manually. The solution to simplify this process is to use a service mesh, such as open-source Istio, to decouple traffic distribution and replica counting.
In this tutorial, you’ll learn how to deploy a canary version of your application in an Istio-enabled cluster and set up Istio to control traffic routing.
Prerequisite
- Kubernetes cluster (minikube)
- kubectl command-line tool
- Istio is installed
- Docker Hub account
- Grafana dashboard
Step 1: Build Docker images and containers for the canary build
How Do I Use Istio to Perform a Canary Deployment? To start deploying the canary version of your app, first create a docker image that contains the version you want to deploy.
- Go to the directory that contains the files you need for your image. The example uses an application called test-canary, stored in a directory with the same name:
cd test-canary
2. Use the docker build
command to build a Docker image. Execute the command using your Docker Hub username and image name:
docker build -t [dockerhub-username]/test-canary .
The output confirms that the image has been created successfully.
3. Use the docker images
command to look at your list of images and check if the new image is in it:
docker images
4. Next, use the docker run
command to build a container using the image you created earlier. Give the container a name and select an access port:
docker run --name [name] -p [port]:8080 -d [dockerhub-username]/test-canary
If the operation is successful, the full ID of the newly created container is output:
5. Use the docker ps
command to see the running container:
docker ps
6. Now access it through your browser using the port you assigned to the container:
http://localhost:[port]
The browser displays the contents of the application:
Istio Executes the Canary Deployment Tutorial
7. Once you have confirmed that the application is working properly, use the docker stop
command to stop the container. Add the container ID to the command, and you can copy it from the first column of docker ps
output:
docker stop [container-id]
8. Finally, to push the image to your Docker Hub account, log in to Docker Hub using the command line:
docker login -u [dockerhub-username]
You will be asked to enter your password. Enter your password and press Enter:
9. Now push the image docker push
with the following command:
docker push [dockerhub-username]/test-canary
Note: Please visit our article on the most common Docker commands and download our PDF cheat sheet for future reference.
Step 2: Modify the app deployment
How Do I Use Istio to Perform a Canary Deployment? To add a canary deployment to your regular application deployment, use a text editor to edit the file that contains the service and deployment specifications.
The example uses an application manifest named app-manifest.yaml
:
nano app-manifest.yaml
Istio Performing Canary Deployment Tutorial: The manifest should look something like this:
apiVersion: v1
kind: Service
metadata:
name: nodejs
labels:
app: nodejs
spec:
selector:
app: nodejs
ports:
- name: http
port: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs
labels:
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v1
spec:
containers:
- name: nodejs
image: markopnap/test-prod
ports:
- containerPort: 8080
How Do I Perform a Canary Deployment on Istio? The example manifest above depicts a production version of a Node.js application whose container is stored in markopnap/test-prod
. To include the canary version of your application, first edit the deployment section of the file and add -v1
to the name of your application:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v1
Now, attach another deployment section to the end of the file with the specification for the Canary build:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v2
labels:
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v2
spec:
containers:
- name: nodejs
image: markopnap/test-canary
ports:
- containerPort: 8080
Note: Remember to replace the sample Docker Hub image location with your file location.
When you’re done editing the file, save it, and then update the system configuration with kubectl apply
with the following command:
kubectl apply -f app-manifest.yaml
Step 3: Configure the Istio virtual service
How Do I Use Istio to Perform a Canary Deployment? Create a new yaml file to store the Istio configuration. The example uses a file named istio.yaml
, but you can give it a name of your choice:
nano istio.yaml
If you previously deployed a production version with Istio, the file already exists and should look something like this:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nodejs-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nodejs
spec:
hosts:
- "*"
gateways:
- nodejs-gateway
http:
- route:
- destination:
host: nodejs
The file has two parts that define the Gateway and VirtualService objects. To introduce the two versions of the application and set up the routing rules that are distributed to users, modify the section at the bottom of the HTTP
. The section must contain two destinations with different subsets and weights:
http:
- route:
- destination:
host: nodejs
subset: v1
weight: 90
- destination:
host: nodejs
subset: v2
weight: 10
The weight parameter tells Istio which percentage of traffic should be routed to a specific destination. In the example above, 90% of the traffic goes to the production build, while 10% of the traffic goes to the Canary build.
Once you’ve edited the Virtual Service section, append the following line to the end of the file to create a Destination Rule:
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nodejs
spec:
host: nodejs
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
The purpose of defining a destination rule is to manage incoming traffic and send it to a specified version of the application.
Save the file and use kubectl apply
it to activate it:
kubectl apply -f istio.yaml
Step 4: Test your canary deployment
How Do I Use Istio to Perform a Canary Deployment? The configuration set in the previous step performs traffic routing to your production and canary deployments. To test this, use the external IP access application istio-ingressgateway
, which Istio uses as a load balancer.
Note: If you’re using minikube, you’ll need to emulate a load balancer by opening another terminal window and issuing commands. Without this, the external IP field in the next step will always show up as pending.minikube tunnel
Istio Performing Canary Deployment Tutorial: istio-ingressgateway
looks for the service in the list of services available in the istio-system
namespace. Use the services listed with kubectl get
:
kubectl get svc -n istio-system
Copy the istio-ingressgateway
external IP address into your browser’s address bar:
http://[ingressgateway_ip]
The browser may display the production version of the application. Hit the refresh button multiple times to simulate some traffic:
After a few times, you should see the canary version of the app:
If you have the Grafana add-on installed, check the incoming request statistics to see the percentage of routes for each deployment. In Grafana, click the home icon:
In the Dashboards section, select Istio and click Istio Service Dashboard:
How Do I Perform a Canary Deployment on Istio? In the dashboard, find the Services field and select the service that corresponds to your application. In this example, the service is named nodejs.default.svc.cluster.local
. Once you’ve selected your service, go to the Service Workloads section:
Select the chart titled Incoming Requests By Destination Workload and Response Code. The chart shows the amount of traffic you’re generating by refreshing the page. In this example, it’s clear that Istionodejs-v1
provides application versions more frequently than Canarynodejs-v2
.
Conclusion of the Canary Deployment Tutorial on Istio
How Do I Use Istio to Perform a Canary Deployment? With this tutorial, you learned how to set up Istio to automatically route traffic to multiple versions of an application. The article also provides instructions on setting up routing rules for Canary app deployments.