Blue/Green deployment strategy
film-storage architecture
To achieve Blue/Green deployment with Cloud Native applications using Argo Rollouts, we have designed this architecture.
This is the initial situation after deploying the application:
OpenShift Components - Online
-
Routes and Services declared with the suffix
-online
. -
Routes mapped only to the online services.
-
Services mapped to pods created by the rollout.
OpenShift Components - Offline
-
Routes and Services declared with the suffix
-offline
. -
Routes mapped only to the offline services.
-
Services mapped to pods created by the rollout.
We will define an active or online service 'film-storage-online' and a preview or offline service 'film-storage-offline'. The idea is that the frontend will always use 'film-storage-online' and 'film-storage-offline' will only be used to test our service before triggering the rollout.
Generate film-storage APP GitOps Deployment Model
First of all, it is required to review a set of objects in our forked git repository to configure the deployment correctly for deploying our application following a GitOps model.
Please follow the next section to understand the required objects and configurations.
Review Services
As the previous picture shows, it is required to generate a couple of services that will be used to redirect the traffic to the correct application version.
Please take a look at the files ./blue-green/film-storage-service-offline.yaml and ./blue-green/film-storage-service-online.yaml to understand the objects and get the names of these elements.
Modify Rollout strategy
The Rollout object controls the application deployment. If you look closely, it is possible to find many similarities between an Argo Rollout object and a Kubernetes Deployment. The main difference between the previous objects referenced is the rollout strategy field.
Please edit the file named ./blue-green/film-storage-back-rollout.yaml in order to add the required <SERVICE_OFFLINE> and <SERVICE_ONLINE> service names:
strategy:
blueGreen:
activeService: <SERVICE_ONLINE>
autoPromotionEnabled: false
previewService: <SERVICE_OFFLINE>
Modify Analysis Template
We have created an AnalysisTemplate 'film-storage-analysis-template' that just validates the health of the application, for production environments a better analysis should be done. Argo Rollouts uses this AnalysisTemplate to validate a new version and set whether it is ready to be promoted or not.
Please edit the file named ./blue-green/film-storage-analysis-template.yaml to add the required <USERNAME> that helps to reference the user namespace in the healthcheck URL.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
labels:
app: film-storage
name: film-storage-analysis-template
spec:
metrics:
- name: film-storage-webmetric
provider:
web:
jsonPath: '{$.status}'
url: >-
http://film-storage-offline.<USERNAME>-blue-green.svc.cluster.local:8080/api/v1/health
successCondition: result == 'UP'
For more information about AnalysisTemplate, please visit the following link. |
Argo CD Application
We are going to create the ArgoCD application film-storage-blue-green, to apply the files modified previously to test Blue/Green deployment. Please, edit the .yaml file named ./argocd/film-storage-blue-green.yaml, and set your own GitHub repository in the repoURL.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: film-storage-blue-green
namespace: %USER%-gitops-argocd
spec:
destination:
name: ''
namespace: %USER%-blue-green
server: 'https://kubernetes.default.svc'
source:
path: blue-green
repoURL: https://github.com/change_me/workshop-argo-rollouts-resources
targetRevision: HEAD
project: default
syncPolicy:
automated:
prune: false
selfHeal: true
oc apply -f argocd/film-storage-blue-green.yaml
application.argoproj.io/film-storage-blue-green created
Looking at the Argo CD dashboard, you would notice that we have a new film-storage-blue-green application.
It is important to wait for Healthy and Synced status in the Argo CD Application |
Test film-storage application
We have deployed the film-storage with ArgoCD. We can test the online and offline services to ensure that they are up and running.
To test the online service, it is required to extract the URL:
oc get route film-storage-online -n %USER%-blue-green -o jsonpath='{.spec.host}'
In addition, regarding testing the offline service, it is required to get the offline route:
oc get route film-storage-offline -n %USER%-blue-green -o jsonpath='{.spec.host}'
We can test the endpoint with the following request:
curl -s $(oc get route film-storage-offline -n %USER%-blue-green -o jsonpath='{.spec.host}')/api/v1/info | json_pp
The result:
{
"app" : {
"buildTime" : "2023/01/10 15:17:57",
"name" : "film-storage",
"version" : "0.2"
}
}
Notice that in each microservice response we have added metadata information to see better the version of each application. This will help us to see the changes while we do the Blue/Green deployment. Because right now we have both routers against the same rollout revision we will have the same response with version 0.2:
We can also see the rollout’s status.
Argo Rollouts offers a Kubectl plugin to enrich the experience with Rollouts https://argoproj.github.io/argo-rollouts/installation/#kubectl-plugin-installation |
oc argo rollouts get rollout film-storage-blue-green --watch -n %USER%-blue-green
NAME KIND STATUS AGE INFO
⟳ film-storage-blue-green Rollout ✔ Healthy 60s
└──# revision:1
└──⧉ film-storage-blue-green-644f5f6df7 ReplicaSet ✔ Healthy 47s stable,active
└──□ film-storage-blue-green-644f5f6df7-bhq6z Pod ✔ Running 46s ready:1/1
film-storage Blue/Green deployment
We have split a Cloud Native Blue/Green deployment into two steps:
-
Deploy a new version.
-
Promote a new version
To test Blue/Green deployment we are going to do changes in the backend application film-storage.
We already deployed the film-storage version 0.2, and we have a new film-storage version 0.3 ready to be deployed.
Step 1 - Deploy a new version
We will deploy a new version 0.3. To do so, we have to edit the files ./blue-green/film-storage-back-rollout.yaml to modify the value 0.2 to 0.3:
image: quay.io/dborrego/film-storage:0.2 <---
And push the changes
git add .
git commit -m "Change film-storage version to 0.3"
git push
ArgoCD will refresh the status after some minutes. If you don’t want to wait you can refresh it manually from ArgoCD UI.
Argo Rollouts will automatically deploy the new film-storage version and execute the prePromotionAnalysis.
oc argo rollouts get rollout film-storage-blue-green --watch -n %USER%-blue-green
NAME KIND STATUS AGE INFO
⟳ film-storage-blue-green Rollout ॥ Paused 19m
├──# revision:6
│ ├──⧉ film-storage-blue-green-7c455c98c8 ReplicaSet ✔ Healthy 4m36s preview
│ │ └──□ film-storage-blue-green-7c455c98c8-m7bwh Pod ✔ Running 36s ready:1/1
│ └──α film-storage-blue-green-7c455c98c8-6-pre AnalysisRun ✔ Successful 27s ✔ 1
└──# revision:5
└──⧉ film-storage-blue-green-644f5f6df7 ReplicaSet ✔ Healthy 19m stable,active
└──□ film-storage-blue-green-644f5f6df7-bhq6z Pod ✔ Running 19m ready:1/1
If the prePromotionAnalysis goes well, we can see that offline applications have version 0.3 and the new attribute description, but the online version has not changed.
This is our current status:
You can check the deployment with the following requests:
curl -s "$(oc get routes film-storage-online -n %USER%-blue-green --template='http://{{.spec.host}}')/api/v1/info" | json_pp
{
"app" : {
"buildTime" : "2023/01/10 15:17:57",
"name" : "film-storage",
"version" : "0.2"
}
}
curl -s "$(oc get routes film-storage-offline -n %USER%-blue-green --template='http://{{.spec.host}}')/api/v1/info" | json_pp
{
"app" : {
"buildTime" : "2023/01/23 21:43:23",
"name" : "film-storage",
"version" : "0.3"
}
}
Functional testers can execute tests to validate this new 0.3 version.
Step 2 - Promote a new version
As we have the promotion turned on to manual, we’re going to promote the new version to final users.
Argo Rollouts provides this command to promote film-storage:
oc argo rollouts promote film-storage-blue-green -n %USER%-blue-green
First Argo Rollouts will just change the service to use the new release (ReplicaSet). We minimize downtime because it just changes the service label.
oc argo rollouts get rollout film-storage-blue-green --watch -n %USER%-blue-green
NAME KIND STATUS AGE INFO
⟳ film-storage-blue-green Rollout ✔ Healthy 43m
├──# revision:6
│ ├──⧉ film-storage-blue-green-7c455c98c8 ReplicaSet ✔ Healthy 28m stable,active
│ │ └──□ film-storage-blue-green-7c455c98c8-m7bwh Pod ✔ Running 24m ready:1/1
│ └──α film-storage-blue-green-7c455c98c8-6-pre AnalysisRun ✔ Successful 23m ✔ 1
└──# revision:5
└──⧉ film-storage-blue-green-644f5f6df7 ReplicaSet ✔ Healthy 43m delay:20s
└──□ film-storage-blue-green-644f5f6df7-bhq6z Pod ✔ Running 43m ready:1/1
This is our current status:
And after scaleDownDelaySeconds Argo Rollouts will scale down the first replicaSet (0.2).
oc argo rollouts get rollout film-storage-blue-green -n %USER%-blue-green
NAME KIND STATUS AGE INFO
⟳ film-storage-blue-green Rollout ✔ Healthy 45m
├──# revision:6
│ ├──⧉ film-storage-blue-green-7c455c98c8 ReplicaSet ✔ Healthy 30m stable,active
│ │ └──□ film-storage-blue-green-7c455c98c8-m7bwh Pod ✔ Running 26m ready:1/1
│ └──α film-storage-blue-green-7c455c98c8-6-pre AnalysisRun ✔ Successful 26m ✔ 1
└──# revision:5
└──⧉ film-storage-blue-green-644f5f6df7 ReplicaSet • ScaledDown 45m
This is our final status:
To test the new online service, you can use again both URL (online and offline):
curl -s "$(oc get routes film-storage-offline -n %USER%-blue-green --template='http://{{.spec.host}}')/api/v1/info" | json_pp
curl -s "$(oc get routes film-storage-online -n %USER%-blue-green --template='http://{{.spec.host}}')/api/v1/info" | json_pp