Helm & Kubernetes | Create Helm Charts and how to push them
In this article, I want to talk about what Helm is, how to install and use it, and how to push its images to artifactory. This sounds like a whole lot of stuff, it actually is, but it is a really important step in CI/CD, so I will try to explain it as good as I can.
What is Helm
In short, Helm is a package manager for Kubernetes that allows developers and operators to more easily package, configure, and deploy applications and services onto Kubernetes clusters.
Helm has the opportunity to set variables for Kubernetes, which you can then assign to your different Kubernetes Objects.
Or with the words of the official website:
Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application.
Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste.
How to install Helm
$ brew install helm
$ choco install kubernetes-helm
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
For more information on how to install Helm visit the official website.
How Helm works
To use Helm, Kubernetes needs to be installed on your computer. If this isn’t the case yet, install either MiniKube or enable Kubernetes Cluster in Docker Desktop.
One line install
Helm manages all your Kubernetes files and installs, changes and deletes all its content. Helm automatically applies every Kubernetes Yaml file that is in its “templates” directory. You can install a whole K8s application with just one simple cli command:
$ helm install APP_NAME CHART_NAME
Central values storage
This is by far not all. Helm has a Values.yaml file, in which you can store all your data required for defining your Kubernetes Objects. Your K8s files can then refer to this Values.yaml file and use these values. With Helm you can prevent copy pasting the exact same name 10 times in different K8s resources. We will take a look at an example later on, so just keep reading.
Overwrite values while deploying
With Helm you have the opportunity to overwrite some values of the Values.yaml file while deploying. You can do this by just adding the — set flag with a key and value behind it. The install command could look something like this:
$ helm install APP_NAME CHART_NAME --set deployment.image=nginx
Package a Chart
With Helm you have not only the opportunity to run your Helm-Charts locally, no, you can also package them and upload them to your personal Helm-Repo. If you have a Helm-Chart ready to get deployed, you just have to run:
$ helm package CHART_NAME --version=MAJOR.MINOR.PATCH
You actually don’t have to use M.M.P versioning, but it is surely good practise to use semantic versioning.
Enough of the boring theory, let’s start with a little example.
First of all, this example is as simple as it could be and will just deploy an Nginx application with a service on the cluster or MiniKube.
As you can see here, there is really just a basic deployment with a service bound to it. Now we will try to create a new Helm Chart for this application.
$ helm create HELM-CHART-NAME
This creates a new Helm Chart in the root of your Project. If you open the folder, you will see that it contains a few subdirectories and yaml files.
- The first of which is the charts dir. You don’t have to pay attention to it at the moment.
- The second one is the .helmignore file. It has similar properties as the .gitignore file for git. You can configure, which files won’t be added to your helm hart when packaging.
- The Chart.yaml file contains some informations about the chart itself and the application versions. You can change them after every change.
- The values.yaml file contains all the values needed for the files in the templates directory.
- The templates directory contains every file that gets executed by Helm. Some files are there by default and in most situations you can ignore them. They help you create an Ingress or generate the console output if a deployment was successful.
Using the values.yaml file
- Add your K8s files to to the templates directory.
- Look at your K8s files and search for values you could replace, mostly there are many of them, and add them to your values.yaml file.
This looks much more simple then this big K8s files, right? This wont do a thing at the moment, so we need to change the other files too, to use the values of this file.
You can refer to these values by using .Values and then the hierarchy you have defined in your file. With this way, you can ensure that you have the the same values where you need them and typos is practically a thing of the past.
Install your first chart
At this point you have configured your first Chart. You can now install it with:
$ helm install nginx-app nginx-chart
If everything worked like it should now, you should be able to see the nginx welcome screen on localhost:30001
If you wanna upgrade your deployment, you can just use the set command to change for example the image.
$ helm upgrade nginx-app --set nginx.deployment.image=nginx:1.7
After that, you should now see that the pods are changed out with the right image.
Package your charts
If you not only want to deploy your charts locally, you have to package them and push them to an artifactory. It is important that you have added all the files you don’t wanna have packaged to the .helmignore file. If this is already the case, just run:
$ helm package nginx-chart --version=1.0.0
This creates a new Helm package out of the helm chart. It looks like:
Push your charts
For pushing our charts, we can use curl. It is the simplest way in my opinion.
$ curl -u username:password -T nginx-chart-1.0.0.tgz \
Another way would be to use Helm directly:
$ helm push nginx-chart-1.0.0.tgz \
After this, you should be able to see your pushed charts in your Helm-chart-registry.
What went good?
The packaging worked like a charm. It worked pretty much on the first try and didn’t require any configuration. Also, the initialisation worked pretty good and didn’t need many changes.
What needs improvement?
The only thing that didn’t went great was, that i used the wrong values of the values.yaml file in the deployment. Since you can describe the Kubernetes objects afterwards or see it directly in your IDE, if a certain value is possible, it was pretty easy to solve.
I hope you could learn something. Happy Helming! 😊