Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Deploy to Kubernetes With Helm

DZone's Guide to

Deploy to Kubernetes With Helm

Get started using Helm with this helpful guide that shows you how to install Helm, pull a Chart from the repository, and some frequently-used commands.

· Cloud Zone ·
Free Resource

Discover a centralized approach to monitor your virtual infrastructure, on-premise IT environment, and cloud infrastructure – all on a single platform.

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:

  • 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).
  • 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. The first step is to retrieve the admin password in order to be able to log in. 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.

helm-grafana-install


Login with username admin and the password we retrieved earlier. After pressing the Log In button, we have access to Grafana and our installation is complete.

helm-grafana-logged-in


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!
...


Again, a complete output as with the install  command is given, I represented it with the three dots.

We can check the outcome of our upgrade command with the  sudo kubectl  get pods command. The output is the following:

NAME                         READY     STATUS    RESTARTS   AGE
mygrafana-64bb749755-j7v4j   1/1       Running   2          3m
mygrafana-64bb749755-pfs7m   1/1       Running   2          24m


Execute the  sudo helm list  command:

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.

Learn how to auto-discover your containers and monitor their performance, capture Docker host and container metrics to allocate host resources, and provision containers.

Topics:
helm ,minikube ,tutorial ,kubernetes ,helm chart ,installation ,cloud

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}