Canary deployments are a strategy for gradually rolling out new versions of an application to minimize risk and ensure a smooth transition. In this workshop lab, you will learn how to perform canary deployments using Istio, an open-source service mesh platform for managing and securing microservices. By the end of this lab, you will understand how to leverage Istio’s traffic routing capabilities to implement canary deployments. We will also use concepts of GitOps using ArgoCD to roll out these changes.
Creating a New Version of Your Application #
As a part of this lab, we will first create a new version of our Random Facts application. Go back to the original directory where your Dockerfile and source code are for your application.
cd ~
cd create-dockerfile
Once you are in that directory, edit the HTML file in src/templates/home.html and update line 8 and change the background-color to #000000.
Once done, ensure you are in the directory where your Dockerfile is and run the following command to create a new version of your application:
docker build --tag random-facts-app:2.0 .
Tag and push your new version to Artifact Registry:
docker tag random-facts-app:2.0 us-central1-docker.pkg.dev/<YOUR_PROJECT_ID>/<YOUR_REPOSITORY_NAME>/random-facts-app:2.0
docker push us-central1-docker.pkg.dev/<YOUR_PROJECT_ID>/<YOUR_REPOSITORY_NAME>/random-facts-app --all-tags
Creating SSH Keys #
For this lab, we will be interacting with Cloud Source Repository and Git so we will need a pair of SSH keys. Generate them with the following command (accept defaults).
Note: Don’t set a password-protected private key. ArgoCD would fail to sync.
cd ~
ssh-keygen
Copy the SSH public key:
cat $HOME/.ssh/id_rsa.pub
Clone Cloud Source Repositories #
As part of the lab provisioning, a Cloud Source Repository has been created for you. In a new tab, go to https://source.cloud.google.com/<YOUR_PROJECT_ID> and click on your repository.
Under SSH authentication, click on the Register the SSH key with Google Cloud. in the second step. Give your SSH key a name (can be any name) and then paste your SSH public key from above in the key textbox. Click Register.
Once done, go back to your repository page and copy the clone command in the 3rd step.
Back in Cloud Shell, run the clone command and then change into the repo directory:
cd <YOUR_REPO_NAME>
Add Workload Artifacts to Repository #
Let’s start populating our repository with workload artifacts.
Ensure you are in your repository’s directory and create a new directory called v1:
mkdir v1 && cd v1
In the v1 directory, create a file for your Deployment manifest for version 1 of your application:
apiVersion: apps/v1
kind: Deployment
metadata:
name: random-facts-app-canary-v1
namespace: random-facts-app-canary
spec:
replicas: 1
selector:
matchLabels:
lab: random-facts-app-canary
template:
metadata:
labels:
lab: random-facts-app-canary
version: v1
spec:
containers:
- name: random-facts-app
image: us-central1-docker.pkg.dev/<YOUR_PROJECT_ID>/<YOUR_REGISTRY_NAME>/random-facts-app:1.0
ports:
- containerPort: 5000
Change back one level of your directory.
Create a file for your Service manifest:
apiVersion: v1
kind: Service
metadata:
name: random-facts-app-service
namespace: random-facts-app-canary
labels:
lab: random-facts-app-canary
spec:
selector:
lab: random-facts-app-canary
ports:
- name: http
port: 5000
protocol: TCP
targetPort: 5000
type: ClusterIP
Create an Istio Virtual Service manifest:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: random-facts-app-vs
namespace: random-facts-app-canary
spec:
hosts:
- "random-facts-app-canary.istio.<YOUR_STUDENT_ID>.<RANDOM_ID>.workshops.acceleratorlabs.ca"
gateways:
- istio-gateway/main-gateway
http:
- route:
- destination:
port:
number: 5000
host: random-facts-app-service
subset: v1
weight: 100
Create an Istio DestinationRule manifest:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: random-facts-app-dr
namespace: random-facts-app-canary
spec:
host: random-facts-app-service
subsets:
- name: v1
labels:
version: v1
Your repository structure should look like this:
.
├── destinationrule.yaml
├── service.yaml
├── v1
│ └── deployment.yaml
└── virtualservice.yaml
Once you have created and saved all of the above manifests locally, commit them to your Cloud Source Repository:
Note: Before proceeding, ensure you are at the root level of your repository directory. If you run an ls you should see your v1 directory.
Note: Using the master branch is required for ArgoCD to register the repo.
git checkout -b master
git add .
git commit -m "Initial commit."
git push --set-upstream origin master
Once pushed, you will now see the artifacts in your Cloud Source Repository UI.
Deploy Workloads via ArgoCD #
Create a Repository in ArgoCD #
Open the ArgoCD UI through your browser and log in if not already. Once logged in, navigate to Settings in the left pane and then select repositories.
Note: You can get your SSH private key by the following command: cat $HOME/.ssh/id_rsa
- Click
+ CONNECT REPO - For connection method, choose
VIA SSH - Name can be left blank
- For Project, select
default - For repository URL add your ssh repository url. The repository URL should start with
ssh:// - Next, add your SSH private key created in the first step
- Select
Skip server verification - Click
CONNECT, and then you should see a successful message:
Create the ArgoCD Application #
Next, we will create our ArgoCD application from our manifests.
- In the ArgoCD UI, navigate to the home screen and click on
+ NEW APP - Give the application a name, ie.
random-facts-app-canary - Choose the default project
- For sync policy, switch to
Automatic - Check the
PRUNE RESOURCESandSELF HEALradio boxes - Under
SYNC OPTIONS, check theAUTO-CREATE NAMESPACEradio box - Under Source, select your repository from the previous step.
- Under Revision, type
master - Under Path, type
. - Under destination select the default cluster
- Under Namespace, type
random-facts-app-canary - Under Directory, check the
DIRECTORY RECURSEradio box - Review the settings and click
CREATE
ArgoCD will now deploy our application. Spend some time reviewing the resources listed in the ArgoCD UI for our application.
We will now deploy v2 of our application. In the root of your repository directory, create a directory called v2. Your repository structure should look like this:
.
├── destinationrule.yaml
├── service.yaml
├── v1
│ └── deployment.yaml
├── v2
└── virtualservice.yaml
Copy the Deployment and Service manifests from your v1 directory and paste them into your v2 directory. Update any references from v1 to v2, including the image tag.
Once done, your directory structure should look like this:
.
├── destinationrule.yaml
├── service.yaml
├── v1
│ └── deployment.yaml
├── v2
│ └── deployment.yaml
└── virtualservice.yaml
Commit your changes via Git and validate that ArgoCD has now rolled out your second deployment. ArgoCD should automatically sync the changes. If you find it is taking long, you can manually click the SYNC button.
At this point, you now have a second version of the application deployed, but we are still sending all of the traffic to v1. Let’s change that.
Let’s start by rolling out v2 of our application by 50%. Istio will start sending 50% of the traffic to v2 while still sending 50% of traffic to v1. Modify your VirtualService and add a second destination block. Use your first destination block as a starting point and be sure to update the weights to be 50 each.
Also update your DestinationRule to add support for v2.
Once done, commit your changes to your repository and wait for ArgoCD to sync your changes.
Once ArgoCD has synchronized, visit your application at: http://random-facts-app-canary.istio.<YOUR_STUDENT_ID>.<RANDOM_ID>.workshops.acceleratorlabs.ca.
You should now see that about 50% of the time, you get a black background.
Now to complete our upgrade to v2 of our application, update the VirtualService again to send 100% of the traffic to v2.
Commit the changes to your repository, wait for ArgoCD to update, and then visit your application again to confirm you always see a black background.