Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In all things, feel free to go straight to the source: https://helm.sh/.

Table of Contents

What is helm?

helm is a command line tool that greatly simplifies the deployment and management of kubernetes objects. Kubernetes objects are defined/managed via yaml manifest files. These files could all be managed by hand. However, suppose you wanted to make sure that each object had a common annotation set. You’d have to manually update each file. helm provides a way to generate the manifest files, and could allow a common annotation to be specified once and then automatically applied to all the kubernetes objects.

...

Additionally, helm can be used to deploy those manifest files directly to a kubernetes cluster. In fact, most helm commands don’t even bother to create local copies of the manifest files. The point is, helm isn’t doing anything ‘special’ - it’s creating manifests and applying them to kubernetes.

What is a helm chart?

At a basic level, a helm chart is instructions to build out a set of kubernetes objects. These instructions consist of two main parts:

...

  • a list of microservices that should be deployed

  • environment variables that should be specified on particular pods

  • annotations that should be placed on particular kubernetes objects

Are all helm charts alike?

Nope. This is part of the… fun. (smile) Any two helm charts can be as different from one another as any two java programs. They’ll all share similar syntax (templates and a yaml values file), but the content and style of each chart is entirely up to the creator of the chart.

Ok... but I don't want to install 'just the defaults'. 🤨

Good! That would be boring. Probably.

...

Code Block
languageyaml
some:
  value: xyz
  other: foo
my:
  list:
    - gamma
    - delta
  dictionary:
    rose: red
    violet: blue
    chrysanthemum: yellow

But... why don't I just modify the contents of my-chart/values.yaml?

You could! And it would all work fine. Until one day, when you decided you wanted to update to a newer version of your helm chart. Chances are, the new chart would have additions to its my-chart/values.yaml file. So you’d have to reconcile those updates with the local changes to your original my-chart/values.yaml. “Not much fun for little Harpo.” 🐟 By placing all your overridden values into a separate file, you are free to update to newer versions of a helm chart, and so long as the new chart is backwards compatible with your current version, you should be able to apply your override file over the top of the new chart.

...

Tip

Furthermore, by separating out overridden values into a separate file, you provide yourself with a descriptive, yet concise view of your deployment, with all the boilerplate information abstracted away. This makes it much easier to understand how a particular deployment is supposed to be working.

What is a 'release'?

Simply put, a release is the combination of:

...

Note

It is NOT recommended that you leverage this particular feature of helm - i.e. make every attempt to avoid local modifications of manifests for running kubernetes objects that were originally created by helm. There is no guarantee that those changes won’t be lost via subsequent helm commands.

Where should I store my override file?

The chart itself should be static and not require any changes. But the override file will, at least initially, see a lot of action, and will need to be updated frequently.

...

In a dystopian world, filled with weeping and gnashing of teeth, there would be multiple copies of the override file, all with a disjoint set of changes. Avoid this dystopian world.

This is awesome! But I don't want to store credentials in my override file.

For quick POCs and such, it’s sometimes handy to be able to specify credentials as environment variables directly in an override file. But that typically means you’re not going to want to check that override file into a git repository. Fortunately, the general answer here is to use some form of kubernetes secrets. When defining a deployment/pod, environment variable values can be specified by pointing to a particular key in a particular kubernetes secret. (Secrets are stored as a map of key/value pairs, so to find a particular value, you must specify both the name of the secret, and the key where the value is found). The actual secret values are stored in kubernetes, and the override file merely maintains pointers to where to find the values. That way, you can check in your override file without exposing any secret information.

I want helm to create the secrets for me.

Do you? For helm to create the secrets, it needs access to the secret values, which means they need to be in a file somewhere. Now you have to figure out how to manage that file such that it’s not checked into a git repo anywhere.

It’s generally best to create/populate kubernetes secrets from OUTSIDE of helm, via some other mechanism. Secrets aren’t likely to be changing too often, so making this a manual process shouldn’t be particularly prohibitive. In any case, different organizations often have wildly different requirements for how secrets must be handled - as such, it doesn’t make sense to try and shoehorn kubernetes secret creation into helm.

I want helm to create PVs and PVCs for me.

Kubernetes PVs and PVCs are, at the end of the day, implemented as yaml manifest files. As such, helm is perfectly capable of creating them. However, that means a helm upgrade or a helm uninstall can just as easily destroy them. An ill-conceived helm command can easily wipe away all your stored data. As such, it's better to create your PVs and PVCs outside of helm, and instead, simply reference them, when needed, in your override file. Just like we do for secrets.

Surely helm will create an ingress for me.

Yeah... maybe... but ingresses are very 'personal' - i.e. each environment typically has very different requirements for what all needs to be configured in an ingress. As such, the 'template' for creating an ingress becomes so flexible as to be largely useless - i.e. you're better off just building the ingress.yaml yourself and cutting out the middleman (helm in this case).

I’ve just modified something in my override file.  Now what?

Now you can run helm upgrade. Helm will comb through the existing manifests, check for things that need to change, and only update the necessary kubernetes objects. For example, if your only change was to add an environment variable to a particular deployment, only that deployment will be updated, and kubernetes will only restart that one associated pod.

I added new files to a configmap.  How come the services that use that configmap don’t see the updates?

You’ve just encountered a limitation of helm. Helm doesn’t keep track of the fact that a particular pod is mounting a particular configmap.  So if you change the contents of a configmap, helm doesn’t know to restart any pods.  As such, you have to manually restart the pods in question, so that when they’re restarted, the pull in the latest version of the configmap.

I have files ‘somewhere else’ and I want to wrap them up into a configmap.

That’s certainly possible, but due to another limitation of helm, those files have to be somewhere underneath the chart’s base directory structure. So files would have to be in my-chart/ somewhere. We recommend copying the files from ‘somewhere else’ into a subdirectory of the chart: cp -r /data/directory-of-handy-files my-chart/ (assuming your working directory is where the my-chart/ directory lives). You’ll now have a my-chart/directory-of-handy-files/ directory that can be referenced from your chart and used to populate a configmap.

...

It is also recommended that this cp be wrapped up into some sort of script or a Makefile so that it’s done each time a helm install or helm upgrade command is run.

What if the templates are 'wrong'?

It is hopefully unlikely, but theoretically possible, that particular environments or particular use cases require updates to be made to the template files themselves (the ones in my-chart/templates/). These files contain what look like normal kubernetes manifests, but they have a lot of extra {{ and }} sprinkled around, indicating where/how particular values from the my-chart/values.yaml and any override file should be feathered in to create the final manifests that get loaded up into kubernetes. In any case, in situations where there isn’t a way to affect the required changes via specific values, as a last resort, it’s possible to modify the contents of the templates. It’s not magic, and it’s well documented here: https://helm.sh/docs/chart_template_guide/getting_started/ .

...

  1. If/when you update to a newer version of the chart, you don’t want to lose any of your custom modifications. If the newer version of the chart still doesn’t provide the necessary, out of the box flexibility you require, you’ll likely have to make similar changes.

  2. The good people who designed the original chart would probably love to know about the changes you’ve had to make, so that they can update the official versions of the chart moving forward, to provide the required features. In a perfect world, the chart templates are flexible enough so that everything you need to do can be specified in your override file, and no local modifications to the templates are required.

Example Directory Structure

Code Block
.
├── Makefile
├── my-certs
│   └── my-cert.pem
├── my-chart
│   ├── templates
│   │   ├── _helpers.tpl
│   │   ├── abc-deployment.yaml
│   │   └── abc-service.yaml
│   └── values.yaml
└── override.yaml

...