In this post we will take a closer look at Helm: a package manager for Kubernetes. We will take a look at the terminology used, install the Helm Client and Server, deploy an existing packaged application and take a look at some useful Helm commands.
Introduction
We can deploy our Docker image manually in Kubernetes and configure Kubernetes to manage our Docker image. So, why do we need a package manager for our application to deploy it to Kubernetes? A package manager will package your Docker image together with the Kubernetes configuration and let you deploy this all together. The advantage is that you are able to put your Kubernetes configuration under version control for your different environments (e.g. development, staging, production) and create a new package when something changes to it. There are several tools available which make it easier to deploy your application to Kubernetes and Helm is one of those. Helm is also maintained by the CNCF (Cloud Native Computing Foundation).
Most of the information in this post is executed with the help from the official Helm documentation.
Prequisites
We will need the following applications in this post:
- a Kubernetes cluster, we will use Minikube for it;
- Kubectl, the CLI tool for interacting with your Kubernetes cluster;
- and of course Helm which consists of two parts:
- Helm, which is the Helm Client application;
- Tiller, which is the Helm Server application which we will install by means of the Helm client into our Kubernetes cluster.
We will ignore any security at this point since we will use a local Minikube Kubernetes cluster. For production use, however, you should definitely incorporate security.
Installation
Minikube and kubectl
For installation of Minikube and kubectl, I refer to a previous post where the installation is explained.
Helm Client and Tiller
First of all, we need to install the Helm Client. Therefore, we go to the Helm releases page. I downloaded the shell script they made available, this made it quite easy to download and install the Helm Client (be sure to give it execution rights with ‘chmod +x’). After running the script, the Helm Client is successfully installed. At the time of writing, version 2.10.0 was installed.
For installing Tiller (the Helm server), we have two choices. The first option can be used for development purposes: you can decide to install Tiller locally and therefore you will have to tell Tiller which Kubernetes cluster to point to. The other option, the one I chose to use, is to install Tiller inside your Kubernetes cluster. During installation, the context (the Kubernetes cluster to use) will be taken from your kubectl config. Execute the following command in order to install Tiller:
sudo helm init
At this moment, we have installed Helm in an insecure manner, but as already said, it doesn’t matter for now, because we are working locally and it is not for production use.
Our Helm configuration is the following (where <user> is your Linux user):
stable repo: https://kubernetes-charts.storage.googleapis.com local repo: http://127.0.0.1:8879/charts HELM_HOME: /home/<user>/.helm
That’s it for the installation, which went very smoothly.
Some Helm concepts
Before we proceed, we need to get acquainted with some of the terminology being used in Helm:
- A Chart is a Helm package. It contains all of the files needed to run your application inside of a Kubernetes cluster. Think of it like your software sources in a Git repository. The official Helm charts can be found on GitHub.
- A (Chart) Repository is a location where the packaged and versioned charts are released. These packages can be deployed to your Kubernetes cluster. Think of it like your binary repository where you keep the different versions of your software (like a Nexus or Artifactory Repository). The Repository for the official Helm charts can be found here (you will need a Google account in order to access it).
- A Release is an instance of a chart running in a Kubernetes cluster. Every time you install a chart, it becomes a new release.
To summarize, Helm installs a Chart from a Repository as a Release in a Kubernetes cluster.
Install a Helm chart
In this section we will try to install an existing chart from the official Helm repository. First, we need to search for a chart to install. We can do so by browsing to the list of stable charts or we can do so by means of the command line:
helm search
The Helm search command will return you the list of stable charts in the official Helm repository. You can also search for a particular chart by adding a search term to it. In our example, we are going to install the Grafana Helm chart. We are not going to do anything with Grafana itself, but it can be installed easily and has an admin page which we can use to test if everything is working fine. So, we will search for Grafana:
helm search grafana
This will return us the following result:
NAME CHART VERSION APP VERSION DESCRIPTION stable/grafana 1.14.5 5.2.3 The leading tool for querying and visualizing time series...
The next thing to do, is to take a closer look at the information of the chart. We can do so by means of the inspect command:
helm inspect stable/grafana
Now a lot of information is returned. This information is also available on GitHub. What you can see here is for example all the parameters that can be set in order to configure the installation to your needs. Also, the default values of these parameters can be viewed. When you take a look at the parameter service.type then we notice that the default value is ClusterIP. In our case, when using Minikube, I want to set this to NodePort in order to make Grafana accessible outside the Kubernetes cluster.
With this in mind, we can now install the Grafana Helm chart into our Kubernetes cluster:
sudo helm install stable/grafana --name mygrafana --set service.type=NodePort
After the install command, we add the chart we want to install, stable/grafana in this case, we give our release a name mygrafana and we set the parameter service.type to NodePort. Another way to set parameters is by adding a values.yaml file to the install command which contains the parameter values.
When running this command, I quickly ran to the following error:
an error occurred forwarding 35793 -> 44134: error forwarding port 44134 to pod <guid>, uid : unable to do port forwarding: socat not found. Error: transport is closing
Apparently, the socat tool is required for installing a Helm chart. Install it with the following command:
sudo apt-get install socat
Now, rerun our install command and now the installation is successful:
NAME: mygrafana LAST DEPLOYED: Thu Sep 6 20:22:08 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mygrafana NodePort 10.102.227.169 <none> 32000:31039/TCP 4s ==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mygrafana 1 1 1 0 4s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE mygrafana-7c6df9bb8d-hg98x 0/1 ContainerCreating 0 3s ==> v1beta1/PodSecurityPolicy NAME DATA CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES mygrafana false RunAsAny RunAsAny RunAsAny RunAsAny false configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim ==> v1/Secret NAME TYPE DATA AGE mygrafana Opaque 3 6s ==> v1/ConfigMap NAME DATA AGE mygrafana 1 6s ==> v1beta1/Role NAME AGE mygrafana 5s ==> v1beta1/RoleBinding NAME AGE mygrafana 4s ==> v1/ServiceAccount NAME SECRETS AGE mygrafana 1 6s ==> v1/ClusterRole NAME AGE mygrafana-clusterrole 5s ==> v1/ClusterRoleBinding NAME AGE mygrafana-clusterrolebinding 5s NOTES: 1. Get your 'admin' user password by running: kubectl get secret --namespace default mygrafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo 2. The Grafana server can be accessed via port 32000 on the following DNS name from within your cluster: mygrafana.default.svc.cluster.local Get the Grafana URL to visit by running these commands in the same shell: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services mygrafana) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT 3. Login with the password from step 1 and the username: admin ################################################################################# ###### WARNING: Persistence is disabled!!! You will lose your data when ##### ###### the Grafana pod is terminated. ##### #################################################################################
At least, it seems that it is successful. When you take a closer look at the v1/Pod(related) section, you will notice that our Pod is not finished deploying yet. Depending on the chart, it can take a while before the Pod is up-and-running. You can check the status with the status command:
sudo helm status mygrafana
This will return the complete output again which was returned after issuing the install command. If you just want to check the status of the Pod, you can also retrieve the Pods with kubectl and inspect the status of the deployment:
sudo kubectl get pods
Wait until the Pod is ready and then we continue with the Note which was outputted after the installation. First step is to retrieve the admin password in order to be able to login. Do so with the following command:
sudo kubectl get secret --namespace default mygrafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
In the next step, we want to retrieve the IP address and the port where we can access the admin login page of Grafana. Do so by executing the following commands:
export NODE_PORT=$(sudo kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services mygrafana) export NODE_IP=$(sudo kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT
Now copy the URL to your browser and the login page of Grafana is shown.
Login with user name admin and the password we retrieved earlier. After pressing the Log In button, we have access to Grafana and our installation is complete.
View, upgrade and delete a Helm chart
In this section we will explore some other useful Helm commands.
List command
With the list command, it is possible to retrieve a list of installed releases. When you add the option --all, all releases are shown (deployed and deleted releases).
sudo helm list
The output in our case, is the following:
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE mygrafana 1 Thu Sep 6 20:34:50 2018 DEPLOYED grafana-1.14.5 5.2.3 default
Upgrade command
With the upgrade command it is possible to upgrade the release to a new Chart version or to update parameters. In our case, we will update a parameter in order to use 2 replicas instead of 1. In order to preserve previous parameters which have been set, we also provide the --reuse-values option. The upgrade command also needs the release name (mygrafana) and the chart (stable/grafana).
sudo helm upgrade mygrafana stable/grafana --reuse-values --set replicas=2
The following output is given after successful upgrade:
Release "mygrafana" has been upgraded. Happy Helming! ...
NAME READY STATUS RESTARTS AGE mygrafana-64bb749755-j7v4j 1/1 Running 2 3m mygrafana-64bb749755-pfs7m 1/1 Running 2 24m
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE mygrafana 2 Sat Sep 8 16:28:29 2018 DEPLOYED grafana-1.14.5 5.2.3 default
We now notice that the revision has been altered to 2.
Delete command
With the delete command, it is possible to remove a release. The release will be present in the history, you can check this with the list command and the option --all.
sudo helm delete mygrafana
The output of the delete command is:
release "mygrafana" deleted
When you want to completely remove the release, use the --purge option with the delete command. Check that it has been completely removed with the list command with option --all. Now it is also removed from the history.
sudo helm delete --purge mygrafana
Summary
In this post we got acquainted with Helm. We took a look at some of the terminology, installed the Helm Client and Server, installed a Chart from the official Repository and took a look at some useful Helm commands. The official Helm documentation is well documented and is of good assistance if you want to explore more Helm features.