Do you ever get lost in all the Kubernetes configuration files you defined for your application? When you deploy with Helm they are treated as packages and are easier to manage.

In this post we will take the Kubernetes deployment we build in several previous posts on Kubernetes and turn it into a Helm package. The final project code can be found on github here.

A more in depth evaluation of all the aspects of Helm can be found in the documentation here.

Setup Helm

We use helm via the helm CLI that communicates with the helm server, called tiller, that runs on your cluster. First install the client on you machine with homebrew.

brew install kubernetes-helm

Then initialise the client and install tiller with the following command:

helm init --upgrade \
          --history-max 200 \
          --tiller-namespace sybrenbolandit

The –upgrade is not mandatory but helps keeping things in sync when you already installed tiller on your cluster. Moreover it is a good practice to set a –history-max so not all previous helm history is stored and managed. Finally we want tiller to run in a specific namespace. (To restrict the tiller’s permissions to only that namespace is out of scope for this post.) We will omit the –tiller-namespace in all coming commands by setting the environment variable like this:

export TILLER_NAMESPACE=sybrenbolandit

Helm around a bit

We are ready to deploy are first helm chart (an installation in helm is called a chart). There are a lot of ready-to-go helm charts that you can use. Use the following command to install the prometheus-operator (see this previous post why we need it).

helm install coreos/prometheus-operator \
             --name prometheus-operator \
             --namespace sybrenbolandit

You can see by the output that this is not just one Kubernetes object, it is a whole package of them.

helm install output of prometheus operator - DEPLOY WITH HELM

To see which charts are currently installed you can use the list command.

helm list output 1024x78 - DEPLOY WITH HELM

We see the name that we gave it together with namespace, the chart, the version and the revision. It gives us a better overview of what is running than checking all separate Kubernetes objects.

Going from here we can delete, upgrade or rollback our deployments. This can be found in the Helm docs here. In the following we will focus on deploying our own chart.

Define your Helm chart

If you read my previous posts on Kubernetes or if you have sufficient knowledge on Kubernetes the easiest way to learn more on Helm charts is to look at an example. Here is the final Helm chart for our java spring application. It has the following structure.

    Chart.yaml       # Information about the chart
    values.yaml      # Default values to fill the templates
    environments/    # Value files per environement
    templates/       # Templates for Kubernetes objects

When we look at the files in the templates directory we see that the structure is almost identical to the one we had before. Only the values of the yaml are substituted with expressions between double parentheses.

{{ .Values.image.pullPolicy | quote }}

Helm uses the go templating language to refer to something in the values files here. In the default values file under image.pullPolicy we find Always. We can also omit parts of these templates by defining conditions.

{{- if .Values.metrics.enabled }}
...more template ...
{{- end }}

In the default values file (java-spring-api/values.yaml) under metrics.enabled we find false, so this part of the template will not be deployed. For even more complex expressions we can use helper functions defined in the _helpers.tpl file. For example for the name:

{{- define "" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

These are just the tip of the iceberg and more on templating is found with Helm here and on the templating language here. We are moving on to deploy our application with Helm.

Deploy with Helm

Now use the install command that we used before and we add the specific values file that we want to use for this deployment. Here we use the one for the test environment.

helm install java-spring-api \
             --name java-spring-api \
             --namespace sybrenbolandit \
             --values java-spring-api/environments/test/values.yaml

We can see this in our helm list as deployed.

helm list output with multiple installations 1024x83 - DEPLOY WITH HELM

And we can validate that our application is running if we port-forward the 8080 port and make the following request.

running application output - DEPLOY WITH HELM

Hopefully you can now turn your Kubernetes manifests into a Chart and deploy with Helm. Happy Helming!