Blog
March 14, 2017 Marie H.

Getting Started with Helm

Getting Started with Helm

Managing Kubernetes manifests for anything beyond a toy project gets messy fast. Helm is the package manager for Kubernetes — it lets you template your YAML, version it, and deploy it with a single command. There's a learning curve but it's worth it.

Fair warning: this is Helm 2, which means Tiller. Tiller is a server-side component that runs inside your cluster and handles releases on Helm's behalf. It has some security implications (cluster-admin by default) but for internal/dev clusters it's fine and it's what everyone's using right now.

Installing Helm and Tiller

Download the Helm client from the releases page and put it in your PATH:

$ helm version
Client: &version.Version{SemVer:"v2.5.1", ...}
Error: cannot connect to Tiller

Right, we need Tiller. Install it into the cluster:

$ helm init
$HELM_HOME has been configured at /Users/marie/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Happy Helming!

If you're on a cluster with RBAC enabled (Kubernetes 1.6+), you'll need to create a service account for Tiller first:

$ kubectl create serviceaccount tiller --namespace kube-system
$ kubectl create clusterrolebinding tiller-cluster-rule \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:tiller
$ helm init --service-account tiller

Verify both sides are talking:

$ helm version
Client: &version.Version{SemVer:"v2.5.1", GitCommit:"...", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.5.1", GitCommit:"...", GitTreeState:"clean"}

Versions should match. If they don't, run helm init --upgrade.

Adding a chart repository

The stable repo is included by default but run an update to get the latest chart list:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. Happy Helming!

Installing a chart

Let's install nginx-ingress as a real example. First, look at what the chart exposes:

$ helm inspect stable/nginx-ingress | head -40

Or just look at the default values:

$ helm inspect values stable/nginx-ingress

There are a lot of values. For a basic install on a cloud provider:

$ helm install stable/nginx-ingress \
  --name nginx-ingress \
  --namespace kube-system \
  --set controller.replicaCount=2 \
  --set controller.service.type=LoadBalancer

Output:

NAME:   nginx-ingress
LAST DEPLOYED: Tue Mar 14 10:23:41 2017
NAMESPACE: kube-system
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME                            CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
nginx-ingress-controller        10.100.200.50   <pending>     80:32080/TCP,443:32443/TCP   1s
nginx-ingress-default-backend   10.100.200.51   <none>        80/TCP                       1s

==> v1beta1/Deployment
NAME                            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-ingress-controller        2         2         2            0           1s
nginx-ingress-default-backend   1         1         1            0           1s

Using a values file

--set works for a few overrides but gets unwieldy fast. Use a values file instead:

# nginx-ingress-values.yaml
controller:
  replicaCount: 2
  service:
    type: LoadBalancer
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-internal: "0.0.0.0/0"
  resources:
    requests:
      cpu: 100m
      memory: 64Mi
    limits:
      cpu: 200m
      memory: 128Mi
$ helm install stable/nginx-ingress \
  --name nginx-ingress \
  --namespace kube-system \
  -f nginx-ingress-values.yaml

Commit that values file to your repo. Now your Helm deployment is reproducible.

Upgrading a release

Changed your values? Upgrade the release in place:

$ helm upgrade nginx-ingress stable/nginx-ingress -f nginx-ingress-values.yaml

Helm tracks revisions, so if something goes wrong:

$ helm rollback nginx-ingress 1
Rollback was a success! Happy Helming!

1 is the revision number. Check history with:

$ helm history nginx-ingress
REVISION  STATUS      CHART                DESCRIPTION
1         SUPERSEDED  nginx-ingress-0.8.9  Install complete
2         DEPLOYED    nginx-ingress-0.8.9  Upgrade complete

Listing and deleting releases

$ helm list
NAME           REVISION  STATUS    CHART                 NAMESPACE
nginx-ingress  2         DEPLOYED  nginx-ingress-0.8.9   kube-system

Delete a release (keeps history):

$ helm delete nginx-ingress
release "nginx-ingress" deleted

Delete and purge (removes history, frees the name):

$ helm delete nginx-ingress --purge

Once you start using Helm you won't want to go back to managing raw manifests for anything with more than a handful of resources. The templating alone is worth it — parameterizing image tags for your CI/CD pipeline is trivial once everything's a chart.