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

Automox is a cloud-based patch management and endpoint protection platform that provides the foundation for a strong security framework by automating the fundamentals of security hygiene to reduce a company’s attack surface by over 80 percent. A powerful set of user-defined controls enables IT managers to filter and report on the vulnerability status of their infrastructure and intuitively manage cross-platform OS patching, third party patching, software deployment, and configuration management. To sign up for a free, 15-day trial of Automox’s cloud-based, automated patch management solution visit www.automox.com/signup.


Subscribe to Our Newsletter

Stay up to date on all things patch management

Reduce your threat surface by up to 80%

Make all of your corporate infrastructure more resilient by automating the basics of cyber hygiene.