Contents

Helm: The Kubernetes Package Manager You Need to Know About

If you’re a software engineer working with Kubernetes, chances are you’ve heard of Helm. But if you’re not already using it, you might be missing out on one of the most powerful tools for managing your Kubernetes deployments.

So, what exactly is Helm, and why should you care?
In short, Helm is a package manager for Kubernetes, designed to make it easier to manage and deploy complex applications on a Kubernetes cluster. Let’s take a closer look at what Helm can do.

Simplify Your Kubernetes Deployments with Helm

Kubernetes is a powerful tool for managing containerized applications, but it can also be complex and time-consuming to set up and manage. That’s where Helm comes in. With Helm, you can package your Kubernetes applications into a single, reusable “chart” that can be easily deployed to any Kubernetes cluster.

For example, if you have a complex application that requires multiple Kubernetes resources, such as deployments, services, and ingress controllers, you can define these resources in a single Helm chart. This chart can then be easily installed or upgraded on any Kubernetes cluster using a single command, simplifying the deployment process and reducing the risk of errors.

Helm makes it easy to install, upgrade, and roll back applications on Kubernetes, using a simple command-line interface that can be integrated into your existing deployment workflows. This can help simplify the development and deployment process, and reduce the risk of errors and inconsistencies across different environments.

What is Helm, and Why Should You Care?

At its core, Helm is a tool for managing Kubernetes resources, including deployments, services, and ingress controllers. But it’s much more than that. Helm is designed to make it easier to manage complex, multi-tier applications on Kubernetes, by providing a simple, modular way to package and deploy these applications.

For example, if you have a multi-tier application that requires a database, a web server, and a load balancer, you can define each of these components in a separate Helm chart. You can then use Helm to install or upgrade these charts together as a single unit, simplifying the deployment process and reducing the risk of errors.

Helm uses a templating system to generate Kubernetes manifests based on user-defined configuration values. This means you can customize your application’s deployment parameters, such as the number of replicas or the container image version, without having to manually edit YAML files or run complex scripts.

Helm Charts: Packaging Your Kubernetes Applications with Ease

The real power of Helm lies in its charts. A Helm chart is a collection of files that describe a Kubernetes application, including its deployment configuration, service definition, and any other resources it requires. Helm charts can be easily shared and reused across different projects, making it easy to deploy complex applications with minimal effort.

For example, if you have a microservices-based architecture with multiple applications, each with its own Kubernetes resources, you can define each application in a separate Helm chart. These charts can then be easily shared and reused across different projects, reducing the need for repetitive deployment work.

Charts are typically versioned, which means you can track changes to your application over time and roll back to previous versions if necessary. Helm also supports dependencies between charts, allowing you to define complex application topologies that can be easily deployed and managed.

Example of a Simple Helm Chart for Deploying a Web Server

First, let’s create a new directory for our chart:

mkdir my-web-server-chart
cd my-web-server-chart

Next, we’ll create a Chart.yaml file to define some basic metadata for our chart:

apiVersion: v2
name: my-web-server
version: 0.1.0
description: A Helm chart for deploying a web server.

Now, let’s create a values.yaml file to define some configuration values for our chart:

replicaCount: 1
image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
ingress:
  enabled: false

This configuration specifies that we want to deploy a single replica of the nginx web server image, with a ClusterIP service listening on port 80.

Next, we’ll create a templates directory for our Kubernetes manifests:

mkdir templates

In this directory, we’ll create a _helpers.tpl file with predefined templates:

{{/*
Expand the name of the chart.
*/}}
{{- define "my-web-server.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "my-web-server.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "my-web-server.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "my-web-server.labels" -}}
helm.sh/chart: {{ include "my-web-server.chart" . }}
{{ include "my-web-server.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "my-web-server.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-web-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "my-web-server.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "my-web-server.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

Also, we’ll create a deployment.yaml file to define our deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-web-server.fullname" . }}
  labels:
    app: {{ include "my-web-server.name" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "my-web-server.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "my-web-server.name" . }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80

This manifest defines a Deployment with the number of replicas specified in our values.yaml file, using the nginx image and exposing port 80.

Finally, we’ll create a service.yaml file to define our service:

apiVersion: v1
kind: Service
metadata:
  name: {{ include "my-web-server.fullname" . }}
  labels:
    app: {{ include "my-web-server.name" . }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
  selector:
    app: {{ include "my-web-server.name" . }}

This manifest defines a Service with the type and port specified in our values.yaml file.

To render the template for your Helm chart without actually deploying it, you can use the helm template command:

helm template my-web-server .

In this command, my-web-server is the name of the release, and . specifies the current directory as the location of the chart files.

When you run this command, you should see the rendered YAML output for the templates in your chart, including the Deployment and Service manifests we defined earlier. You can use this output to verify that your templates are rendering correctly and to inspect the generated Kubernetes manifests before deploying them.

Now that we’ve defined our chart, we can build and deploy it using the following commands:

# Package the chart
helm package .

# Install the chart
helm install my-web-server my-web-server-0.1.0.tgz

This will create a new release of our chart called my-web-server, using the version specified in our Chart.yaml file. We can then upgrade or roll back this release using the helm upgrade and helm rollback commands.

Conclusion

In conclusion, Helm is a powerful tool for managing Kubernetes applications, and one that every software engineer working with Kubernetes should be familiar with. By using Helm charts to package and deploy your applications, you can simplify the deployment process and reduce the risk of errors.