Helm on Google Kubernetes Engine

I will come back to the rationale for this post at a later date, but consider this another notebook type of post, serving as part of my external brain. Also, this post assumes that the reader has some passing understanding of kubernetes, container technologies such as Docker, and is interested in building or running distributed systems such as web applications, compute jobs, or data services.

Files for this post are available at github.

Kubernetes, for those who do not know, is:

an open-source system for automating deployment, scaling, and management of containerized applications. It groups containers that make up an application into logical units for easy management and discovery. Kubernetes builds upon 15 years of experience of running production workloads at Google, combined with best-of-breed ideas and practices from the community.

In other words, Kubernetes is a platform for running applications composed of potentially many containers, their interconnections, and network services to the outside world as needed. Kubernetes is open source giving the freedom to take advantage of on-premises, hybrid, or public cloud infrastructure, letting you effortlessly move workloads to where it matters to you. Kubernetes is even supported on a laptops making development easy and reproducible.

Kubernetes-based applications typically comprise one or mre [yaml]-formatted files describing the application itself, storage, network connections, services (such as load balancers), and security. As such, they are easily tracked as text files. The helm project, described as “the missing kubernetes package manager” can render these files more generalizable and facilitate sharing.

The rest of this post will describe how to run helm on Kubernetes. Note that you will need a Google Cloud account and billing project in order to proceed. If you want to use another kubernetes platform, the instructions below may be somewhat different.

Because helm requires a Kubernetes cluster, the first step is to create a Kubernetes cluster. In this case, I am using Google Kubernetes Engine, so follow the instructions to create your first cluster.

Create the helm service account

Helm is going to be responsible for creating and maintaining resources on our kubernetes cluster. In order to “delegate” this authority to helm, we first create a “service account” on the cluster. See this blog post for a deep dive. However, since kubernetes is a standard, the following yaml file should work for any kubernetes with role-based access control enabled.

# This is an extract from here: http://jayunit100.blogspot.fi/2017/07/helm-on.html
apiVersion: v1
kind: ServiceAccount
  name: helm
  namespace: kube-system
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
  name: helm
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
  - kind: ServiceAccount
    name: helm
    namespace: kube-system

Assuming that the kubernetes cluster is running and that the kubectl executable is configured correctly, the following line will install the service account into kubernetes.

$ kubectl apply -f helm-service-account.yaml

You should see the following output that just says the the service account was created successfully.

serviceaccount/helm created
clusterrolebinding.rbac.authorization.k8s.io/helm created

Before proceeding, be sure that helm is installed on your local machine. The next line will configure helm to be used with kubernetes. In addition, it will install the tiller service on the kubernetes cluster that will function to ensure that helm-created services are enabled and running.

$ helm init --service-account helm

If successful, there should be a new service, the tiller service, running on kubernetes. The kubectl command line can get information about the resources on the cluster. In this case, we are looking specifically to see if tiller is running.

$ kubectl get deploy,svc tiller-deploy -n kube-system

You should receive something like below. Note that the IP address, etc., will differ for your installation.

NAME                                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/tiller-deploy   1         1         1            1           15d

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
service/tiller-deploy   ClusterIP   <none>        44134/TCP   15d

Helm has the capability of creating an example “Chart”. The helm chart includes all the files necessary to create an entire application and associated services on the kubernetes cluster. The following will create a simple helm chart that deploys an nginx webserver and connects up a load balancer. See the github repo for the files created by this command.

$ helm create samplechart

After running the command above, there will be a new directory, samplechart created. To “install” the samplechart, use the following line:

$ helm install --name helm-text ./samplechart --set service.type=LoadBalancer

The output of the command will be something like:

NAME:   helm-text
LAST DEPLOYED: Sun Mar 24 14:19:25 2019
NAMESPACE: default

==> v1/Deployment
helm-text-samplechart  0/1    1           0          0s

==> v1/Pod(related)
NAME                                    READY  STATUS             RESTARTS  AGE
helm-text-samplechart-6697574fd9-hp2fm  0/1    ContainerCreating  0         0s

==> v1/Service
NAME                   TYPE          CLUSTER-IP    EXTERNAL-IP  PORT(S)       AGE
helm-text-samplechart  LoadBalancer  <pending>    80:30084/TCP  0s

1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get --namespace default svc -w helm-text-samplechart'
  export SERVICE_IP=$(kubectl get svc --namespace default helm-text-samplechart -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  echo http://$SERVICE_IP:80

In the NOTES section of the output, kubernetes lets us know where to look for the IP address of the new nginx service. If I query for the service to discover the IP address (after a few minutes for the external IP address to be created):

$ kubectl get --namespace default svc -w helm-text-samplechart

We can see that the IP address is ready if the EXTERNAL-IP field is filled in below. If it is not, wait a few minutes and try again.

NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
helm-text-samplechart   LoadBalancer   80:30084/TCP   1m

Navigating to http://EXTERNAL-IP should result in a screen that looks like:

A successful nginx deployment

A successful nginx deployment

See what is running under helm:

$ helm ls
NAME        REVISION    UPDATED                     STATUS      CHART               APP VERSION NAMESPACE
helm-text   1           Sun Mar 24 14:19:25 2019    DEPLOYED    samplechart-0.1.0   1.0         default

And delete a helm chart based on the name in helm ls.

$ helm delete helm-text

As I mentioned, this post is mainly for me to refresh my memory on using helm in kubernetes. Both kubernetes and helm are incredibly enabling technologies, so consider taking an afternoon to play with them if you are developing applications or want to run “jobs” on a vendor-agnostic, scalable hosting platform.

Sean Davis
National Cancer Institute, NIH


comments powered by Disqus