5.2. Helm

Helm is a Cloud Native Foundation project to define, install and manage applications in Kubernetes.

tl;dr

Helm is a Package Manager for Kubernetes

  • package multiple K8s resources into a single logical deployment unit
  • … but it’s not just a Package Manager

Helm is a Deployment Management for Kubernetes

  • do a repeatable deployment
  • manage dependencies: reuse and share
  • manage multiple configurations
  • update, rollback and test application deployments

In this lab we are going to create our very first Helm chart and deploy it.

Task 5.2.1: Create Chart

First, let’s create our chart. Open your favorite terminal and make sure you’re in the workspace for this lab. If you are still on the VM you can switch back to our webshell:

cd /home/projects/
mkdir myhelm
cd myhelm
helm create mychart

You will now find a mychart directory with the newly created chart. It already is a valid and fully functional chart which deploys an nginx instance. Have a look at the generated files and their content. For an explanation of the files, visit the Helm Developer Documentation . In a later section you’ll find all the information about Helm templates.

Task 5.2.2: Install Release

Before actually deploying our generated chart, we can check the (to be) generated Kubernetes resources with the following command:

helm install --dry-run --debug --namespace <namespace> myfirstrelease ./mychart

Finally, the following command creates a new release and deploys the application:

helm install --namespace <namespace> myfirstrelease ./mychart

With kubectl get pods --namespace <namespace> you should see a new Pod:

NAME                                     READY   STATUS    RESTARTS   AGE
myfirstrelease-mychart-6d4956b75-ng8x4   1/1     Running   0          2m21s

You can list the newly created Helm release with the following command:

helm ls --namespace <namespace>

Task 5.2.3: Expose Application

Our freshly deployed nginx is not yet accessible from outside the Kubernetes cluster. To expose it, we have to make sure a so called ingress resource will be deployed as well.

Also make sure the application is accessible via TLS.

A look into the file templates/ingress.yaml reveals that the rendering of the ingress and its values is configurable through values(values.yaml):

{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
  {{- with .Values.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- with .Values.ingress.className }}
  ingressClassName: {{ . }}
  {{- end }}
  {{- if .Values.ingress.tls }}
  tls:
    {{- range .Values.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- with .pathType }}
            pathType: {{ . }}
            {{- end }}
            backend:
              service:
                name: {{ include "mychart.fullname" $ }}
                port:
                  number: {{ $.Values.service.port }}
          {{- end }}
    {{- end }}
{{- end }}

Thus, we need to change this value inside our mychart/values.yaml file. This is also where we enable the TLS part:

[...]
ingress:
  enabled: true
  hosts:
    - host: mychart-<namespace>.<appdomain>
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: chart-example-tls
      hosts:
        - mychart-<namespace>.<appdomain>
[...]

Before we apply this config, we need to workaround an issue with our installation and this helm chart. We always use a default secret for all urls in this cluster but the helm chart expects a specific on. So delete the line mentioning the secretName in the ingress template of the helm Chart.

Apply the change by upgrading our release:

helm upgrade --namespace <namespace> myfirstrelease ./mychart

This will result in something similar to:

Release "myfirstrelease" has been upgraded. Happy Helming!
NAME: myfirstrelease
LAST DEPLOYED: Wed Dec  2 14:44:42 2020
NAMESPACE: <namespace>
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
  https://<namespace>.<appdomain>/

Check whether the ingress was successfully deployed by accessing the URL https://mychart-<namespace>.<appdomain>/

Task 5.2.4: Overwrite value using commandline param

An alternative way to set or overwrite values for charts we want to deploy is the --set name=value parameter. This parameter can be used when installing a chart as well as upgrading.

Update the replica count of your nginx Deployment to 2 using --set name=value

Solution

helm upgrade --namespace <namespace> --set replicaCount=2 myfirstrelease ./mychart

Values that have been set using --set can be reset by helm upgrade with --reset-values.

Task 5.2.5: Values

Have a look at the values.yaml file in your chart and study all the possible configuration params introduced in a freshly created chart.

Task 5.2.6: Remove release

To remove an application, simply remove the Helm release with the following command:

helm uninstall myfirstrelease --namespace <namespace>

Do this with our deployed release. With kubectl get pods --namespace <namespace> you should no longer see your application Pod.