Simplifying Kubernetes application management

Photo by pexels.comPhoto by pexels.com

After completing a 4-month period on a client’s project that included a complete migration from “raw” K8S-yaml-files to Helm Charts, I figured I need to put the things I’ve learned in writing for others to read, and for me to better learn. This post is the little brother of my 8-minute introduction to Kubernetes, make sure you read it first if you’re not yet familiar with basic K8s concepts.

TL;DR

You can install dependencies and proprietary software on your K8S cluster with a simple: helm install https://dev.to/prodopsio/an-8-minute-introduction-to-kubernetes-1oi/mysql, there are hundreds of available installations like this one, but you can also do that with your own product/services!


What’s HELM?

  1. “A helmsman or “helm” is a person who steers a ship, sailboat, submarine, other types of maritime vessel, or spacecraft.” — Wikipedia

  2. “The package manager for Kubernetes; Helm is the best way to find, share, and use software built for Kubernetes.” — Helm.sh

Why do we need it?

A question I asked myself multiple times trying to understand how this magical installer thing is making my Kubernetes life better. Well, Helm lets you fetch, deploy and manage the lifecycle of applications, both 3rd party products and your own.

No more maintaining random groups of YAML files (or very long ones) describing pods, replica-sets, services, RBAC settings, etc. With helm, there is a structure and a convention for a software package that defines a layer of YAML templates and another layer that changes the templates called values. Values are injected into templates, thus allowing separation of configuration, and defining where changes are allowed. This whole package is called a “Helm Chart”.

Essentially you create structured application packages that contain everything they need to run on a Kubernetes cluster; including dependencies the application requires.


Helm is a CLI, Tiller is its backend

Practically speaking, Helm is a CLI tool that interacts with its backend server called “Tiller”. Tiller is typically installed by sending the command helm init and lives in the kube-system namespace (unless instructed otherwise). It is in charge of deploying Charts requested by Helm.

When a Chart is installed, Tiller creates a “Release” and starts tracking it for changes. This way Helm not only takes part in installation but is an actual deploy tool that manages the lifecycle of applications in a cluster using Chart Releases and their revisions.


Helm concepts | Chart

Helm uses Charts to pack all the required K8s components for an application to deploy, run and scale. It is also where dependencies are defined, and configurations are updated and maintained.

A chart root has to have only one file named Chart.yaml by convention. It can optionally (and by default if you use helm create) have a few more components on which I’ll elaborate shortly, but first, here’s what a typical chart structure would look like:

    ├── Chart.yaml
    ├── templates
    │   ├── service.yaml
    │   └── replicaset.yaml
    ├── charts
    │   ├── nginx-ingress-1.1.2.tgz
    ├── requirements.lock
    ├── requirements.yaml
    └── values.yaml

In this chart (let’s call it “web-UI”), there are templates of Service and ReplicaSet, which upon helm installation will be created using the values.yaml file that can be seen a the bottom of the list. Also, the web-UI chart requires Nginx to run, and so Nginx appears as a subchart under the charts directory. requirements.yaml is the file describing the actual requirement and lists Nginx inside. The lock file which is also part of the pack is created when helm installs the requirements when commanded with helm dependency update.

A Chart.yaml is a description of the package and in fact the only required file in it, there are only three required entries: apiVersion, name and version. Here’s an example of what it would look like: (You can find the full list of options and entries in a Chart right here.)

    apiVersion: v1
    name: drone
    version: 1.0.0

Templates

Templates are an optional subdirectory in a chart. They combine the K8s components, e.g. Service, ReplicaSet, Deployment etc, converted into a Go-Template format to which values will, later on, be matched. Let’s take a look of a partial template example:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name:  {{ .Values.name }}
      labels:
        app:  {{ .Values.name }}
        somelabel:  {{ .Values.labels.somelabelkey }}

Values

Values are described in the values.yaml file which is necessarily a yaml structure holding values to match the templates. Considering the template above, a matching values file would be:

    name: web-ui
    labels:
      somelabelkey: somelabelvalue

Subcharts

Subcharts also named dependencies, are required charts for the current one. You can think of it as another way of packing applications so that if my backend requires a Redis cache to run, this is another way to set it up. Another way of using subcharts is considering it as an inheritance mechanism which allows fetching a standard chart with templates and uses it as a subcharts in multiple parent charts that would provide the values.


Helm concepts | Repository

Repositories are where helm charts are held and maintained. In essence, these are a set of templates and configuration values stored as code (sometimes packed as a .tar.gz file). When you helm install stable/redis by default helm reaches out to the Helm/Charts repo on GitHub, searching under the stable tree.

Visit this repo, and you’ll also find the incubator subdirectory where you can get and install incubated Charts that have not yet been tagged as production-ready (Stable). This does not mean you can’t use them; try introducing them in a development cluster and use them. The Helm community manages strict sem-ver guidelines for versioning, and even the smallest change creates a new Chart release. You can be confident that if a specific version of a remote Chart is working in one way, it will never break on you out of the blue.

An excellent example of using a different repo is Elastic’s ElasticSearch Chart, which used to be maintained by the company in the Helm/Charts repo.

Elastic had decided to move their product to their Helm repo, and to get the latest official Chart you can now add their repo to Helm by: helm repo add elastic https://helm.elastic.co followed by: helm install --name elasticsearch elastic/elasticsearch


Helm concepts | Release

Think of a release as a mechanism to track installed applications on a K8S cluster; when an application is installed by Helm, a release is being created. You can create different installations of a product, e.g., Redis and have two different releases created and tracked in the cluster.

Releases can be tracked with helm ls, each would have a “revision” which is the Helm release versioning terminology; if a specific release is updated, e.g., adding more memory to the Redis release, the revision would be incremented. Helm allows rolling back to a particular revision, making it virtually the manager for deployments and production status handler.


TLS

Tiller and Helm need a way to communicate. By default, this connection is not very secure, which means that if one of the endpoints is compromised or accessible to a compromised component, traffic can be read and analyzed. Beyond discussing the actual attack surface of not securing communication between systems, we can easily create a secure TLS connection using an auto-generated certificate. In order to do that here’s a script that takes you through the process and can be implemented anywhere.


Contributions

You may find yourself (like I have) running into a new requirement for ability or feature from an official chart under github.com/helm/charts, it may very well be a bug (not so unlikely with incubator charts). Since Helm and its charts are both open source projects with hundreds of contributors, they are intensely active. Make changes to the desired chart and open a PR with the contribution, if all requirements have been made and taken care of, the team will approve the change in a matter of days.

While the process is quite demanding (and we should be thankful that’s so), changes are being reviewed and approved or disapproved quickly. Read more about contributing to the project; note that if you’re only making small changes most of the document is not relevant as it outlines requirements for new charts.


That’s it.

I hope that by now you understand Helm and why it is such a powerful system. As this is just an introduction, to learn and “feel” it, there’s no going around intense work with it; deploying 3rd party products and building your charts.

My name is Omer, and I am an engineer at ProdOps — a global consultancy that delivers software in a Reliable, Secure and Simple way by adopting the Devops culture. Let me know your thoughts in the comments below, or connect with me directly on Twitter @0merxx. Clap if you liked it, it helps me focus my future writings.