This February I got a chance to attend the Helm Summit in Portland. It was filled with amazing talks covering various topics about Helm. I attended almost all of them, and also got the opportunity to present a Lightning Talk myself. The talk was about a Helm trick/tip that I came across and found very useful, so I thought I’d share with you all as an article.
Helm lets us manage Kubernetes applications effortlessly. Helm Charts make installation and upgradation of Kubernetes applications easier. In this article, I want to focus on one out of the many benefits of using Helm: How Helm makes updating an app that uses ConfigMap very easy.
Updating a deployment
This is a sample manifest of a deployment. Let’s assume this is being used to run an app. You specify the pod template under spec.template section. Now if you want to update the app, it is a must that something from this spec.template section changes. Meaning, for a change in container image, the deployment will get updated, but not for a change in spec.replicas.
Updating a deployment that uses a ConfigMap
Some apps require certain configuration files and values. It’s not recommended to have these configuration values/files baked into the container image. This is so, because otherwise every time your configuration file changes, you’d have to recreate the container image. Kubernetes provides a great way of managing configuration files/values, with the ConfigMap resource.
There are 2 ways to expose ConfigMap data to a pod,
- Env vars
- Volume mounts
We’re going to focus on the volume mounts way of exposing ConfigMap.
I’ve created a very simple chart to use as an example to go over this. Within that chart I have the following manifest for a ConfigMap:
As you can see, the name of the ConfigMap is nginx-cm, and a file called default.conf is reading its data. This default.conf is an nginx configuration file.
Now I want to use this ConfigMap nginx-cm for my app. So I’m going to expose it via Volume Mounts in the deployment manifest for my app.
As shown in the manifest above, we need to add the ConfigMap under Volumes section, and give it a unique name (config-volume as shown in the example manifest). Then, we add this volume under volume mounts in the containers section. The volumeMounts.mountPath field is the exact location in the container where the configuration file will be made available to the container.
So using these manifests, we can have an app running that uses the content of nginx configuration file made available by the ConfigMap.
Now let’s say it’s time to change the nginx configuration file. Changes to this config file should be followed by an update to the ConfigMap too, otherwise our app that uses the ConfigMap won’t use the new content.
We can for sure use the
kubectl update command for updating the ConfigMap. This should be followed by an update to the deployment as well. Will
kubectl update work for the deployment too?
I got this message when I tried.
This is because the deployment’s spec.template portion has not changed even after updating the ConfigMap resource. Even though the ConfigMap’s data section changed, that didn’t cause any changes in the deployment’s spec.template One workaround for this is to delete all the pods being managed by the deployment, and then the deployment will create new pods that use the updated configMap. But I didn’t quite like this approach, as you have to delete all the pods manually. So I started looking for better solutions. That’s when I came across this Helm trick. https://github.com/kubernetes/helm/blob/master/docs/charts_tips_and_tricks.md#automatically-roll-deployments-when-configmaps-or-secrets-change
As you can see under annotations, you can provide path to your configmap file, and pass it to sha256 sum function. This updates the annotation section everytime the configmap file changes, thus in turn updating spec.template portion of the deployment. I found this very helpful, because your configuration file contents can keep on changing quite frequently. So because of this trick, Helm ensures that your app will keep reflecting those changes promptly.
I have created this sample Helm chart to show how this trick can be implemented.
Do check it out and hopefully you’ll find it useful for your apps too! Also feel free to add more to it, and maybe share any such tips/tricks that you have come across as well!