Kubernetes Helm 101

Using Kubernetes for the first time can come with frustrations. As an example, let’s say an organization has different environments for production versus development. When specifying resource requests and limits, that organization might have to make one file for each environment that are identical except for the values themselves. Fortunately, there’s a solution: Helm, the Kubernetes package manager.

Helm introduces the concept of a “chart”. A charts layout looks like the following:

The Chart.yaml file holds metadata of the chart and will have a layout like this:

An important thing to note here is that the “name” must be the same name as the parent directory.

The values.yaml file holds the default values. If no other method overrides the key, then this value will be used. We’ll go into more detail on these values later in the post.

The other envX-values.yaml files are one way to override the default value file. Now, you may be thinking “why is this method better than just duplicating the Kubernetes yaml files?” Well, value files only need one per environment, instead of one per file per environment. In the layout seen above, we would need six files for three environments:

  • normal-kubernetes-file-enva.yaml
  • normal-kubernetes-file-2-enva
  • normal-kubernetes-file-envb.yaml
  • normal-kubernetes-file-2-envb
  • normal-kubernetes-file-envc.yaml
  • normal-kubernetes-file-2-envc

This layout is a very dirty and hard to maintain. However, with Helm, we would only need five files:

  • enva-values
  • envb-values
  • envc-values
  • normal-kubernetes-file
  • normal-kubernetes-file-2

From a mathematical standpoint, the number of files to maintain in both scenarios would be:


filesNeeded = (# envs) * (# kubernetes files)

...and each file would need to be updated for a change.


filesNeeded = (# envs) + (# kubernetes files)

Generally, only the value files OR the Kubernetes files need to be tweaked.

Since I’ve used nginx as an example in previous posts, we’ll use it again in this post. For this scenario, let's assume that we have a local environment, as well as a production environment.

First, we need to install helm. On Mac, use “brew install kubernetes-helm”. Once installed, we need to start the tiller pod. This runs in the kube-system Kubernetes namespace. “helm init”. Once the pod is up and running, run “helm ls”. You will see that no charts are deployed yet.

Now, let’s make a directory called “nginx” and make the chart. In that directory, make the Chart.yaml file like so:

We can use the built-in linting tool by running “helm lint”. This will check for any helm based formatting errors, but it won’t check for Kubernetes errors.

The output should look something like this:

Here, Helm is telling us that it is missing the templates directory, a values.yaml file, and an icon (we can ignore this one).

Make a templates directory and then templates/nginx.yaml should look like this:

Some key things to highlight:

  • “.Chart.Name” is a high-level value, set in the “Chart.yaml” file
  • “.Release.Name” is the name of the release, set at deployment time with --name flag
  • “.Values.replicaCount” will look for the key “replicaCount” in the values.yaml file

Now, add this as your values.yaml file:

Let’s try to deploy this now that “helm lint” should be cleaned up. We can see a sample of the exact Kubernetes yaml that will be run if we type “helm template . --name example-nginx”.

Your output should look like this:

Great, no errors! Let’s deploy it with: “helm install . --name example-nginx”

The output will look something like this:

Now that it’s deployed, we can see it’s helm information with “helm ls”:

“REVISION” can be thought of as how many times it has been installed/upgraded.

Now, let’s make it for our theoretical production environment. Instead of copying and pasting the nginx.yaml file, just make another values file: prod-values.yaml.

As previously mentioned, the default values are in the values.yaml file. If we want to override them, one way is to tell Helm to use a different values file. For example, “helm upgrade --install example-nginx . -f prod-values.yaml”.

NOTE: the “upgrade --install” is the idempotent way to install/upgrade a chart.

As you can see, there are now five replicas instead of two!

A third and final way to override default values is by using the “--set” like so:

“helm upgrade --install example-nginx . --set replicaCount=10”

After doing this upgrade, “helm ls” will have increased it’s revision number:

Helm is NOT, in any way, a supervisor.

If you delete a deployment via Kubernetes (or anything else deployed via Helm) it won’t spin it back up like a deployment would spin up a pod if it was missing.

For example, “kubectl delete deployment example-nginx” will delete the deployment and helm will still report the chart has been deployed.

Deleting a chart is simple: “helm delete --purge <release-name>”. To delete the chart we just built, run “helm delete --purge example-nginx”.

About Automox

Facing growing threats and a rapidly expanding attack surface, understaffed and alert-fatigued organizations need more efficient ways to eliminate their exposure to vulnerabilities. Automox is a modern cyber hygiene platform that closes the aperture of attack by more than 80% with just half the effort of traditional solutions.

Cloud-native and globally available, Automox enforces OS & third-party patch management, security configurations, and custom scripting across Windows, Mac, and Linux from a single intuitive console. IT and SecOps can quickly gain control and share visibility of on-prem, remote and virtual endpoints without the need to deploy costly infrastructure.

Experience modern, cloud-native patch management today with a 15-day free trial of Automox and start recapturing more than half the time you're currently spending on managing your attack surface. Automox dramatically reduces corporate risk while raising operational efficiency to deliver best-in-class security outcomes, faster and with fewer resources.

Dive deeper into this topic