If you are here, it means you work somehow with containers. However, you feel some pain in managing them, especially with DevOps. You are just looking for a better way. Well, my friend, helm is the way to go. In this helm tutorial, we will see how to use helm to improve our DevOps process.
Better yet, we will get you up and running even if it’s your first time with helm. However, helm is a tool to manage containers, so we assume you already have some. If it is also your first time with containers, you should learn first how to use Docker and then Kubernetes (with Minikube). In fact, helm works on top of Kubernetes, which runs Docker containers.
Here’s what we will cover today:
- What is Helm?
- Do I Really Need Helm?
- Helm Tutorial Part 1: The Setup
- Helm Tutorial Part 2: Charts
- Helm Tutorial Part 3: Use Helm
What is Helm?
The guys who make helm are pretty neat in defining what they do:
[Helm is] the package manager for Kubernetes.
They put this phrase at the very beginning of their site. Then, they go on by saying “Helm is the best way to find, share, and use software built for Kubernetes”.
To understand what they mean, we need to take a step back. Imagine you have an application you deploy with DevOps, using a CI/CD pipeline. This pipeline is just a set of automated tasks that take your code, compile it, and package it in a simple package. This package can be, for example, a “.tar.gz” folder. This is the process of creating an artifact. (Okay, but what is an artifact? Read this if you are not sure).
Your artifact, by itself, does nothing. It is just a compressed folder. You need to put it on a server and configure the server to run it. But you can go a step further, and use containers. Think of containers as pre-configured virtual servers. You can set up your container as part of your CI/CD pipeline so that later you just need to deploy the container. Awesome.
Later on, you discover microservices. A complex application is not just a container, but a set of different containers. Each container does a different thing, but they all communicate and work together. Suddenly, you need something more. And this is where helm comes it.
Helm allows you to define how a set of containers should be deployed. You just create a bunch of helm configuration files and then you let helm eat them. It will connect to your Kubernetes and create your application. It can even help you roll back to a previous state.
Do I Really Need Helm?
Personally, I was doubtful when I first embraced helm. I had just started with containers, and I was a newbie in managing them with Kubernetes. The last thing I wanted was yet-another-tool-to-learn. But in the end, using only the Kubernetes YAML files was simply not enough. It was just too painful.
My answer would be yes, you always need helm. It takes just a few minutes to start, and maybe a couple of hours learning. But it will help you set up your project in the right way, even if you just have one container. Particularly, this is where helm can give you some help that you wouldn’t get with vanilla Kubernetes:
- You need to have some variables to pass when starting a new container instance (e.g. specifying image version, mount disks or other settings).
- Your application uses multiple containers together.
- You want an easy way to restore to a previous state in your application (e.g. to the previous release).
- You want to include in your CI/CD process other infrastructural components beyond the container, like load balancers.
- Your containers leverage environment variables.
Decide yourself, but you will need at least one of those points in literally any application you deploy!
Helm Tutorial Part 1: The Setup
We know what, we know why, now we can dive into the how. In this section of this helm tutorial, we will see how to start with helm in 5 minutes.
Getting Helm
First, you need to install helm. This is quite easy. On Windows, you can di it with Chocolately, a CLI utility to install stuff. Don’t have it? Execute Powershell as an administrator and run this command:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Now, you can use this other command to install helm.
choco install kubernetes-helm
Instead, if you are on Linux, you need to download the installation script with CURL. Very easy, just use the following two commands.
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
And here’s a bonus tip. If you want to run helm in the cloud, with Azure you can easily have helm in your Azure Cloud Shell.
Setting up Helm for the First Time
In short, helm has two parts: a client and a server. The client is basically the command-line utility you use, the helm
command in the terminal. This, however, does nothing by itself. It just acts as a way of telling the server what to do.
The server is just a container. It is the server to orchestrate everything that happens in your Kubernetes cluster. This also means you need to have one helm server for each Kubernetes cluster where you want to use helm.
With the previous section on “Getting Helm”, we already obtained the client. Now, it is time to set up the server and then tell the client where the server is. In short, we need to do the following.
- Create a service account for Helm to use (by default, name is
tiller
) - If you have Role-Based Access Control (RBAC), give the user the right privilege. Note: no RBAC = you must skip this
- Init helm by telling the name of the service account
We can accomplish all of that with three simple little commands:
kubectl --namespace kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller --wait
Of course, for all this magic to work, we need to have kubectl
already up and running.
Once our helm installation is ready, we can start to have some fun.
Helm Tutorial Part 2: Charts
What is a Helm Chart?
If you are new to helm, you want to know what a chart is. Well, simply enough a chart is just a helm “package”. Is the set of files that define an application, according to helm. In those files, you list how many containers you want, of which type, how to scale them and so on. You define the dependencies, the environment variables and such.
In the end, a chart is nothing more than a folder with all the configuration files helm needs to build your application.
But helm is not just about building applications, it is also about sharing them. Thus, you can share charts and download them (we will see how to do that later). If you want to take a look at the public chart made by others and that you can download for free, look at the charts/stable repository on GitHub.com. You will find things like Redis, Memcached or Nginx.
How do I create a Helm Chart?
Creating a helm chart is easy, and it is probably the masterpiece of this helm tutorial. If you want to go the easy way, just use the following command.
helm create chartname
Obviously, use a name you want instead of chartname
. Remember that a helm chart is just a folder. Thus, this command will create a folder with the name of the chart, and it will fill it with some default files.
The folder will have the following structure (note that we named our chart “webapp”).
We can break down the folder structure.
Chart.yaml
defines the name of the cart, its version, a description, and some other general information.values.yaml
is probably the most valuable file. Here you define some values that you can then reference in the other files. They look a lot like variables in coding..helmignore
tells helm what is not part of the chart.charts
folder contains sub-charts your application needs. For example, you may need the Redis sub-chart for some caching stuff, you can put it in that folder. You will put there only compressed charts.templates
folder is where the magic happens. It contains all the files that define how to build your application. Those are similar to Kubernetes files._helpers.tpl
is a file where you define functions that you can call in your other files.tests
is a folder where you may want to put the configuration of tests. Those tests are the ones that Kubernetes will use to determine if your app is running.
Now, if you prefer the hard way instead, just create the files yourself. Just note that everything in the templates
folder defines the chart, and you can have as many YAML files as you need.
A Template File
The default app creates three files in templates
to define three resources: a deployment, a service, and an ingress. Of course, you can remove those and add your owns, but just for an explanation, we can take a look at the default files.
We can take a look at service.yaml, the smaller one. Note that your might slightly differ from the one below, depending on the helm version you have.
apiVersion: v1
kind: Service
metadata:
name: {{ include "webapp.fullname" . }}
labels:
{{ include "webapp.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "webapp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
It basically just looks like any Kubernetes configuration file. Now, it is beyond the point of this article to explain Kubernetes files and how to create a deployment, a service and so on. Instead, we should focus on the things that Helm adds to the mix:
- Obtaining values from the
values.yaml
function - Calling helper functions
We will discuss these two topics below.
How to Use Values in Helm
The first thing we want to do is add some values in your values.yaml file. If you went with the default file, you already have some in here. In a YAML file, you have all the values in a format of key: value
. For example, you can have name: "John"
. But with YAML you can do more than that, you can nest values any time you want. In this way, you can obtain something like the following.
author:
name: "John"
surname: "Doe"
company:
name: "ICTShore"
website: "ICTShore.com"
Suppose the one above is our values.yaml
file. In that case, we can get all those values from any point in any file inside the templates folder. To do that, just recall it with dots, much like in Object-Oriented Programming. Then, prepend .Values
and enclose everything in double curly brackets. Sounds complex? Two examples will show you how easy it is.
{{ .Values.author.company.website }}
will be replaced with “ICTShore.com” when deploying the chart.- To get the author’s name (John), use
{{ .Values.author.name }}
As easy as that. But values are not just simple placeholders. In fact, when you deploy a chart, you can override some values or even all of them. So, think of the values you define in values.yaml
as really just defaults. Thus, never put sensible information like passwords or keys.
Furthermore, when importing a sub-chart, you can even redefine its values. This flexibility allows you to scale and reuse your applications.
Calling Functions in a Helm Template
We know that we can define some functions in _helpers.tpl
. Now, we want to use them in our templates.
In short, inside _helpers.tpl
, we can define new functions with {{- define "chartname.functionname" --}}
, put the body of the function, and then finish it with {{- end -}}
. Note that here we use the dashes, not just the brackets.
Once we define the function, we can go ahead to use it in any template with {{ include "chartname.functionname" }}
.
In the end, functions are just a way to glue together multiple values or have some kind of conditional flows where you return one value or another based on some conditions. They allow you to do some flow control, but you don’t need necessarily functions to do that.
If-Else Flow Control in Helm
You may want to use completely different templates in some cases, for example, you may add additional debug variables when you have the “debug” value set to true. Well, we can do that since we can use if-else statements in Helm charts. Typically, you want to check a value, and based on it do some stuff or other stuff.
Using flow control in Helm is easy. We have three key constructs, {{ if CONDITION }}
, {{ else if CONDITION }}
, {{ else }}
and {{ end }}
. The condition can be just about anything, like comparing two values (e.g. debug == 1
).
The following code shows an example of flow control.
{{ if .Values.sslSecret }}
secretName: {{ .Values.sslSecret }}
{{ else if .Values.useDefaultSecret == 1 }}
secretName: default-name
{{ else }}
secretName: false
{{ end }}
Of course, you don’t need to use all the structures all the time. Using just “if” and “end” is enough most of the time.
Helm Tutorial Part 3: Use Helm
Now that we have our chart we may as well put it to good use. It is time to deploy it. In this section, we will see how helm can help us with that. We will also see how helm can help us fix everything if things start to go south.
Deploy your Helm Chart
After creating our chart in the previous part of this helm tutorial, we need to deploy it. This means actually taking the configuration of the chart and pushing it to Kubernetes. It means actually creating pods, containers, ingress, and all the other resources we need.
This is the process of installing the chart. We can do it with the following command.
helm install --name release-name path/to/chart
Simply enough, this will install our chart in our Kubernetes cluster, creating a release with the name we provide. What is a release? Simply put, it is an instance of your chart running. We may also want to use some useful additional flags:
--namespace
to provide a namespace where to install the chart--set key=value
to override some values.yaml- –
-dry-run
Do not actually deploy the chart, this is useful for your Continuous Deployment pipeline, where you want to test your chart’s configuration before actually deploying it.
Of course, feel free to use --help
to discover more.
Install a Chart from the Repository
Sometimes, you just want a chart made by others. In that case, you still want to use helm install
, but instead of the path to a folder, you can simply provide the chart name. For example:
helm install --name my-balancer stable/nginx-ingress
You will attempt to download the file from the Helm Hub, the public repository of charts. If you want, you can also add private repositories with helm repo add
, and search for charts inside them with helm search
.
DevOps: Upgrade an Existing Chart
At the beginning of this helm tutorial, we made a promise to show you something all the developers want . An easy way to deploy the newer version of your application to your Kubernetes cluster that automatically updates your existing containers, with virtually no downtime.
Well, my friend, let me show you the helm upgrade
command, that does just that. The command works pretty much like install, but feel free to take a look at the extended documentation.
helm upgrade --name release-name path/to/chart
Obviously, the release name must be the same one of the chart you previously deployed or upgraded. As simple as that.
Fix Stuffs: Helm Rollback
You may find yourself in trouble from time to time, but helm helps you to navigate in these painful moments. If your latest upgrade happens to destroy everything, don’t panic. First, check the history of your chart to see how many points in time you can roll-back to.
helm history release-name
Tip: if you are not sure about the name of your release, run helm ls
to see all releases. Remember to use –-namespace
or --all-namespaces
to see the ones in a specific namespace.
The history will look something like this.
Now, once you identify the revision you wish to roll-back to, you can use the helm rollback
command.
helm rollback release-name revision-number
Tip: you can omit the revision number to automatically rollback to the previous one.
Wrapping It Up
This helm tutorial gave you all the tools you need to use helm and improve your containerized application. Of course, helm is much more than that, and you should explore it a little bit before calling yourself an expert.
If you feel there is something that definitely needs to be on this helm tutorial, or if you want some help on some of its part, just drop a comment below.