Right now, our production environment contains Jenkins and ChartMuseum. On the other hand, we created a new production-ready release of go-demo-5. Now we should let our business, marketing, or some other department make a decision on whether they'd like to deploy the new release to production and when should that happen. We'll imagine that they gave us the green light to install the go-demo-5 release and that it should be done now. Our users are ready for it.
We'll deploy the new release manually first. That way we'll confirm that our deployment process works as expected. Later on, we'll try to automate the process through Jenkins.
Our whole production environment is stored in the k8s-prod repository. The applications that constitute it are defined in requirements.yaml file. Let's take another look at it.
1 cd ../k8s-prod
2 3 cat helm/requirements.yaml
The output is as follows.
dependencies: - name: chartmuseum repository: "@stable" version: 1.6.0 - name: jenkins repository: "@stable" version: 0.16.6
We already discussed those dependencies and used them to install Jenkins and ChartMuseum from the @stable repository. Since we do not want to bump versions of the two, we'll leave them intact, and we'll add go-demo-5 to the mix.
1 echo "- name: go-demo-5 2 repository: "@chartmuseum" 3 version: $VERSION" 4 | tee -a helm/requirements.yaml
5 6 cat helm/requirements.yaml
The output of the latter command is as follows.
dependencies: - name: chartmuseum repository: "@stable" version: 1.6.0 - name: jenkins repository: "@stable" version: 0.16.6 - name: go-demo-5 repository: "@chartmuseum" version: 0.0.1
Our dependencies increased from two to three dependencies.
Usually, that would be all, and we would upgrade the Chart. However, we still need to change the host value. In the "real world" situation, you'd have it pre-defined since hosts rarely change. But, in our case, I could not know your host in advance so we'll need to overwrite the ingress.host value of go-demo-5.
1 echo "go-demo-5: 2 ingress: 3 host: go-demo-5.$ADDR" 4 | tee -a helm/values.yaml
5 6 cat helm/values.yaml
The latter command outputs the final version of the values. The section related to go-demo-5 should be similar to the one that follows.
... go-demo-5: ingress: host: go-demo-5.18.219.191.38.nip.io
We already discussed that we'll document production environment in Git and, therefore, adhere to GitOps principles.
Typically, we'd push the changes we made to a different branch or to a forked repo, and we'd make a pull request. Someone would review it and accept the changes or provide notes with potential improvements. I'm sure you already know how pull requests work, the value behind code reviews, and all the other good things we're doing with code in Git. So, we'll skip all that and push directly to the master branch. Just remember that we're not going to skip pull request and the rest because we should, but because I'm trying to skip the things you already know and jump straight to the point.
1 git add .
2 3 git commit -m "Added go-demo-5"
4 5 git push
As you already know, we need to update local Helm cache with the new dependencies.
1 helm dependency update helm
The last lines of the output are as follows.
... Saving 3 charts Downloading chartmuseum from repo https://kubernetes-charts.storage.googleapis.com Downloading jenkins from repo https://kubernetes-charts.storage.googleapis.com Downloading go-demo-5 from repo http://cm.18.219.191.38.nip.io Deleting outdated charts
We can see that this time Helm downloaded three Charts, including go-demo-5 we just added as a dependency in requirements.yaml. We can confirm that by listing the files in the helm/charts directory.
1 ls -1 helm/charts
The output is as follows.
chartmuseum-1.6.0.tgz go-demo-5-0.0.1.tgz jenkins-0.16.6.tgz
The go-demo-5 package is there, and we are ready to update our production environment.
1 helm upgrade prod helm 2 --namespace prod
Let's take a look at the Pods running inside the prod Namespace.
1 kubectl -n prod get pods
The output is as follows.
NAME READY STATUS RESTARTS AGE prod-chartmuseum-68bc575fb7-dn6h5 1/1 Running 0 4h prod-go-demo-5-66c9d649bd-kq45m 1/1 Running 2 51s prod-go-demo-5-66c9d649bd-lgjb7 1/1 Running 2 51s prod-go-demo-5-66c9d649bd-pwnjg 1/1 Running 2 51s prod-go-demo-5-db-0 2/2 Running 0 51s prod-go-demo-5-db-1 0/2 ContainerCreating 0 15s prod-jenkins-676cc64756-bj45v 1/1 Running 0 4h
Judging by the AGE, we can see that ChartMuseum and Jenkins were left intact. That makes sense since we did not change any of their properties. The new Pods are those related to go-demo-5. The output will differ depending on when we executed get pods. In my case, we can see that three replicas of the go-demo-5 API are running and that we are in the process of deploying the second database Pod. Soon all three DB replicas will be running, and our mission will be accomplished.
OpenShift ignores Ingress resources so we'll have to create a Route to accomplish the same effect. Please execute the command that follows.
oc -n prod create route edge --service prod-go-demo-5 --hostname go-demo-5.$ADDR --insecure-policy Allow
To be on the safe side, we'll confirm that the newly deployed go-demo-5 application is indeed accessible.
1 kubectl -n prod rollout status 2 deployment prod-go-demo-5
3 4 curl -i "http://go-demo-5.$ADDR/demo/hello"
We waited until rollout status confirms that the application is deployed and we sent a request to it. The output of the latter command should show the status code 200 OK and the familiar message hello, world!.
As the last validation, we'll describe the application and confirm that the image is indeed correct (and not latest).
1 kubectl -n prod 2 describe deploy prod-go-demo-5
The output, limited to the relevant parts, is as follows.
... Pod Template: ... Containers: api: Image: vfarcic/go-demo-5:18.08.08-3 ...
Now that we explored how to perform the upgrade manually, we'll try to replicate the same process from a Jenkins job.