Helm Charts: An Organised Way to Install Apps on a Kubernetes Cluster
Tags: devops, kubernetes, helm
Published: 2023-11-27 12:59:16

Helm is a package manager for Kubernetes that helps in automating the deployment of applications in the Kubernetes cluster. Helm packages are called charts. A chart is a collection of related resources inside a directory that can deploy a variety of applications like databases, web applications, monitoring applications, machine learning applications and other related solutions to a Kubernetes cluster.

The charts can be downloaded from a repository and shared. A repository is a hub where Kubernetes packages are stored in the form of Helm charts. You can access these charts from [ArtifactHub](https://artifacthub.io/) which is the repository containing the Helm packages. Once a chart is deployed in a Kubernetes cluster a release is created. A release is an instance of a chart running in the cluster and every time you install a chart a release is created.

In this article, you will set up Helm and learn how to search, install, upgrade, do rollbacks, uninstall and manage chart releases. You will also create and package your own charts and set up your chart repositories that host charts that you want to install.

### Prerequisites

- [Minikube](https://minikube.sigs.k8s.io/docs/start/) installed which will be used to run the Kubernetes cluster locally on your machine. To start Minikube run the following command:
```
minikube start --driver=virtualbox
```
Here Virtualbox is used as the driver of choice to start the minikube cluster. To use [virtualbox] (https://www.virtualbox.org/wiki/Downloads) ensure that it is installed. You can also use docker as a driver instead of VirtualBox. The Minikube command to use with the docker driver is `minikube start --driver=docker`. Note that the [drivers](https://minikube.sigs.k8s.io/docs/drivers/) which you can use with `minikube start` are not just restricted to these two drivers demonstrated above.
- [Kubectl](https://kubernetes.io/docs/tasks/tools/) should also be installed. Luckily kubectl comes pre-installed with Minikube.
- Ensure you have [docker](https://docs.docker.com/engine/install/) installed on your machine. Docker is a virtualization platform for shipping applications as containers.
- Basic knowledge of [docker](https://docs.docker.com/get-started/overview/) and [kubernetes](https://kubernetes.io/docs/tutorials/kubernetes-basics/) will be beneficial to follow this tutorial. 
To confirm if your local Kubernetes cluster is running use the following command.
```
minikube status
```
An output similar to the following will be displayed.
```
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
```
You can test the connectivity of the cluster with the following command.

```
kubectl cluster-info
```
If everything works fine there will be no errors and you are now connected to the local Kubernetes cluster. With the basic connection setup in place, it's time to install Helm.

### Helm Installation
In this section you will see how to install `helm` on various `os` platforms.
#### Installing Helm On Linux
To install Helm in Linux use the following commands.

```
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
```
#### Installing Helm on macOS
[Homebrew]() package manager for macOS will be used to install Helm.

```
brew install helm
```
#### Installing Helm on Windows
Type the following commands on the Windows terminal to install helm. You can use either [Scoop](https://scoop.sh/#/) a command-line installer for Windows or [Chocolatey](https://chocolatey.org/) which is a Package Manager for Windows to install helm.
##### Installing with Scoop

```
scoop install helm
```
##### Installing with Chocolately

```
choco install kubernetes-helm
```
To confirm if Helm is installed type `helm` on the terminal and an output displaying various helper commands from helm will be displayed.

### Searching Helm  Charts from a Chart Repository
Helm charts are stored in a chart repository. This repository analogy is similar to [docker hub](https://hub.docker.com/) where you can pull or push images. In a chart repository, you can also pull your charts from the repository and update the repository locally for you to use the chart.
The repository that hosts  Helm charts is [ArtifactHub](https://artifacthub.io/).  ArtifactHub is a web based application that enables finding, installing and publishing Kubernetes packages and configurations. 
Searching for the helm charts can be done in two ways:
- Through the terminal.
- Through the artifacthub graphical user interface.

Let's search for one of the most commonly used charts in DevOps which is [Grafana](https://grafana.com/). Grafana is an interactive data visualization platform that provides charts that are put into dashboards from which insights from complex infrastructure can be analyzed. You can also query and set alerts based on the set criteria for metrics on the supported integrated data sources with grafana. Searching grafana helm chart via the terminal can be done with the following command.

```
helm search hub grafana
```
The output will display a list of grafana charts from which you can choose from.
##### output
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u54kp12m11su7iv5pf2y.png)

You can also search the `Grafana` chart via the artifacthub homepage and all the indexed charts related to grafana will be displayed.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3s4wbkepn3cpgycazg4.png)

A list of available grafana charts will be displayed from which you can choose the one you want to use.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zw8im2a9f7v9jarql05.png)

The Helm charts in ArtifactHub have instructions on how to install the charts on the cluster. Select the first grafana chart displayed on the results list and click the install button shown on the right side of the page. A pop-up with the installation instructions will be displayed as shown below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8lcz68q9ivs8jhjbrp6o.png)

You can copy the instructions at the terminal to add the grafana repository of the grafana helm chart to the cluster:

```
helm repo add grafana https://grafana.github.io/helm-charts
```
#### output

```
"grafana" has been added to your repositories
```
Once the repo has been added let Helm know it exists by doing an update:

```
helm repo update
```
#### output

```
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "grafana" chart repository
Update Complete. ⎈Happy Helming!⎈
```
Having done the above, the next step is to install the Helm chart.

### Helm Chart Installation
The `grafana` chart repo added in the previous section contains configuration variables that can be modified if you want to upgrade or do a rollback of a release. The values are stored in `values.yaml` file and can be viewed with the command `helm show values chartname`. The chartname in your case is `(repository/chartname)` which is `grafana/grafana` as shown in the following command:

```
 helm show values grafana/grafana
```
A long output of the values stored in the `values.yaml` file for grafana chart will be displayed. To install the grafana helm chart, `helm install` command is used with the following format:

```
 helm install releasename repository/chartname
```
In your instance replace the above command with the following values:

```
helm install grafana grafana/grafana
```
The displayed output will be similar to the following:
####output
```
NAME: grafana
LAST DEPLOYED: Tue Nov 21 23:53:13 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:
   kubectl get secret --namespace default grafana -o 
   jsonpath="{.data.admin-password}" | base64 --decode ; echo
...
```
The output displayed has a `NAME` which is the name of your release `grafana`. Other metadata information include `namespace`, `revision`, `status` and `deployment date` of when the helm chart was installed. The `NOTES` section contains instructions of how to implement the installed chart and access to it.
To review the deployed charts use `helm list` command:

```
helm list
```
##### output
```
NAME   	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART        	APP VERSION
grafana	default  	1       	2023-11-21 23:53:13.531164235 +0300 EAT	deployed	grafana-7.0.8	10.1.5     
```
To view if the installed grafana release is working, run the command below to see the pods running:

```
kubectl get pods
```
##### output
```
NAME                                   READY   STATUS      RESTARTS   AGE
grafana-f4bf7955b-6lzbn                1/1     Running     0          63m
```
You can also view all Kubernetes resource components by using the command `kubectl get all` which will show resources like `pods`, `deployments`, `services` and `replicasets`. 

### Upgrading a Helm Release
With the deployed release now in place, you may want to modify the release to handle more traffic by increasing the number of `pods` running in the cluster. For this to be done you will have to do an upgrade of the deployed release. At this point, you may ponder whether you have to uninstall the release and redeploy it afresh again with the new changes. The good thing for you is that is not necessary. You can use `helm upgrade` command to upgrade the release and a new version of the chart will be created.
The grafana chart has a configuration known as replicas that control the number of deployed pods. Currently, one pod is running in the cluster. To confirm the pod running, use the following command:

```
kubectl get pods
```
##### output

```
NAME                                   READY   STATUS      RESTARTS   AGE
grafana-f4bf7955b-6lzbn                1/1     Running     0          63m
```
From the above, you can see the pod that is running is one as shown in the `READY` column with `1/1`. What if you want to implement redundancy in your system to prevent failure in case one of the pods is not running properly? Redundancy in such a scenario can be achieved by adding more pods. Set the configuration variable `replicas` of the grafana chart to use `3 pods` with the following command:

```
helm upgrade grafana  grafana/grafana --set replicas=3 --reuse-values
```
The `--reuse-values` flag instructs helm to merge the new value set with the old values. This means the old values are added on top of the previous release. The updated release will look like the one below:

##### output
```
Release "grafana" has been upgraded. Happy Helming!
NAME: grafana
LAST DEPLOYED: Wed Nov 22 01:03:28 2023
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
...
```
To view whether the pods running are three in number after upgrading, run the command below:
 
```
kubectl get pods
```
##### output

```
NAME                                   READY   STATUS      RESTARTS   AGE
grafana-564c5b7d4b-b7fjh               1/1     Running     0          116s
grafana-564c5b7d4b-p9dgq               1/1     Running     0          2m7s
grafana-564c5b7d4b-z4h5j               1/1     Running     0          2m18s
```
From the above results, you can see three grafana pods are now running after upgrading the release. You can now test the grafana dashboard chart in the browser to see if it is running on the Kubernetes cluster.  Start by getting the password you will use to login in with the following command:

```
kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
```
A lengthy string containing the password will be shown. Keep it somewhere safe as you will need it for login. Next is to get the Grafana URL by running the following commands at the terminal:
```
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")
```
Proceed to use the `POD_NAME` variable with the following command:
```
kubectl --namespace default port-forward $POD_NAME 3000
```
The output at the terminal will display results similar to the one below after doing a port-forward:
##### output
```
Forwarding from 127.0.0.1:3000 -> 3000
Forwarding from [::1]:3000 -> 3000
```
Go to the browser of your choice and paste `127.0.0.1:3000` and a graphical user interface to login to grafana will be displayed as shown below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whdu1vbtyed5bpdgv0bp.png)

To login use `admin` as the username and for the password field copy the string of password you earlier got when you ran the `kubectl get secret ...` command. When logged in, the dashboard will appear like the one below and you can now explore the grafana dashboard features.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wex3valy9f76aeogcjxl.png)

With this in place, the next step is to do rollback changes and delete the release.

#### Implementing a Rollback and Deleting a Release
When you do a Helm Upgrade on a release, a new version is created in an incremental manner. Helm stores all the revisions of a release internally which allows you to return to a previous revision if needed. In your scenario, you want to revert back to one pod from the current three pods running. The `helm rollback release_name release_version` command will be used for the revision. To do a rollback to `revision 1` which is the state where you had one pod run the following command:

```
helm rollback grafana 1
```
The output you get will show the rollback is successful as shown below.
##### output
```
Rollback was a success! Happy Helming!
```
You can check the revised revision by listing the releases.

```
helm list
```
The new revision is `3` and not `1`.
##### output
```
NAME   	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART        	APP VERSION
grafana	default  	3       	2023-11-22 01:15:42.462861105 +0300 EAT	deployed	grafana-7.0.8	10.1.5     
```
In every change whether an upgrade or rollback of a release, helm will create a new revision. In your case, the revision will be `3` but still will be similar to revision `1` which has one pod. You can confirm this by running:

```
kubectl get pods
```
The output below will show one pod running in your grafana release.
##### output
```
NAME                                   READY   STATUS      RESTARTS   AGE
grafana-f4bf7955b-bl5rw                1/1     Running     0          2m30s
```
To delete a release and associated revisions use `helm delete release_name` command. The following command will delete the grafana release in the cluster:

```
helm delete grafana
```
The output will display results stating that grafana has been uninstalled:
##### output
```
release "grafana" uninstalled
```
You can now confirm if the release has been deleted:

```
helm list
```
The output displayed will show no release list available:
##### output

```
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION
```
### Deploying Custom Charts
In this section you are going to deploy your own custom helm charts. Use the following command to create a custom chart named `kubechart`:

```
helm create kubechart
```
A new directory with the name of the chart will be created. To view the contents of the chart created use the `tree` command at the root of the project where the chart has been created:

```
tree
```
##### output

```
.
└── kubechart
    ├── charts
    ├── Chart.yaml
    ├── templates
    │   ├── deployment.yaml
    │   ├── _helpers.tpl
    │   ├── hpa.yaml
    │   ├── ingress.yaml
    │   ├── NOTES.txt
    │   ├── serviceaccount.yaml
    │   ├── service.yaml
    │   └── tests
    │       └── test-connection.yaml
    └── values.yaml

4 directories, 10 files
```
Below is a brief overview of the above folder structure:
- `charts`: charts is a directory that contains other charts called subcharts. At the moment it's empty but as your business needs grow subcharts can be placed inside this folder.
- `Chart.yaml`: This is where the metadata information related to your chart will reside. This includes information like API version of the chart, name and description of the project.
- `templates`: This directory contains all resource definitions that your chart will install on the cluster.
- `values.yaml`: This file contains the default values for the chart. These values can be overridden when using `helm install` or `helm upgrade`.

You can now install the created custom chart. The created custom chart you are using contains the default `nginx` image for demonstration purposes but you can follow these exact steps when using your own images. In the `helm install` command pass flags `--dry-run` and `--debug` while pointing to the current chart directory to see what helm would deploy to the cluster.

```
helm install kubechart --dry-run --debug ./kubechart
```
A lengthy output will be displayed and will contain all the resource definitions to be applied to your cluster. You can now go ahead to package the chart for distribution.

```
helm package ./kubechart
```
The generated output will be similar to the following:

```
Successfully packaged chart and saved it to: .../kubechart-0.1.0.tgz
```
You can now go ahead to install the packaged chart. The installation process is similar to how you install charts from the artifacthub repository.

```
helm install kubechart kubechart-0.1.0.tgz
```
The output will contain a set of instructions that you can use to run your chart.
##### output

```
NAME: kubechart
LAST DEPLOYED: Fri Nov 24 16:25:08 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=kubechart,app.kubernetes.io/instance=kubechart" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
```
You have now successfully deployed your custom chart running nginx.

### Conclusion
You now know how to use helm charts to install, upgrade, do rollbacks and uninstall helm releases on your Kubernetes cluster. You have also seen how to use the ArtifactHub chart repository to get helm charts. You have also seen how to create your own custom charts by installing and packaging the charts. 
For further guidance regarding helm charts visit [official helm page](https://helm.sh/docs/chart_template_guide/getting_started/).