Getting Started with Kubernetes Helm Charts

Getting Started With Helm Charts

Helm makes Kubernetes more user-friendly. It is a package manager. Helm Charts makes it easier to design, install and upgrade a Kubernetes application. They manage the complexity to make the installation process repeatable. Users are easily able to update and share their designs. Also, Helm has a rollback function to easily go back to order versions.

Helm Chart Structure

With the create command, Helm provides a predetermined structure to ensure a standard.


├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── service.yaml
└── values.yaml

The files above will be auto-generated. Helm uses YAML format for configuration files.

Invoking Helm

In order to use Helm, you’ll need the following things:

  • A Kubernetes Cluster (Minikube provides a simple way of running Kubernetes)
  • Install Helm and Tiller, the server-side component.

(Make sure the Minikube and Tiller versions are compatible with the Kubernetes Cluster)

Once you have all the components installed, start your minikube:

$ minikube start

You will also need to use the following command to initialize Helm and Tiller:

$ helm init

Next, use the following Helm command to create the structure described above:

$ helm create hello-world

Writing Your First Helm Chart

Let’s check the status of the pods:

$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                    READY     STATUS    RESTARTS   AGE
kube-system   kube-addon-manager-minikube             1/1       Running   2          1h
kube-system   kube-dns-54cccfbdf8-xcltd               3/3       Running   6          1h
kube-system   kubernetes-dashboard-77d8b98585-sj9lm   1/1       Running   2          1h
kube-system   storage-provisioner                     1/1       Running   2          1h
kube-system   tiller-deploy-59d854595c-97hdp          1/1       Running   2          1h

The tiller pod and the minikube pods are running. Let’s make some changes to Helm Charts. We are going to open the value.yml. It looks like this:

# Default values for hello-world.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
repository: heroku/nodejs-hello-world
tag: stable
pullPolicy: IfNotPresent
type: ClusterIP
port: 80
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
path: /
- chart-example.local
tls: []
#  - secretName: chart-example-tls
#    hosts:
#      - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
#  cpu: 100m
#  memory: 128Mi
# requests:
#  cpu: 100m
#  memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}

The highlighted line has been changed. Instead of nginx, we are going to download heroku/nodejs-hello-world. You can set the default values in this value.yml file. They will be shared with other files.

If we check Helm, we don’t see anything:

$ helm ls

Let’s start the Helm Chart:

$ helm install hello-world
NAME:   kissing-markhor
LAST DEPLOYED: Fri Mar  9 09:13:04 2018
NAMESPACE: default
==> v1/Service
NAME                         TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)  AGE
kissing-markhor-hello-world  ClusterIP  <none>       80/TCP   1s
==> v1beta2/Deployment
kissing-markhor-hello-world  1        1        1           0          1s
==> v1/Pod(related)
NAME                                          READY  STATUS             RESTARTS  AGE
kissing-markhor-hello-world-6bbb947b9c-rttnz  0/1    ContainerCreating  0         1s
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app=hello-world,release=kissing
-o jsonpath="{.items[0].metadata.name}")
  echo "Visit to use your application"
  kubectl port-forward $POD_NAME 8080:80

The noticeable part is the “NAME”. This name was generated by Helm.

Let’s check Helm:

$ helm ls
NAME             REVISION    UPDATED                     STATUS     CHART              NAMESPACE
kissing-markhor  1           Fri Mar  9 09:13:04 2018    DEPLOYED   hello-world-0.1.0  default

Also Kubernetes:

$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                          READY  STATUS    RESTARTS AGE
default       kissing-markhor-hello-world-6bbb947b9c-rttnz  1/1    Running   0        5m
kube-system   kube-addon-manager-minikube                   1/1    Running   2        2h
kube-system   kube-dns-54cccfbdf8-xcltd                     3/3    Running   6        2h
kube-system   kubernetes-dashboard-77d8b98585-sj9lm         1/1    Running   2        2h
kube-system   storage-provisioner                           1/1    Running   2        2h
kube-system   tiller-deploy-59d854595c-97hdp                1/1    Running   2        2h

So the pod has been deployed to Kubernetes. We can use port forwarding:

$ kubectl port-forward kissing-markhor-hello-world-6bbb947b9c-rttnz 8080:80

Now you should be able to check your deployed application.

$ curl
<!DOCTYPE html>
<title>Welcome to nginx!</title>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>

Alternatively, you can check to see the newly created application. Let’s tidy up. Find the server name:

$ helm ls
NAME             REVISION  UPDATED                    STATUS     CHART               NAMESPACE

kissing-markhor  1         Fri Mar  9 09:13:04 2018   DEPLOYED   hello-world-0.1.0   default

Use the following command to delete:

$ helm delete kissing-markhor
release "kissing-markhor" deleted

Let’s check the cluster:

$ kubectget pod --all-namespaces
NAMESPACE     NAME                                    READY  STATUS    RESTARTS  AGE
kube-system   kube-addon-manager-minikube             1/1    Running   2         2h
kube-system   kube-dns-54cccfbdf8-xcltd               3/3    Running   6         2h
kube-system   kubernetes-dashboard-77d8b98585-sj9lm   1/1    Running   2         2h
kube-system   storage-provisioner                     1/1    Running   2         2h
kube-system   tiller-deploy-59d854595c-97hdp          1/1    Running   2         2h

We can see the kissing-marker pod is gone.


The above should give you the inspiration to start using Helm Charts. It should make your Kubernetes deployments easier to handle.


About the author

Zak H

Zak H

Zak H. lives in Los Angeles. He enjoys the California sunshine and loves working in emerging technologies and writing about Linux and DevOps topics.