ALL THINGS KUBERNETES

Simplifying App Deployment in Kubernetes with Helm Charts

You have learned in our previous tutorials how to create pods, StatefulSets, Deployments, ConfigMaps, and other Kubernetes resources by manually designing resource manifests and specs. Knowing how to work with the Kubernetes REST API is very important when you first learn the platform. Deploying apps with the manually configured resource manifests and assembling various parts of your application (e.g., RBAC, persistent storage, services) from scratch is very useful because this gives you fine-grained control over your Kubernetes applications.

However, in some cases, you want to quickly deploy a complex application that requires multiple resources and prerequisites (e.g., ConfigMaps, volumes) without bothering about its individual components. To simplify the deployment of containerized applications, the Kubernetes community created the Helm package manager and Helm charts: pre-packaged containerized applications that include all necessary resource manifests, configurations, and resources to run in Kubernetes. Helm has a purpose similar to other popular package managers: npm for Node.js, dpkg for Linux, pip for Python, and so on. It gives you access to repositories storing packages (Helm charts) that can be easily deployed, upgraded, and deleted from your Kubernetes cluster. At some point in your journey as the Kubernetes user and/or administrator, you’ll need to learn how to use Helm. In this article, we introduce you to Helm and show some common operations you can perform with it. Let’s get started!

What Is Helm?

Helm is a tool for Kubernetes packages called charts. A chart contains pre-configured Kubernetes resources such as ConfigMaps , Deployments , and StatefulSet  manifests, PersistentVolumes  , and configurable settings for them. As such, a chart may be seen as a bundle of resources that, if connected together, can create a complex Kubernetes deployment with multiple prerequisites. Charts are the convenient way to tell the Kubernetes api-server which resources a given application needs to properly run in Kubernetes.

Helm package manager supports the following operations:

  • Creating new charts from scratch
  • Packaging charts into chart archives
  • Interacting with chart repositories (retrieving charts, adding new charts to repos etc.)
  • Installing and deleting charts from an existing Kubernetes cluster
  • Performing upgrades and rollbacks of charts

Each chart exposes configuration options that can be changed by the user and merged into a release. The latter is a chart deployed with default or custom configuration options in Kubernetes. You can consider a release to be a running instance of a chart with a specific configuration. Releases are the units of deployment, upgrade, and rollback.

To facilitate coordination with the Kubernetes cluster, the Helm package manager includes two main components: the Helm Client and the Helm Server (Tiller) (see the Helm workflow in the image below).

The Helm Client is a CLI for end users that facilitates local chart development, repository management, and interacting with the Tiller server to install, inspect, upgrade, or uninstall charts.

Helm Workflow

In its turn, the Tiller Server is an in-cluster server that interacts with the client and the Kubernetes API to facilitate Helm package management. Tiller server is responsible for:

  • Processing incoming requests from the Helm client
  • Combining chart settings and custom configuration to build a release
  • Installing charts into Kubernetes and tracking the subsequent release
  • Upgrading and uninstalling charts using Kubernetes primitives and API.

Note: normally, the Tiller server is deployed in the kube-system  namespace of your cluster, but it can be also deployed locally for development purposes.

Now you have a general understanding of the Helm architecture and features, so let’s see how it works. Let’s start by installing the Helm client on your local machine.

To complete this tutorial, you’ll need the following prerequisites:

  • A running Kubernetes cluster. See Supergiant documentation for more information about deploying a Kubernetes cluster with Supergiant. As an alternative, you can install a single-node Kubernetes cluster on a local system using Minikube.
  • A kubectl command line tool installed and configured to communicate with the cluster. See how to install kubectl here.

Step 1: Installing Helm Client

There are various ways to install Helm Client: from binary, from source, using OS package managers or the installation script. You can find the installation details for your system here.

If you are using macOS as we did for this tutorial, the easiest way to install the Helm client is using Homebrew:

If you type helm  after installation, you’ll see a full list of Helm commands and further installation instructions for Tiller.

Helm Commands

Step 2: Installing Tiller

The next thing we need to do is to install the Helm Server — Tiller. Tiller typically runs inside of your Kubernetes cluster. However, you can still run it locally for development. In this tutorial, we’re going to deploy Tiller inside our Minikube cluster.

The simplest way to install tiller  into the cluster is to run helm init . This command will result in Helm connecting to the default cluster. To find the name of this cluster, run kubectl config view . After the connection is established, Helm will install tiller  into the kube-system  namespace.

As the message above suggests, the way we installed Tiller is not fully secure (see Security note below). However, it’s enough for test/learning/development clusters like Minikube.

After helm init , you will be able to run kubectl get pods --namespace kube-system  and see Tiller running.

You can use helm init  with custom flags to:

  • Install the canary build with the --canary-image  flag
  • Install a specific image version with --tiller-image
  • Install into a specific cluster with --kube-context
  • Install into a specific namespace with --tiller-namespace
  • Install Tiller with a Service Account with --service-account  for RBAC-enabled clusters

Once Tiller is installed, running helm version  should show you both the client and server version.

Security Note: If your cluster is exposed to uncontrolled network environments, or if you use multitenant clusters you should take extra steps to protect your TIller installation.

There are four key areas to consider:

  1. Role-based access control (RBAC)
  2. Tiller’s gRPC endpoint and its usage by Helm
  3. Tiller release information
  4. Making sure that Helm charts are secure

For more information about securing your Tiller server, please, consult this section of the official documentation.

Step 3: Using Helm

Helm client simplifies installation of charts into Kubernetes clusters through this simple workflow:

  • retrieve a Helm chart from a local chart package or remote repository. The chart will contain all necessary resource definitions needed to run your application.
  • edit default chart configuration to match your requirements.
  • request Tiller to create a release with chart resources and your custom configuration.
  • Tiller uses the provided resources and configuration to request K8s api-server to deploy the chart.
  • Helm client and Tiller manage the release (upgrade, rollback, delete)

Helm Repos

A Helm repository is a collection of charts (packages) installable using Helm package manager and containing common configuration for Kubernetes apps such as resource definitions to configure the application’s runtime, various dependencies, communication mechanisms, and network settings.

By default, the Helm client interacts with the /stable  branch of the official Kubernetes Charts repository that provides ~160 configured apps. The repository contains well-tested and well-maintained charts that comply with basic technical requirements of the Kubernetes. Redis, TensorFlow, NGINX, Apache Hadoop, Fluentd are just some examples of popular software available in this repository.

You can see the list of apps in the /stable  repository running helm search :

Helm Charts

To find information about the individual chart, you can run helm inspect <chart-name> . For example, to learn more about the contents of stable/redis  chart, you can do the following:

Each Chart may include the following settings:

  • metadata (see the example above)
  • image settings (repository and image names, pull policy etc.)
  • various configuration options

To find a full list of configurable options, you can use helm inspect values <chart-name> or find the official chart documentation in the chart repository on GitHub. For example, this is a partial list of configuration options for the Redis chart from the  /stable  Kubernetes repository:

Redis Config Options

You can customize the chart configuration during the installation. For example, to install the Redis chart with the server password and persistence.enabled  set to false , we can run the following command:

As you see, we are using --set  flag with a list of key/value pairs for the configuration options. Multiple values can be separated by ,  characters. So --set a=b,c=d  becomes:

If you are going to edit multiple configuration fields, it would be a good idea to save them in a file and refer to that file during the installation. For example, let’s create a file with the YAML-formatted configuration for our Redis chart:

First, delete the release running helm delete my-redis-release . Then, save the configuration above in the redis-config.yml  and install the Redis chart with the following command:

This will create the Redis release named my-redis-release  . You can give any name to your release using the --name  flag on helm install . The above command will produce the following output:

As you see, Kubernetes has created a bunch of resources for your Redis app. If you are using Minikube, open the Kubernetes dashboard with minikube dashboard  to see them or use kubectl get commands to display them in your terminal.

These are the main resources created by Tiller:

One Deployment for the Redis slave:

Redis Deployment

One StatefulSet for the Redis master:

Redis StatefulSet

One ConfigMap:

Redis ConfigMap

Two Services for Redis Slave and Redis Master each:

Redis Services

Imagine how much time it would take you to design manifests for each of these resources yourself. All of these manifests come bundled in the Redis chart and Tiller takes care of assembling and deploying them for you.

Benefits of deploying applications with Helm charts do not end there. By default, the Redis chart includes Liveness and Readiness probes to evaluate the health of your Redis Master and Slave. You can verify that by running kubectl describe ss <your-redis-statefulset-name>

Also, by default, the Redis chart configures Persistent Volumes and Persistent Volume Claims for your Redis deployment, so you shouldn’t worry about persistence of your database data.

Note: Since we are using Minikube, we had to install Redis with --set persistence.enabled=false . That is because Minikube has certain root access issues when using persistent volumes with Redis. See minikube issue 1990 for more information.

The last but not the least, the Redis chart optionally can start a metrics exporter for Prometheus. If metrics config is enabled, the chart will expose the metrics endpoint (port 9121) in the service. Now you have an idea of how much time you can save using charts instead of manually designing all resources and manifests needed to run Redis in production. Everything you need: persistence, services, metrics are bundled together into one chart.

We can make sure that all the configuration options we used during the installation were successfully applied. To see the values that were set for a given release, you can run helm get values <release-name> .

Values that have been --set  can be cleared by running helm upgrade  with --reset-values specified.

Step 4: Accessing the Redis Server

As a part of the chart installation process, Helm has automatically configured Redis master and slave. The chart includes useful directions for accessing Redis server from within your Kubernetes cluster.

To access Redis, you need to use your custom password provided during the installation.

First, export this password to the environmental variable:

Check that the password was successfully exported:

Then, run a Redis pod you can use as a client:

From within the bash of this container, you can now connect to the master with:

Or, alternatively, you can easily connect to your Redis slave:

If you want to connect to your database from outside the cluster execute the following commands:

Step 5: Managing releases

Helm client offers useful tools for managing your releases including upgrades and rollbacks. You may want to upgrade your release when a new version of the chart came out or when you need to change the chart’s configuration. To upgrade the release, you can use the helm upgrade  command. This command will take configuration you provide and try to perform the least invasive upgrade updating only things that have changed since the last release.

To illustrate how the upgrade works, let’s first change our Redis configuration file redis-config.yml :

Now, let’s upgrade the release:

After the upgrade, a new configuration is reflected in the release. We can easily verify this from our Kubernetes dashboard or with kubectl :

Redis Updated Helm Release

As you see, the Tiller have successfully applied new pod labels specified in the upgrade configuration.

If the release upgrade was not smooth or you want to return to the previous configuration of your deployment, you can rollback the release with helm rollback [RELEASE] [REVISION] . For example:

The command above rolls back my-redis-release  to its very first version. Each time you install, upgrade, or rollback the release, the revision number is incremented by 1. You can use helm history [RELEASE]  to see revision numbers for a certain release.

After upgrade, we can verify that the old configuration values were reset by running:

Great! We have successfully rolled back to the previous configuration values.

Step 6: Delete the Release

If you don’t need your release anymore, you can delete it with:

Or:

This will delete all resources (pods, StatefulSets, ConfigMaps) created by Helm.

Conclusion

As you’ve seen, Helm package manager and Helm charts dramatically simplify configuration, deployment, and management of your containerized applications in Kubernetes. Helm charts contain all configuration you may need to enable persistence storage, RBAC, network policies, liveness and readiness probes, container-specific settings and configuration for your app. The scope of configuration may vary depending on whether your app needs persistence storage and how many configuration options are exposed. In general, however, using well-maintained charts from the official /stable  repository you can deploy the app at a fraction of time without creating any resource manifests on your own. With such great powers, however, come great responsibilities. When using Helm in production you should ensure that the charts used are safe and that Helm and Tiller instances are not compromised by malicious users to get access to your cluster.