CICD for Kubernetes
Designing CICD pipeline is not easy, you have to find the balance between
automating things and making it maintainable. Maintainable in a sense that the other DevOps engineer can understand what is happening in the pipeline, so that they fix it if something goes wrong or improve it. In this entry, I will discuss my take on CICD for Kubernetes.
PROs of using this Setup
Later we are going to dive deeper on how the following feats were achieved.
- Using GitOps, to learn more about GitOps visit opengitops.dev.
- All resources used in the CICD are K8s native.
- Apps are easy to deploy and troubleshoot.
- Changes to configmaps are picked up and applied to the apps automatically, no need to restart pods.
Tools used in this CICD pipeline
Argo Workflows
Argo workflow is what I’ve used for the workflow engine/orchestrator. This will handle things like running of static analysis, creation of docker images, and replacing and committing the new image to the QA app config repo, etc. The main reasons why I’ve used Argo Workflow is because it’s k8s native, it’s opensource, and it works seemlessly with ArgoCD.
Kaniko
Kaniko is the tool that lets us build the container images inside kubernetes.
Argo CD
Argo CD is our GitOps controller. It will watch over the app config repo for changes. And if there are, it will automatically reconcile the desired state to the cluster state.
Kubevela
We are using kubevela as OAM to make app deployment easier. To learn more about kubevela, you can read here.
Reloader
Reloader app ensures that our workloads use the most recent configmap. If there are changes on the configmap of the apps it’s managing, it will restart all instances of that app to update the config in the pods.
CICD in Action
In this scenario, we are assuming that the development and unit tests are happening on the developers local machine.
Once the Devs pushed their changes into the app code repo, they will have to run a pipeline that will execute static analysis, deploy the changes, integration and regression tests on the QA environment.
Note: We can use an events tool like Argo Events to detect if there are commits to the app code repo and run the CI pipeline automatically.
Pre-requisites
Before we can run the CI pipeline and CD, we need to setup the following.
So right now, we will be wearing our DevOps/Operator hat while setting up the cluster.
Setting Up the Cluster
1 | ### Clone the dev-k8s repo |
Access https://localhost on your browser to make sure all cluster app are successfully deployed.
Note: Initially an unsecure warning will pop-up, select proceed and accept risk.
To get the initial password for the admin
user, run this:
1 | kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo |
Login and verify that all cluster apps (i.e. argo-workflow, kubevela and reloader) are deployed successfully.
Fork it!
Now we will switch to our Developer Hat.
We will be using these sample repos for our pipeline, so we will need to fork these.
sample-springboot - App code repo of our sample springboot app.
sample-kubevela-argocd - App config repo for our QA and PROD env.
Clone the k8s-cicd repo.
Edit the qa-sample-app.yaml and prod-sample-app.yaml, and change the repoURL
to your sample-kubevela-argocd forked repo.
1 | # On k8s-cicd/apps/qa-sample-app.yaml and k8s-cicd/apps/prod-sample-app.yaml |
Apply the Application manifests.
1 | cd k8s-cicd |
Edit the ci.yaml. Edit the app_repo
value on get-git-hash
and build-container-image
step with your sample-springboot forked repo. Then edit the app_config_repo
on deploy-to-qa
step with your sample-kubevela-argocd forked repo.
1 | # On k8s-cicd/workflows/ci.yaml |
Add required Secrets
Add the regcred(docker secret) and git-token to argo namespace.
1 | # Create 'git-token', secret for commiting to app config repo |
Run the CI Workflow
First, open http://localhost/qa on your browser and inspect the web page.
Now, for example we want to edit the app, in this case we will modify the background. Edit the background-color
of the sample-app on your sample-springboot forked repo.
1 | # On sample-springboot/src/main/java/hello/HelloWorldCtrl.java |
Commit the changes and push to git.
Now run the CI workflow.
1 | argo -n argo submit workflows/ci.yaml |
Let’s visit the Argo Workflows UI to see what’s happening in the workflow.
Open your browser to http://localhost/argo and click on the running build workflow. This CI workflow will do the following:
- Check out app code
- Perform a mock static analysis
- Building of new image and pushing to dockerhub
- Replacing and committing it to QA app config repo for deployment
- Run a mock integration test on QA
- Run a mock regression/acceptance test on QA
- Mock sending of results to Dev
Note: Once the old is replaced by the new image and commited to git, ArgoCD will make sure that it will be deployed to the K8s cluster.
Wait a couple of minutes and check http://localhost/qa. Verify that your modifications were applied.
Test the Reloader
Edit the value of env.prefix
on sample-kubevela-argocd/qa/sample-app.properties to any value of your choice.
1 | # On sample-kubevela-argocd/qa/sample-app.properties |
Commit and push it to your sample-kubevela-argocd repo. Wait a couple of minutes for your modifications to be picked up and applied by ArgoCD to the configmaps. The Reloader app then will detect that the sample-app pod is not using the most recent sample-app-properties
and terminate the pod. A new pod with the correct configmap will be spawned. Visit http://localhost/qa and verify that your changes were applied.
Run the CD(Continuos Delivery) workflow
If all tests passed, the Devs can decide to deploy the new release to Prod.
To do that, they will have to run the CD workflow.
1 | argo -n argo submit workflows/cd.yaml |
Visit http://localhost/argo to check on the running deploy workflow. This will fetch the image deployed on QA, replace it, and commit it to the PROD app config repo, and ArgoCD will do the rest. And that’s it, our changes have reached Prod. WOOT!
There are many things that can be improved on this Kubernetes CICD pipeline, but I think it’s a good starting point for those who want to setup their CICD pipeline with GitOps and all K8s native component. I really enjoyed working with ArgoCD + Kubevela + Reloader, the auto reconcilation is very convinient. And if you add that to how simplified Kubevela made application deployment is, if I put myself on the shoes of the Developer I think, Yes, I’ll be able to focus more on coding my app!
And that’s all I have for you guys, thank you and ciao. :)