An intro to Helm and how you can use it for packaging cloud native applications

In the evolving landscape of the cloud native world managing and deploying applications to kubernetes environments has become a critical skill.

Helm is a tool which aids in simplifying the complex process and provides a streamlined process.

Why Helm

  1. Reproducible and Consistency: Helm allows us to package complete applications and configurations into a single unit.

  2. Versioning and Rollback: Helm allows us to version our charts and perform rollbacks when required.

  3. Multi Environment Deployment: The template engine of helm allows us to seamlessly deploy resources in multiple namespaces and environments.

  4. CI/CD integration: Helm integrates easily with CI/CD pipelines which allows organizations to automate deployment processes.

Building a sample Helm Chart

To build a helm chart from scratch firstly install helm in your system.

Once run in your directory run the following command

helm create webserver

A directory called webserver is created

templates: these are the files helm packages and manages , these are the kubernetes manifests that helm will deploy.

Chart.yaml: metadata about the helm chart , contains details about chart name , version , description.

values.yaml: default configuration about the helm chart.

helperts.tpl: reusable Go template functions.

For this exercise we will only work with the deployment.yaml and service.yaml so the rest of the files in templates can be removed.

rm hpa.yaml ingress.yaml serviceaccount.yaml

These are the parts which are picked from values files

"{{ .Values.image.repository }}

We are going to add another container to this deployment so under the values.yaml add a block like this.

In the values.yaml file we add this

webcontainer:
  name: httpd
  repository: httpd
  pullPolicy: Always
  tag: latest

In the deployment.yaml template we add the following block

- name: {{ .Values.webcontainer.name }}
  image: {{ .Values.webcontainer.repository }}:{{ .Values.webcontainer.tag }}
  imagePullPolicy: {{ .Values.webcontainer.pullPolicy }}

So the containers block looks like this

containers:
        - name: {{ .Values.webcontainer.name }}
          image: {{ .Values.webcontainer.repository }}:{{ .Values.webcontainer.tag }}
          imagePullPolicy: {{ .Values.webcontainer.pullPolicy }}
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

To test the helm templates we can run the following commands

helm template web ./webserver

web is the releaseName given to the chart.

The output displayed is this

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dryrun-webserver
  labels:
    helm.sh/chart: webserver-0.1.0
    app.kubernetes.io/name: webserver
    app.kubernetes.io/instance: dryrun
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: webserver
      app.kubernetes.io/instance: dryrun
  template:
    metadata:
      labels:
        app.kubernetes.io/name: webserver
        app.kubernetes.io/instance: dryrun
    spec:
      serviceAccountName: dryrun-webserver
      securityContext:
        {}
      containers:
        - name: httpd
          image: httpd:latest
          imagePullPolicy: Always
        - name: webserver
          securityContext:
            {}
          image: "nginx:1.16.0"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}
helm install --debug --dry-run dryrun ./webserver

This displays the installation process and demonstrates the template values , this will not install the chart but show what is about to be installed.

To package the chart into a tar file run the following command

helm package webserver

Output: Successfully packaged chart and saved it to: webserver-0.1.0.tgz

Installation of Helm Chart

Let us install the chart

helm install web ./webserver

OUTPUT

NAME: web
LAST DEPLOYED: Wed Feb  7 20:02:07 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=webserver,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

Run the following commands to view your deployed pods and deployment

kubectl get deploy
kubectl get pods

To upgrade a chart i:e to make modifications to the chart edit the templates and run the following command

helm upgrade web ./webserver


Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Wed Feb  7 20:05:37 2024
NAMESPACE: default
STATUS: deployed
REVISION: 2

Notice the revision is marked as 2.

To view the revisions by helm run the following command

helm history web (web is release name)

REVISION    UPDATED                     STATUS        CHART              APP VERSION    DESCRIPTION     
1           Wed Feb  7 20:02:07 2024    superseded    webserver-0.1.0    1.16.0         Install complete
2           Wed Feb  7 20:05:37 2024    deployed      webserver-0.1.0    1.16.0         Upgrade complete

To rollback to a particular release run the following command

helm rollback web 1
Rollback was a success! Happy Helming!

View helm history once again

helm history web            
REVISION    UPDATED                     STATUS        CHART              APP VERSION    DESCRIPTION     
1           Wed Feb  7 20:02:07 2024    superseded    webserver-0.1.0    1.16.0         Install complete
2           Wed Feb  7 20:05:37 2024    superseded    webserver-0.1.0    1.16.0         Upgrade complete
3           Wed Feb  7 20:09:22 2024    deployed      webserver-0.1.0    1.16.0         Rollback to 1

This is a basic intro on developing your own custom charts using helm.

A sample Helm Project can be found here -> Click here for a Helm project

Happy Helming.