HELM FOR DUMMIES

HELM FOR DUMMIES
HELM FOR DUMMIES

Kubernetes has become an essential tool for managing containers, widely supported across all major cloud platforms. However, with multiple methods available for deploying applications on Kubernetes, it can be challenging for beginners to grasp the differences between them.

One of the most popular tools for deploying applications on Kubernetes is Helm, known for its flexibility in configuration and customization. It’s frequently compared to another tool, Kustomize, as both offer unique approaches to managing deployments.

In this article, we’ll dive into what Helm is, how it operates, and why it has gained such widespread popularity.

Definition and characteristics of Helm

Helm is a package manager for Kubernetes. It allows you to install, in two commands, an application from any source on your cluster; the only prerequisite for this installation is the presence of the “helm” binary on your computer.

Helm is the Kubernetes counterpart of yum and apt in the Redhat and Debian worlds.

As a package manager, Helm not only allows for a quick installation, it also allows for a versioned installation of an application. This aspect is important, because it will allow you to know what is deployed at a given time on your cluster, as well as facilitate its upgrade (or downgrade!) of version.

If for example, you have installed a Minecraft server with Helm, and the package developers released a new version, you can easily update your instance of the application with a single Helm command.

Finally, one of the advantages of Helm today is its standardization: if a cluster uses Helm, even if you are new to the project, you can have an idea of ​​what is running on it.

How does Helm work?

A Kubernetes cluster allows applications to be deployed on a set of nodes using easy-to-manage objects: an object can represent a volume, an instance of the application, a network service allowing communication with the application, etc. 

These objects are often represented as YAML manifests.

Applications deployed on Kubernetes are usually complex, and will need several of these objects to work properly. We will need to make our application work (with a Deployment), give it parameters (with ConfigMap and/or Secrets), allow its access from inside the cluster (with a Service) and/or from outside (with an Ingress)… In short, a lot of manifests to manage for a single application!

Kubernetes Objects

An application is composed of a multitude of manifests

These manifests can be very verbose, detailing every parameter of the associated component. These parameters can be different depending on what you want, for example your application consumes less resources on a development cluster than on a production cluster.

In the beginning, we managed manifests manually: either we became copy-paste pros, or we made scripts to be able to configure our manifests and avoid duplicating too much code.

Kustomize is one of the tools that has become a reference in this function: it allows, from a YAML manifest, to modify it according to patches (= small changes) before applying it to a cluster.

Helm has taken the path of templating: we define our objects as templates with parameters, we enter default values ​​when creating the Chart (the package containing the application), then we allow the user to give his own parameters when he wants to apply the Chart on his cluster. When deploying, Helm will substitute the parameters with the provided values, giving you the manifests that will be deployed on Kubernetes.

Helm allows you to install an application with a system of templates, default values ​​and values ​​per installation

Helm allows you to install an application with a system of templates, default values ​​and values ​​per installation

Under the hood, Helm uses the Go templating language with (among others) the Sprig function library: you can use parameters, but also logical conditions, loops, define functions (or templates) – in short, it’s powerful!

How to use Helm?

First, some vocabulary: 

  • Chart : A Helm package; it is defined by its name and version. It is a tar.gz file, a compressed folder.
  • Release : An instance of a Helm package on a Kubernetes cluster; there can be multiple releases of the same Chart on a cluster (as long as you give them distinct names).
  • Manifest : A Kubernetes object, defined as code in YAML (or JSON).
  • Repository/Registry : A web server that contains different versions of one or more Charts.

Creating a Helm Package

Let’s start with the basics: creating a Helm package.

To create a Helm package, you can use the Helm binary command: `helm create my-web-server`. Helm will create a folder `my-web-server`, in which you will be able to find several files and folders; by importance:

  • Chart.yaml : metadata file of your Chart; contains the name of the Chart and its version. It also contains (optionally) the dependencies that your Chart might need.
  • values.yaml : the default values ​​of your parameters. This is what you will need to modify to give healthy defaults to your application allowing it to work in general cases.
  • templates/ : the templates that will be deployed by the Chart: any file with the extension `.yaml` in this folder (or subfolder) will be recognized by Helm to be deployed on the cluster. This is where the code for your deployment will be located.
  • charts/ : any dependencies your Chart may have; and yes, Helm is a package manager, and any good package manager can manage dependencies!
my-web-server/
├── charts/
├── templates/
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests/
│       └── test-connection.yaml
├── Chart.yaml
└── values.yaml

topography of a freshly created chart

With the command we ran, Helm created a Chart for a simple web server, with lots of editable options; if you open values.yaml, you’ll see for example a `replica: 1`, a `resources` block, and lots of other options. You can choose to override these when installing your application, or keep these defaults.

It is up to you to modify the content of these different files to adapt it to your needs.

Now that we have a valid Chart, let’s see how to package it.

Packaging and provision of a Chart

If you don’t intend to share your Chart outside your organization, and you don’t mind deploying from a folder instead of a registry, you can just use Git to keep the different versions of your Chart.

If you want to share it with other entities, you will need to package it and make it available to them.

To package a Chart, it’s simple: run the command `helm package my-web-server`, and Helm will compress this folder into a file “my-web-server-0.1.0.tgz”. This archive can now be pushed to a Helm registry, which will make it available to users.

The Helm Registry is a simple web server that contains:

  • an index file at the root `index.yaml` which lists all available packages and links to download them
  • and packages, often in the format “NAME_OF_CHART-VERSION.tgz”

It’s a simple operation, and if you don’t want to host the registry yourself you can easily configure most Git providers to do this (GitHub Action and GitHub Pages, Gitlab Package Registry, etc).

Helm can also use OCI registries, which store artifacts in Docker registries.

Once your Chart is pushed to the registry and its index file has been updated, it is available to users.

Retrieving a Chart

To retrieve a Chart, Helm will need to know the register where it is stored. In normal operations, Helm will keep a local cache of registers and their respective indexes. Although it is rarely used, you can do without it to directly download the Chart you are applying.

To add the registry and its index to our local cache, we need to perform the following commands:

``` 
helm repo add my-repo-name http://my-repo-url
helm repo update
```

You can then list the different Charts and versions available with the command

`helm search repo`

Helm is now configured to be able to retrieve Charts from the my-repo-name registry; to install a Chart registered on this registry, we will need to call it by prefixing it with the name we gave locally to the registry; for example, for a “my-web-server” Chart, we will now call it “my-repo-name/my-web-server”.

Note that the name “my-repo-name” is unique to your computer; another user can name it whatever they want. Within the same organization, it is better to synchronize on the name you use for each registry, so that the documentation is easier to use.

Install my Chart

My Chart is created and is either accessible on my system or made available on a registry. Now let’s see how we can install it on our cluster.

An installation of a Chart on a cluster is called a Release. A Chart can have multiple instances on a single cluster, each identified by different releases. Although a Release is not a Kubernetes object directly, it is only identified by its namespace and name.

To install my Chart, I can do a: 

`helm install webserver-001 my-repo-name/my-web-server`.

Helm will then perform the following actions:

  • download the “my-web-server” archive from the “my-repo-name” registry
  • merge any values ​​given on the command line with the default values ​​of the Chart – here, no overloads, we only use the default values
  • generate manifests to install from templates
  • install these manifests on the cluster in the current/specified namespace.
  • write these manifests to a state file; by default, this state file is in a Kubernetes secret.

Your application will now run on the cluster!

The state file will allow Helm to do advanced operations on the management of your Release; first of all, it will allow you to quickly perform rollbacks, when you want to go back on a deployment. But more importantly, it will allow Helm to do cleaner updates, taking into account not only the last desired state and the new desired state, but also the current state of your deployment, which will allow manual and automated changes to remain; this is very useful when you use admissions controllers for example. This is called three-ways reconciliation.

Helm uses three-way reconciliation to integrate manual changes with the changes desired by your Chart.

Helm uses three-way reconciliation to integrate manual changes with the changes desired by your Chart.

There is no way to disable this behavior, and it is very easy to trip up – so avoid manually touching objects managed by Helm, and you will be fine :).

Three-ways reconciliation is part of Helm’s inner workings, and you won’t need to know how it works to use the tool; but it’s still useful to know!

Your web server should now be running without problems, and you can check its status with a

`kubectl get pods`.


Update my release

Your server is running with a single pod; that’s good, but it’s not enough for you anymore! Let’s update the pod’s replica count:

```helm upgrade webserver-001 my-little-repo/my-web-server –set replicas=3```

You should now see 3 replicas running on the cluster. Simple, right? 

Under the hood, Helm performed the following actions: 

  • downloaded/used the latest version of Chart “my-little-repo/my-web-server”;
  • downloaded from Kubernetes the latest desired state of our application;
  • downloaded from Kubernetes the current state of our application;
  • merged the value “replicas=3” with the old values ​​given in our release;
  • generated the manifests to install from the templates;
  • generated a differential of changes to be applied based on the current state, the old desired state and the desired state;
  • made these changes in Kubernetes as patches;
  • writes the new state file to a Secret, which represents the new current state of the cluster.

Putting parameters in the command line, however, is not very clean; you can create a file to store them and call them more simply through it:

```# cat values_webserver_001.yaml 
replicas: 3
resources:
 requests:
   cpu: 0.1
   memory: 200Mi
```

You can then call this file like this:

```helm upgrade webserver-001 my-little-repo/my-web-server –file values_webserver_001.yaml```

There you have it, your Kubernetes infrastructure is now fully defined As Code!

List and delete my releases

Now that we have installed our applications, we can list them with the following command:

`helm ls` 

helm ls

We can see the different installed releases, with their Chart and the applied revision.

If you want to uninstall your release, you can do so with the command

`helm uninstall webserver-001`.

helm uninstall

Helm will take care of removing all files associated with your release.

In terms of templating, what are Helm’s features?

Now that we’ve covered how to use Helm, let’s quickly cover the features that make Helm so powerful.

Helm uses the Golang templating language, with the addition of the Sprig library, which gives a lot of freedom in what you want to do in terms of templates:

  • {{“.Values.Variables”}} : you can of course substitute a variable with a value in one of your templates, but also:
  • {{” if .Values.createRBAC”}} : you can use logical conditions (if/else) to condition the creation of code blocks, or even certain resources
  • {{“range .Values.users”}}  : you can use loops to be able to repeat a block multiple times
  • {{“include ‘my-function’ .”}}  : you can use templating functions, to avoid repeating code between multiple resources

We’ve been talking since the beginning of the article about the values ​​Helm uses to substitute parameters; Helm will use the values ​​you give it (`values.yaml` file and command line overloads), but it will also provide several interfaces to give you more information:

  • “.Values.*” contains all values ​​provided explicitly by you
  • “.Release.*” contains information about your Release, in particular its name and namespace
  • “.Chart.*” contains information about your Chart, including its name and version
  • “.Files.*” , a helper to access local files; useful for creating configmaps properly!
  • “.Capabilities” , a helper to check the capabilities of the cluster you are deploying to; useful to avoid deploying custom resources if they are not defined on the cluster!

With these different tools, you can generate almost all the manifests you want to deploy – Helm is for me in the right place between a pure ops solution and a pure developer solution.

Helm also has advanced deployment features, which will allow you for example to define in which order objects should be created, define pre and post deployment hooks (for example, to clean data between two versions), or even define tests on objects deployed with Helm.

These advanced features will often take the form of a Kubernetes Job, with a special label recognized by Helm – so no need to learn a new language to develop tests!

Helm, Kustomize or Operators – Which to Choose?

There are several ways to deploy an application to a Kubernetes cluster, with different tools and methods. I have often seen Helm compared to Kustomize and even Operators to do deployments; this section will aim to quickly show the differences between these methods, and illustrate that they do not have the same target audience.

Kubernetes Operators allow through Custom Resources to simplify the creation of objects. For example, instead of creating 5 Kubernetes objects to deploy my web server, I could create a custom resource “WebServer”, put all my parameters in it, and develop an application that monitors these custom resources and creates the Kubernetes objects when necessary. This is useful when you have many similar applications, but has several drawbacks: it is very complex to implement, requiring to create, monitor and update regularly an additional application. An operator also requires to keep your WebServer manifests up to date with the operator. In return, you develop the operator, so you have total freedom on how it creates and manages manifests over time.

For pure Kubernetes deployments, an Operator will often be overkill as it will add a lot of complexity for little gain. However, if your application needs to create objects outside of Kubernetes, such as a database, then an Operator can become a more appealing solution.

The operator will also allow maintenance operations to be performed automatically, such as automated backups or certificate renewals. This is one of the major advantages that the operator will have over other deployment methods.

An operator allows you to define your own Kubernetes objects

An operator allows you to define your own Kubernetes objects

Kustomize allows you to deploy applications through bases and patches; it’s an elegant solution, as long as you have very few modifications to make to your base. The most notable difference between Helm and Kustomize is the package management aspect. Kustomize doesn’t have packages, versioning, or even possible rollbacks; it can simulate versioning and packaging through Git. The biggest flaw of Kustomize for me, comes from its documentation: it’s a language that aims to be strongly guided, but the documentation is hard to navigate to be able to do basic operations.

Kustomize is now included by default in the `kubectl` binary.

Kustomize uses a patch system to create its assets

Kustomize uses a patch system to create its assets

Helm is a middle ground between the two: a relatively simple templating solution to set up, versionable, and auditable on the cluster. Helm benefits from advanced features (pre-hook, post-hook, tests, etc.) that allow it to do fully automated rollbacks – we will talk about this in a future article.

The best of all worlds is achieved when you can use Kustomize on Helm value files, allowing you to minimize the code duplication you will have on your deployments. This is for example possible when you use GitOps, for example Flux.

 KustomizeHelmOperator
Complexity to implement simplesimplecomplex
Adaptability to needslowhightotal
Implementation timedownAVERAGEpupil
Maintenance timeAVERAGEdownpupil
Managing Previous DeploymentsNoYesyes (depending on implementation)
Number of instances
on a cluster
11->N1->N
Target usessimple applications, little configurationsimple to complex applications,
with a desire to share
complex applications; an operator’s custom resources will often represent non-Kubernetes objects, such as letsencrypt certificates or Kafka topics.


In short, if we talk only about deployment tool, Helm comes in first place in relation to the ratio [time invested / efficiency of the solution] for almost all applications; only simple applications will benefit from using pure Kustomize compared to Helm.

But an application lives over time, and this is where Helm will win hands down the first place, with its package manager aspect allowing it to manage application updates simply and cleanly.

If you are interested in this comparison, you can also check out this techtarget article which explains in detail how to choose between Helm and Operators.

Conclusion

Helm is the most widely used deployment tool on Kubernetes today, and it’s a position it deserves despite its flaws! Maintaining a Chart is relatively simple once you know Helm, and only requires simple programming skills to do so.

If you deploy applications on your cluster, before deploying manifests from the Internet, look for Charts to do this; it may be more complicated today, but you will thank me in 6 months when you want to upgrade and you have in the meantime had to modify a lot of small parameters on these manifests so that they are better adapted to your cluster.

A good resource to use for this research is artifacthub.io , which lists most of the Charts available on the net.

Author

  • Mohamed BEN HASSINE

    Mohamed BEN HASSINE is a Hands-On Cloud Solution Architect based out of France. he has been working on Java, Web , API and Cloud technologies for over 12 years and still going strong for learning new things. Actually , he plays the role of Cloud / Application Architect in Paris ,while he is designing cloud native solutions and APIs ( REST , gRPC). using cutting edge technologies ( GCP / Kubernetes / APIGEE / Java / Python )

    View all posts
0 Shares:
Leave a Reply
You May Also Like
What is Cilium CNI
Read More

What is Cilium CNI

Table of Contents Hide What is Cilium Cilium Installation PrerequisitesCreating a Kubernetes ClusterInstallationCilium CLIHubble – observability according to…
Learn Prometheus : A Complete Guide
Read More

Learn Prometheus : A Complete Guide

Table of Contents Hide HistoricalKey ConceptsMetricsScrapingPromQLAlertingService DiscoveryExportersTargetsLabelsTime Series Database (TSDB) Prometheus Installation Prometheus ConfigurationAlert ManagerAlertmanager Installation Alertmanager ConfigurationAlert…