Using Helm

This guide explains the basics of using Helm (and Tiller) to managepackages on your Kubernetes cluster. It assumes that you have alreadyinstalled the Helm client and the Tiller server (typically by helm init).

If you are simply interested in running a few quick commands, you maywish to begin with the Quickstart Guide. This chaptercovers the particulars of Helm commands, and explains how to use Helm.

Three Big Concepts

A Chart is a Helm package. It contains all of the resource definitionsnecessary to run an application, tool, or service inside of a Kubernetescluster. Think of it like the Kubernetes equivalent of a Homebrew formula,an Apt dpkg, or a Yum RPM file.

A Repository is the place where charts can be collected and shared.It’s like Perl’s CPAN archive or theFedora Package Database, butfor Kubernetes packages.

A Release is an instance of a chart running in a Kubernetes cluster.One chart can often be installed many times into the same cluster. Andeach time it is installed, a new release is created. Consider a MySQLchart. If you want two databases running in your cluster, you caninstall that chart twice. Each one will have its own release, whichwill in turn have its own release name.

With these concepts in mind, we can now explain Helm like this:

Helm installs charts into Kubernetes, creating a new release foreach installation. And to find new charts, you can search Helm chartrepositories.

‘helm search’: Finding Charts

When you first install Helm, it is preconfigured to talk to the officialKubernetes charts repository. This repository contains a number ofcarefully curated and maintained charts. This chart repository is namedstable by default.

You can see which charts are available by running helm search:

  1. $ helm search
  2. NAME VERSION DESCRIPTION
  3. stable/drupal 0.3.2 One of the most versatile open source content m...
  4. stable/jenkins 0.1.0 A Jenkins Helm chart for Kubernetes.
  5. stable/mariadb 0.5.1 Chart for MariaDB
  6. stable/mysql 0.1.0 Chart for MySQL
  7. ...

With no filter, helm search shows you all of the available charts. Youcan narrow down your results by searching with a filter:

  1. $ helm search mysql
  2. NAME VERSION DESCRIPTION
  3. stable/mysql 0.1.0 Chart for MySQL
  4. stable/mariadb 0.5.1 Chart for MariaDB

Now you will only see the results that match your filter.

Why ismariadb in the list? Because its package description relates it toMySQL. We can use helm inspect chart to see this:

  1. $ helm inspect stable/mariadb
  2. Fetched stable/mariadb to mariadb-0.5.1.tgz
  3. description: Chart for MariaDB
  4. engine: gotpl
  5. home: https://mariadb.org
  6. keywords:
  7. - mariadb
  8. - mysql
  9. - database
  10. - sql
  11. ...

Search is a good way to find available packages. Once you have found apackage you want to install, you can use helm install to install it.

‘helm install’: Installing a Package

To install a new package, use the helm install command. At itssimplest, it takes only one argument: The name of the chart.

  1. $ helm install stable/mariadb
  2. Fetched stable/mariadb-0.3.0 to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
  3. NAME: happy-panda
  4. LAST DEPLOYED: Wed Sep 28 12:32:28 2016
  5. NAMESPACE: default
  6. STATUS: DEPLOYED
  7. Resources:
  8. ==> extensions/Deployment
  9. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
  10. happy-panda-mariadb 1 0 0 0 1s
  11. ==> v1/Secret
  12. NAME TYPE DATA AGE
  13. happy-panda-mariadb Opaque 2 1s
  14. ==> v1/Service
  15. NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  16. happy-panda-mariadb 10.0.0.70 <none> 3306/TCP 1s
  17. Notes:
  18. MariaDB can be accessed via port 3306 on the following DNS name from within your cluster:
  19. happy-panda-mariadb.default.svc.cluster.local
  20. To connect to your database run the following command:
  21. kubectl run happy-panda-mariadb-client --rm --tty -i --image bitnami/mariadb --command -- mysql -h happy-panda-mariadb

Now the mariadb chart is installed. Note that installing a chartcreates a new release object. The release above is namedhappy-panda. (If you want to use your own release name, simply use the—name flag on helm install.)

During installation, the helm client will print useful informationabout which resources were created, what the state of the release is,and also whether there are additional configuration steps you can orshould take.

Helm does not wait until all of the resources are running before itexits. Many charts require Docker images that are over 600M in size, andmay take a long time to install into the cluster.

To keep track of a release’s state, or to re-read configurationinformation, you can use helm status:

  1. $ helm status happy-panda
  2. Last Deployed: Wed Sep 28 12:32:28 2016
  3. Namespace: default
  4. Status: DEPLOYED
  5. Resources:
  6. ==> v1/Service
  7. NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  8. happy-panda-mariadb 10.0.0.70 <none> 3306/TCP 4m
  9. ==> extensions/Deployment
  10. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
  11. happy-panda-mariadb 1 1 1 1 4m
  12. ==> v1/Secret
  13. NAME TYPE DATA AGE
  14. happy-panda-mariadb Opaque 2 4m
  15. Notes:
  16. MariaDB can be accessed via port 3306 on the following DNS name from within your cluster:
  17. happy-panda-mariadb.default.svc.cluster.local
  18. To connect to your database run the following command:
  19. kubectl run happy-panda-mariadb-client --rm --tty -i --image bitnami/mariadb --command -- mysql -h happy-panda-mariadb

The above shows the current state of your release.

Customizing the Chart Before Installing

Installing the way we have here will only use the default configurationoptions for this chart. Many times, you will want to customize the chartto use your preferred configuration.

To see what options are configurable on a chart, use helm inspect values:

  1. helm inspect values stable/mariadb
  2. Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
  3. ## Bitnami MariaDB image version
  4. ## ref: https://hub.docker.com/r/bitnami/mariadb/tags/
  5. ##
  6. ## Default: none
  7. imageTag: 10.1.14-r3
  8. ## Specify a imagePullPolicy
  9. ## Default to 'Always' if imageTag is 'latest', else set to 'IfNotPresent'
  10. ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images
  11. ##
  12. # imagePullPolicy:
  13. ## Specify password for root user
  14. ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run
  15. ##
  16. # mariadbRootPassword:
  17. ## Create a database user
  18. ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run
  19. ##
  20. # mariadbUser:
  21. # mariadbPassword:
  22. ## Create a database
  23. ## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-on-first-run
  24. ##
  25. # mariadbDatabase:

You can then override any of these settings in a YAML formatted file,and then pass that file during installation.

  1. $ cat << EOF > config.yaml
  2. mariadbUser: user0
  3. mariadbDatabase: user0db
  4. EOF
  5. $ helm install -f config.yaml stable/mariadb

The above will create a default MariaDB user with the name user0, andgrant this user access to a newly created user0db database, but willaccept all the rest of the defaults for that chart.

There are two ways to pass configuration data during install:

  • —values (or -f): Specify a YAML file with overrides. This can be specified multiple timesand the rightmost file will take precedence
  • —set (and its variants —set-string and —set-file): Specify overrides on the command line.

If both are used, —set values are merged into —values with higher precedence.Overrides specified with —set are persisted in a configmap. Values that have been—set can be viewed for a given release with helm get values <release-name>.Values that have been —set can be cleared by running helm upgrade with —reset-valuesspecified.

The Format and Limitations of —set

The —set option takes zero or more name/value pairs. At its simplest, it isused like this: —set name=value. The YAML equivalent of that is:

  1. name: value

Multiple values are separated by , characters. So —set a=b,c=d becomes:

  1. a: b
  2. c: d

More complex expressions are supported. For example, —set outer.inner=value istranslated into this:

  1. outer:
  2. inner: value

Lists can be expressed by enclosing values in { and }. For example,—set name={a, b, c} translates to:

  1. name:
  2. - a
  3. - b
  4. - c

As of Helm 2.5.0, it is possible to access list items using an array index syntax.For example, —set servers[0].port=80 becomes:

  1. servers:
  2. - port: 80

Multiple values can be set this way. The line —set servers[0].port=80,servers[0].host=example becomes:

  1. servers:
  2. - port: 80
  3. host: example

Sometimes you need to use special characters in your —set lines. You can usea backslash to escape the characters; —set name="value1\,value2" will become:

  1. name: "value1,value2"

Similarly, you can escape dot sequences as well, which may come in handy when charts use thetoYaml function to parse annotations, labels and node selectors. The syntax for—set nodeSelector."kubernetes.io/role"=master becomes:

  1. nodeSelector:
  2. kubernetes.io/role: master

Deeply nested data structures can be difficult to express using —set. Chartdesigners are encouraged to consider the —set usage when designing the formatof a values.yaml file.

Helm will cast certain values specified with —set to integers.For example, —set foo=true results Helm to cast true into an int64 value.In case you want a string, use a —set’s variant named —set-string. —set-string foo=true results in a string value of "true".

—set-file key=filepath is another variant of —set.It reads the file and use its content as a value.An example use case of it is to inject a multi-line text into values without dealing with indentation in YAML.Say you want to create a brigade project with certain value containing 5 lines JavaScript code, you might write a values.yaml like:

  1. defaultScript: |
  2. const { events, Job } = require("brigadier")
  3. function run(e, project) {
  4. console.log("hello default script")
  5. }
  6. events.on("run", run)

Being embedded in a YAML, this makes it harder for you to use IDE features and testing framework and so on that supports writing code.Instead, you can use —set-file defaultScript=brigade.js with brigade.js containing:

  1. const { events, Job } = require("brigadier")
  2. function run(e, project) {
  3. console.log("hello default script")
  4. }
  5. events.on("run", run)

More Installation Methods

The helm install command can install from several sources:

  • A chart repository (as we’ve seen above)
  • A local chart archive (helm install foo-0.1.1.tgz)
  • An unpacked chart directory (helm install path/to/foo)
  • A full URL (helm install https://example.com/charts/foo-1.2.3.tgz)

‘helm upgrade’ and ‘helm rollback’: Upgrading a Release, and Recovering on Failure

When a new version of a chart is released, or when you want to changethe configuration of your release, you can use the helm upgradecommand.

An upgrade takes an existing release and upgrades it according to theinformation you provide. Because Kubernetes charts can be large andcomplex, Helm tries to perform the least invasive upgrade. It will onlyupdate things that have changed since the last release.

  1. $ helm upgrade -f panda.yaml happy-panda stable/mariadb
  2. Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
  3. happy-panda has been upgraded.
  4. Last Deployed: Wed Sep 28 12:47:54 2016
  5. Namespace: default
  6. Status: DEPLOYED
  7. ...

In the above case, the happy-panda release is upgraded with the samechart, but with a new YAML file:

  1. mariadbUser: user1

We can use helm get values to see whether that new setting tookeffect.

  1. $ helm get values happy-panda
  2. mariadbUser: user1

The helm get command is a useful tool for looking at a release in thecluster. And as we can see above, it shows that our new values frompanda.yaml were deployed to the cluster.

Now, if something does not go as planned during a release, it is easy toroll back to a previous release using helm rollback [RELEASE] [REVISION].

  1. $ helm rollback happy-panda 1

The above rolls back our happy-panda to its very first release version.A release version is an incremental revision. Every time an install,upgrade, or rollback happens, the revision number is incremented by 1.The first revision number is always 1. And we can use helm history [RELEASE]to see revision numbers for a certain release.

Helpful Options for Install/Upgrade/Rollback

There are several other helpful options you can specify for customizing thebehavior of Helm during an install/upgrade/rollback. Please note that thisis not a full list of cli flags. To see a description of all flags, just runhelm <command> —help.

  • —timeout: A value in seconds to wait for Kubernetes commands to completeThis defaults to 300 (5 minutes)
  • —wait: Waits until all Pods are in a ready state, PVCs are bound, Deploymentshave minimum (Desired minus maxUnavailable) Pods in ready state andServices have an IP address (and Ingress if a LoadBalancer) beforemarking the release as successful. It will wait for as long as the—timeout value. If timeout is reached, the release will be marked asFAILED. Note: In scenario where Deployment has replicas set to 1 andmaxUnavailable is not set to 0 as part of rolling update strategy,—wait will return as ready as it has satisfied the minimum Pod in ready condition.
  • —no-hooks: This skips running hooks for the command
  • —recreate-pods (only available for upgrade and rollback): This flagwill cause all pods to be recreated (with the exception of pods belonging todeployments)

‘helm delete’: Deleting a Release

When it is time to uninstall or delete a release from the cluster, usethe helm delete command:

  1. $ helm delete happy-panda

This will remove the release from the cluster. You can see all of yourcurrently deployed releases with the helm list command:

  1. $ helm list
  2. NAME VERSION UPDATED STATUS CHART
  3. inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0

From the output above, we can see that the happy-panda release wasdeleted.

However, Helm always keeps records of what releases happened. Need tosee the deleted releases? helm list —deleted shows those, and helm list —all shows all of the releases (deleted and currently deployed,as well as releases that failed):

  1. helm list --all
  2. NAME VERSION UPDATED STATUS CHART
  3. happy-panda 2 Wed Sep 28 12:47:54 2016 DELETED mariadb-0.3.0
  4. inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0
  5. kindred-angelf 2 Tue Sep 27 16:16:10 2016 DELETED alpine-0.1.0

Because Helm keeps records of deleted releases, a release name cannot bere-used. (If you really need to re-use a release name, you can use the—replace flag, but it will simply re-use the existing release andreplace its resources.)

Note that because releases are preserved in this way, you can rollback adeleted resource, and have it re-activate.

‘helm repo’: Working with Repositories

So far, we’ve been installing charts only from the stable repository.But you can configure helm to use other repositories. Helm providesseveral repository tools under the helm repo command.

You can see which repositories are configured using helm repo list:

  1. $ helm repo list
  2. NAME URL
  3. stable https://kubernetes-charts.storage.googleapis.com
  4. local http://localhost:8879/charts
  5. mumoshu https://mumoshu.github.io/charts

And new repositories can be added with helm repo add:

  1. $ helm repo add dev https://example.com/dev-charts

Because chart repositories change frequently, at any point you can makesure your Helm client is up to date by running helm repo update.

Creating Your Own Charts

The Chart Development Guide explains how to develop your owncharts. But you can get started quickly by using the helm createcommand:

  1. $ helm create deis-workflow
  2. Creating deis-workflow

Now there is a chart in ./deis-workflow. You can edit it and createyour own templates.

As you edit your chart, you can validate that it is well-formatted byrunning helm lint.

When it’s time to package the chart up for distribution, you can run thehelm package command:

  1. $ helm package deis-workflow
  2. deis-workflow-0.1.0.tgz

And that chart can now easily be installed by helm install:

  1. $ helm install ./deis-workflow-0.1.0.tgz
  2. ...

Charts that are archived can be loaded into chart repositories. See thedocumentation for your chart repository server to learn how to upload.

Note: The stable repository is managed on the Helm ChartsGitHub repository. That projectaccepts chart source code, and (after audit) packages those for you.

Tiller, Namespaces and RBAC

In some cases you may wish to scope Tiller or deploy multiple Tillers to a single cluster. Here are some best practices when operating in those circumstances.

  • Tiller can be installed into any namespace. By default, it is installed into kube-system. You can run multiple Tillers provided they each run in their own namespace.
  • Limiting Tiller to only be able to install into specific namespaces and/or resource types is controlled by Kubernetes RBAC roles and rolebindings. You can add a service account to Tiller when configuring Helm via helm init —service-account <NAME>. You can find more information about that here.
  • Release names are unique PER TILLER INSTANCE.
  • Charts should only contain resources that exist in a single namespace.
  • It is not recommended to have multiple Tillers configured to manage resources in the same namespace.

Conclusion

This chapter has covered the basic usage patterns of the helm client,including searching, installation, upgrading, and deleting. It has alsocovered useful utility commands like helm status, helm get, andhelm repo.

For more information on these commands, take a look at Helm’s built-inhelp: helm help.

In the next chapter, we look at the process of developing charts.