Introduction to Helm
Archie ToThis article assumes readers have a basic knowledge about Kubernetes, as Helm and Kubernetes are closely related. Reading Introduction to Kubernetes is highly recommended prior to reading this article.
What is Helm?
Helm is a package manager for Kubernetes. Think of Helm as a way to install and upgrade applications built on Kubernetes. Helm allows you to install applications with multiple Kubernetes components with a single command.
Why Helm?
To explain the benefits that Helm brings about, suppose you are deploying an app onto k8s (an abbreviation for Kubernetes). The app consists of a Deployment to run the containers, a Service for networking, a Configmap for basic configurations, a Secret to store passwords, a Persistent Volume and a Claim to store files and some IngressRoutes for advanced routing.
Without Helm, you might have a resource description file for each of these, such as deployment.yaml
, service.yaml
, etc., each of which define parameters specific to this particular deployment of the application.
With Helm, these are generalized as templates where the parameters are placeholders and can be filled out independently in a definition for the entire application.
We’ll see how this looks later; for now let’s look at what this means for managing our deployment.
Package k8s app components
Without Helm, in order to deploy these resources, you will have to run kubectl apply -f <resource_file_name>.yaml
for each resource.
With Helm, a single command will do the trick. This becomes even less work for applications that require a large number of resources.
Reusability
Suppose you want to deploy a second app with similar resources but with a different name.
Without Helm, you would have to modify each resource yaml file and apply each file individually.
With Helm, a single change in values.yaml
with a single helm install
command will provide the exact same result.
Versioning
You successfully deployed your app. You then upgraded some resources and now the app doesn’t work anymore. You want to revert the app back to its previous version.
Without Helm, you would have to recall the changes you’ve made to each deployment, remove them and reapply the yaml files.
With Helm, a single helm rollback
command would suffice.
Main components of Helm
Suppose we are deploying a very simple web application with 2 main components: A Deployment and a Service resource. A typical Helm chart would contain the following:
Chart.yaml
A file that contains metadata about the chart:
apiVersion: v2
name: my-web-app
description: A Helm chart for deploying a simple web application
version: 1.0.0
appVersion: 1.0.0
values.yaml
This file contains default values for the chart’s configuration. These values will be plugged into the corresponding variable names defined in Helm templates. For our web application, it might include settings like the number of replicas and the image to use:
replicaCount: 2
image:
repository: my-web-app
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
templates
This directory contains all Kubernetes manifest templates needed for our application (This is why we said Helm package k8s app components). Each template can use variable names to plug in the values provided in values.yaml
. Here’s an example of a deployment template (deployment.yaml
):
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
labels:
app: {{ .Chart.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
resources:
limits:
cpu: {{ .Values.resources.limits.cpu }}
memory: {{ .Values.resources.limits.memory }}
requests:
cpu: {{ .Values.resources.requests.cpu }}
memory: {{ .Values.resources.requests.memory }}
And an example of a service template (service.yaml
):
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
selector:
app: {{ .Chart.Name }}
Others
There are other components that are also worth looking into:
helpers.tpl
: A file for defining reusable template snippets and helper functions in Helm.NOTES.txt
: A file for providing post-installation information and instructions.tests
: A directory for defining tests to verify the functionality of the deployed chart.
How to use Helm
Using the my-web-app
example above. Your directory might look like the following:
my-web-app/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── _helpers.tpl
│ ├── NOTES.txt
│ └── tests/
│ └── test-connection.yaml
Let’s look at some of basic Helm commands for this chart:
helm install
To deploy my-web-app
Helm chart to your Kubernetes cluster with a release name set to my-release
:
helm install my-release ./my-web-app
This will create a Deployment and a Service resource for my-web-app
in k8s cluster with the following Kubernetes manifest files:
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-release-my-web-app
labels:
app: my-web-app
spec:
replicas: 2
selector:
matchLabels:
app: my-web-app
template:
metadata:
labels:
app: my-web-app
spec:
containers:
- name: my-web-app
image: "my-web-app:1.0.0"
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-release-my-web-app
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: my-web-app
Notice how the variable names have been replaced with the correspoding values in values.yaml
.
helm upgrade
To upgrade the existing my-release
to a new version of the my-web-app
chart, start by modifying values.yaml
. For example, change the image tag:
image:
repository: my-web-app
tag: "2.0.0"
pullPolicy: IfNotPresent
Then run:
helm upgrade my-release ./my-web-app
The Deployment resource should be updated with the new image tag.
helm roll back
If for some reasons, the new image tag 2.0.0
doesn’t work and you want to change it back to 1.0.0
. You can roll my-release
back to the previous version:
helm rollback my-release 1
The Deployment resource should get back to using 1.0.0
tag for its image.
helm uninstall
To take the app down, you can uninstall my-release
from the Kubernetes cluster:
helm uninstall my-release
All resources associated with app should be deleted.
Conclusion
In this article, we’ve explored the basics of Helm, a powerful package manager for Kubernetes that simplifies the deployment and management of applications. Helm bundles up mutliple Kubernetes resources, implements dynamic resource definitions and provides simple commands for version control. Thanks to Helm, app deployments onto k8s become extremely maintainable, reusable and managable.