Helm: Deep Dive
In my last blog, I talked about the various tools that I’ve tried and at the very beginning of the list, resided Helm and Tiller.
Overview
Helm is an old project which started soon after Kubernetes itself and was announced at the very first Kubecon. It is the package manager for Kubernetes through which you can create, search, install, upgrade and delete charts in your Kubernetes cluster. Not limited to that use, Helm is also used in teams as a collaboration tool.
So what do I mean when I say chart? Let’s start by getting ourselves familiar with the components and terminologies of Helm
Charts
A chart can be described as a Kubernetes ready app or package that can be directly installed into a cluster and used. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster. You can find over 1000+ such charts at Helm Hub repository which are created to solve and help with community-wide needs.
Repository
A repository is a place where charts can be stored, collected, and shared.
Release
A release is a running instance of a chart in a Kubernetes cluster. One chart can be installed multiple times into the same cluster and each time it is installed, a new release is created.
How does helm setup work?
Helm comprises of two components, a command-line client to view and manage packages on the user’s side and a server called Tiller to install the packages on the cluster.
The Helm client allows developers to create new charts, manage chart repositories, and interact with the tiller server.
On the server-side, the Tiller server runs inside the Kubernetes cluster. It interacts with the Helm client and translates chart definitions and configuration to Kubernetes API commands. Tiller combines a chart and its configuration to build a release. Tiller is also responsible for upgrading charts, or uninstalling and deleting them from the Kubernetes cluster.
Installation
Helm installation can we carried out with great ease, all thanks to the readily available script which you can directly curl and execute, or you can download the binaries of your desired version and store them at /usr/local/bin/helm. For the installation of more platforms, check the docs for the steps.
After executing these steps, the installation can be verified using the helm version command. If all went as planned, this command prints the client version of helm but prompts an error or times out for the server-side installation. This is because our client-side Helm is in place but we are yet to initialize the Tiller at the server side. To do that, run helm init. This will install Tiller to your running Kubernetes cluster and will also set up any necessary local configuration.
On successful execution, you will get the following message
Tiller (the Helm server-side component) has been installed into your Kubernetes Clusterhelm version should return both client and server versions.
Next optional, but advised step would be to update the local cache to sync the latest available packages with the environment using helm repo update command.
Helm and Tiller setup is ready to be used. Happy Helming!
Know your commands
Searching for charts :
helm search <source> <chart>|helm search <chart>
The source can be hub which will search charts on the Helm Hub or it can be a repo that you have added.
To add a repo, use the command helm repo add <name> <repository-url>. Now you can search your repository using the commandhelm search repo <chart> .
Inspecting a chart :
helm inspect <chart-name>
Inspecting a chart gives tons of details about the chart including and not limited to name, source, app version, api version, description and value file. We will know more about the value file later in this blog.
Installing a chart :
helm install <release> <chart>
This command will install the specified chart with the specified release name. On executing the install command, the following information would be shown on the cli.
- Last Deployed: Date and time of deployment.
- Namespace: Namespace in which deployments are created.
- Status: Current status of the release. When completed, this value would be
DEPLOYED. The status of the release can be viewed at any time using the commandhelm status <release-name>. - Resources: The resources created as part of the chart.
- Notes: The notes provided by the author of the chart which can be of help for the user using the chart. We will discuss it in more details while creating our own chart later in this blog.
If using a later version of Helm, release name can be left unspecified and generate-name flag can be used instead. In earlier versions, this flag is by default set to true.
Custom installation of charts :
Charts have a value file containing the variable which can be overridden. These values can be viewed using helm show values <chart>.
To provide a custom file containing the new values for the variales, pass it in the following format helm install -f <value-file> <release-name> <chart> or helm install --values <value-file> <release-name> <chart>.
Or to specify a few values, use the set flag as helm install --set <variable1>=<value1>,<variable2>=<value2> <chart>.
Note that if both set and values flags are used in the same command, then both the provided values will be merged and in case of any overlapping, the ones provided by set will get priority over those provided by values .
Also, The set and values can be used with helm upgrade command as well.
Viewing Helm installations:
helm list
To list the installed releases, use helm list command. Furthermore, to view the releases which are now uninstalled as well, use helm list --all. This will show details like
- NAME: Name of the release.
- REVISION: The first installation of any chart is considered as the first revision. Every subsequent upgrade or change creates a new revision. This integer value can be used to rollback in case of failed installations.
- UPDATED: Timestamp of the last update performed on the release.
- STATUS: Current status of the release.
- CHART: Chart installed as part of the release.
Upgrading a chart :
helm upgrade <release> <chart> <flags>
Upgrade command is used to upgrade the existing release with either new values or new charts. As shown in the custom installation of chart topic, use values, f or set to provide new values while upgrading like helm install -f <new-value-file> <release> <chart>. On upgrading, the status of the previous revision changes to SUPERSEDED.
Rolling back an upgrade :
helm rollback <release> <revision>
rollback command is used to rollback any release in case of a failure. Note that any rollback will also create a new revision in the history and similar to the case of an upgrade, will change the status of the previous revision to SUPERSEDED.
Viewing the history of revisions :
helm history <release>
To view the charts, status, and update timestamps of the various revision of a release, history command can be used.
Uninstalling a chart :
helm uninstall <release>
To remove any release, uninstall command can be used. In previous versions of Helm, when a release was uninstalled, a record of its deletion would remain. In later versions, deletion removes the release record as well. If you wish to keep a deletion release record, use --keep-history flag with the uninstall command.
Get Vaibhav Rajput’s stories in your inbox
Join Medium for free to get updates from this writer.
Creating a chart is a big topic itself and so deserves a separate section, so moving on to creating your very own chart.
Creating a Chart
To start creating your own Helm chart, start with helm create <chart-name> command. This will create the following directory structure within a folder by the name specified chart name.
Let us first understand what all these files and directories signify
- charts : Contains the charts that this chart will be using and will be dependent on.
- Chart.yaml : Contains the metadata about the chart like chart name, version, author/maintainer etc.
- .helmignore : Contains files or patterns for files which will be ignored when packaging Helm charts on completion.
- templates : Contains the templates for resources that should be created when installing the chart.
- values.yaml : As discussed previously in this blog, this file is used to store default values for variables. These variables can be overridden while installing or upgrading the release.
At this stage, the package is ready to be installed using the command helm install ./<chart-name>/. And will give an output similar to this
Since we gave no name to our release, it has been named ponderous-spaniel. It will different for you. I love these creative names so I will let it stay like this, however you can always give a release name.
After the name, we can see the deployed timestamp, namespace and status.
Followed by these are the resource which includes deployment, a service and a pod created as part of the deployment. The deployment and service are created using the template files present under <chart-name>/template/ folder. If you look at these deployment files, you will see that these are picking variables defined in values.yaml file and the Chart.yaml. Also, you must have noticed a ingress.yaml file in the templates folder which did not get deployed. That is also due to the values present in the values.yaml file.
The templates/ingress.yaml started with the following if condition
{{- if .Values.ingress.enabled -}}This condition states that if the enabled tag in the ingress section in values file is true, this condition will hold true.
And in our values.yaml, the default values set was
ingress: enabled: false
Hence, the content of template/ingress.yaml did not get deployed.
Similarly, in template/deployment.yaml file, we see the following in the spec section
spec: containers: - name: {{ .Chart.Name }} image: “{{ .Values.image.repository }}:{{ .Values.image.tag }}”
Here, the name of the pod will be taken from the Name tag defined in Chart.yaml and the image will be taken from repository and tag from the image section of values.yaml file.
I hope that clarifies how values.yaml and Chart.yaml files are used to customize and select templates to be deployed from the template directory.
Apart from just picking up values from these files, they can also be used to manipulate and format templates using different template functions, pipelines and flow controls as shown under the chart template developer’s guide.
Getting back to the output we got from installing the chart, we also saw some NOTES at the bottom. These are generated using the templates/NOTES.txt file. These are used to provide any complementary data that can be helpful to the user who is installing this chart.
Tip: For completely ignoring packaging of any template file, you can add the file in
.helmignorefile
Yes, this is a very basic chart which does not solve much of a problem but it was created to help you, readers, in understanding how a chart gets packaged and installed in the cluster. To add more resource as per your requirements, you can always add more template files in the templates folder and they will get deployed as the chart is installed.
Some helpful tips and tricks while creating your own chart
Linting
Use helm lint ./<chart-name> command to see if your chart is well-formed. It will help you to not only find fatal errors but also best practice recommendations.
Dry Run
Use dry-run flag like helm install ./<chart-name> --dry-run to check if your chart will give an error while installing. It will not install the chart resources, so there is no need to clean the residue on failure.
Debug
Use debug flag as helm install ./<chart-name> --debug to get a more in-depth view of the installation. This will show you the following details
- SERVER: “127.0.0.1:39348” : This states that Helm client created a connection to Tiller to install the chart. Note that ports can be different for every system.
- CHART PATH : The path where the chart is placed on the local system.
- NAME : Name of the release.
- REVISION : As shown earlier, ideally it will be 1 for our first installation and will be incremented with every subsequent upgrade or rollback.
- RELEASED : The timestamp on which the chart was packaged. A package can be created using the
helm package <chart-name>command which will convert chart directory to a chart archive. - CHART : Name and version of the chart.
- USER-SUPPLIED VALUES : Values provided using
valuesorsetflag during installation. If no value is provided, it will show{}. - COMPUTED VALUES : Values provided in
values.yamlfile. - HOOKS : Hooks are used for intervening at specific points in a release’s life cycle including before and after installation, deletion, upgrade or rollback. While creating a template, if annotation tag with key
”helm.sh/hook”and valid value is provided in themetadata, then the resource defined in that template is treated as a hook. One of their use can be to perform health checks to verify that pod resources are up and running e.g. making TCP calls to a server created as part of the chart to see if they are responding as intended post-installation. - MANIFEST : Template files after replacing the template functions, flow controls and pipelines with rendered values hence creating the final deployable template files. Once installed, the manifest files can be seen using
helm get manifest <release-name>at any time.
Helm 2 vs Helm 3
As stated in the architecture section of this blog, Helm comprises of two components, a command-line client to view and manage packages on the user’s side and a server called Tiller. Until Helm 2 release, there was a constantly running Tiller server in your cluster. To be able to create and delete resources, Tiller holds admin privileges which is a concern for security as this permissive configuration could grant a user a broad range of permissions they weren’t intended to have.
So, as the Helm development teams observed how community members were using Helm in certain scenarios, they found that Tiller’s release management system did not need to rely upon an in-cluster operator to maintain state or act as a central hub for Helm release information and given to the Custom Resource Definitions, Tiller outlived its need. Hence, Helm 3 got rearchitected to remove Tiller and move a lot of this logic into more modern Kubernetes techniques like operators and a client-side template which now fetches information from the Kubernetes API server, renders the charts client-side, and store a record of the installation in Kubernetes.
If you are working with Helm 2 and want to shift to all modern security, identity, and authorization features supported Helm 3, Helm has created a document for you to stay with the pace.











