Trusting Who's at the Helm

7 Sep 2016

Last year at KubeCon in San Francisco, I first learnt about Helm—a sort of Homebrew for Kubernetes. It seemed too good to be true, so I dug deeper. Fast forward to today, and I find myself packaging applications with Helm.

In this post, I'll talk briefly about why Helm is so exciting, and then show you how to install and use one of the packages I wrote.

Why Use a Package Manager?

A team I worked with was deploying various components to Kubernetes, including: Zookeeper, etcd, Consul, Cassandra, Kafka, and Elasticsearch. Each one of these components was using a manifest file that someone on the team had written by hand, and then these manifest files had been improved over time. Each change, each improvement, reflecting some sort of knowledge or experience the team had gained.

But there are many teams across the world deploying these same components. And let's face it, most deploy situations are similar enough. So each one of these teams is, for the most part, duplicating each other's work.

But what if there was a way to avoid that? What if we could organise that collective knowledge and bring people together to collaborate on it.

Traditionally, you would install a piece of software on Linux with a ./configure && make install invocation. Which can (as you might already know) present its own kind of hell, as you look up cryptic error messages and try to resolve dependencies. And even once you're done, you're usually left to figure out how to configure the application properly. It can take hours or days to get even a basic working setup.

Enter package managers.

Package managers (like yum and APT) are a big reason many of the popular Linux distributions are as successful as they are. They provide a standard, opinionated way to install, configure, upgrade, and run an application in a matter of minutes. And the packages themselves are open source, and anyone can contribute to them.

This is exactly what Helm does for Kubernetes.

Working with Helm

Wanting to move away from our home-grown mess of Kubernetes manifest files, I eventually made the plunge and decided to take a look at Helm.

One of the first things I learnt was that since hearing the Helm talk last year, Helm (originally a Deis project) has been officially adopted by the Kubernetes project. Deis continues to work on the project along with the Kubernetes community, and the original code has been renamed Helm Classic.

This was everything I needed to convince me that Helm was the way forward.

So, with that decided, all that was left was to convert our custom Kubernetes manifests into Helm packages, called charts.

Working with Helm is a delight. And provided you have a Kubernetes cluster, installation is as easy as a download and then helm init. Read more in the official docs.

But that's not where the ease of use stops. After all that mucking around with Kubernetes manifest files, it is very satisfying typing something like helm install etcd and moments later having a production ready etcd cluster up and running.

And just a week after getting started with all of this I had submitted four pull requests against the official charts repository.

But enough gushing...

Getting Our Hands Dirty

Let's take a look at using Helm to install the Apache Spark chart I created. We'll do this using my forked charts repository.

Start by cloning the repository:

$ git clone git@github.com:lachie83/charts.git

Install the Apache Spark chart under a Kubernetes namespace called spark:

$ helm install charts/incubator/spark/ --namespace=spark
busted-rodent

At this point you're done. Helm has installed Spark on your Kubernetes cluster with the release name busted-rodent. This release name was automatically generated for us, but don't worry, you can specify your own release names if you wish.

Spark is now up and running and ready to be used.

You can use Helm to list all current deployments, which includes information about the version, status, and chart name:

$ helm list -l
NAME            VERSION UPDATED                     STATUS      CHART
busted-rodent   1       Fri Aug 19 16:09:00 2016    DEPLOYED    spark-0.1.0

Let's check the busted-rodent release deployment status:

$ helm status busted-rodent
Last Deployed: Fri Aug 19 16:09:00 2016
Status: DEPLOYED
Resources:
==> v1/Service
NAME                       CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
busted-rodent-spark-mast   10.0.115.78   <none>        7077/TCP   12s
busted-rodent-spark-webu   10.0.137.193  <pending>     8080/TCP   12s
busted-rodent-zeppelin-c   10.0.108.115  <pending>     8080/TCP   12s
==> extensions/Deployment
NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
busted-rodent-spark-work   3         3         3            3           12s
busted-rodent-zeppelin-c   1         1         1            1           12s
busted-rodent-spark-mast   1         1         1            1           12s

As you can see, the status command tells us about the Kubernetes provisioned resources that have been deployed as part of the chart.

We can get the same information from Kubernetes if we want:


$ kubectl get deployments,pods,svc --namespace=spark
NAME                                        DESIRED        CURRENT       UP-TO-DATE   AVAILABLE   AGE
busted-rodent-spark-mast                    1              1             1            1           26s
busted-rodent-spark-work                    3              3             3            3           26s
busted-rodent-zeppelin-c                    1              1             1            1           26s
NAME                                        READY          STATUS        RESTARTS     AGE
busted-rodent-spark-mast-2223277764-uu4jw   1/1            Running       0            26s
busted-rodent-spark-work-4055452751-7xxdv   1/1            Running       0            26s
busted-rodent-spark-work-4055452751-lscnh   1/1            Running       0            26s
busted-rodent-spark-work-4055452751-q9iwg   1/1            Running       0            26s
busted-rodent-zeppelin-c-3386843750-h9p6k   1/1            Running       0            26s
NAME                                        CLUSTER-IP     EXTERNAL-IP   PORT(S)      AGE
busted-rodent-spark-mast                    10.0.115.78    <none>        7077/TCP     26s
busted-rodent-spark-webu                    10.0.137.193                 8080/TCP     26s
busted-rodent-zeppelin-c                    10.0.108.115                 8080/TCP     26s

With only the helm install command, I managed to deploy an Apache Spark cluster using configuration provided by the community.

Impressive, I hope you'll agree!

Wrap Up

Using Helm as your Kubernetes-native package manager lets you install and manage battle-tested applications with only a single command.

There are all sorts of places to go from here.

For example, you could hook Helm into your Continuous Integration (CI) or Continuous Deployment (CD) pipeline. All you'd have to do is have your CI/CD system create updated charts, deploy them to a Helm repository, and then call helm upgrade to trigger a rolling application update.

Now you know a little about Helm, I encourage you to get involved.

I want to see the official chart repository grow and grow and keep on growing. And every PR you submit improves Kubernetes for everyone. So let's make Helm the one-stop shop for Kubernetes packages.

If you're interested in contributing, see the contributing guide or drop in to the #helm channel on the Kubernetes Slack.

Posted in Helm, Kubernetes

triangle square circle

Did you enjoy this post?