Helm Explained: A Step-by-Step Guide to Creating Your Own Helm Chart with Hands-On Example (Part 2)
Hello Everyone! π
This is Part 2 of the Helm Explained Blog. It is about how you can create your own Helm Chart for your applications. If you want to understand what Helm is and how to install and manage applications using Helm, etc., please refer to Part 1.
Prerequisites
Command line access
Kubectl command line tool installed
A Kubernetes cluster running and configured in your system via KubeConfig file (default path is
~/.kube/config
)Helm command line tool installed
Advantages of Creating Helm Chart for your applications
Helm Charts are basically a collection of related Kubernetes resources. We can either apply and manage each resource's YAML individually or use Helm to simplify this process. In the end, we get a Helm Chart that we can apply easily with one command without the risk of forgetting some resources.
Helm makes it easy through a templated approach. All Helm charts follow the same structure while still having a structure flexible enough to represent any type of application you want to run on Kubernetes. You also get versioning support since deployments are always in the process of getting their next patch. Manually applying configurations will inevitably lead to errors, and thatβs when Helm charts become important when a large number of configurations are required to run a single application.
Steps to Create Helm Chart
In this Guide, I am using local KinD cluster with Helm version 3.17.0
You need to containerize your application first using Docker or similar tools since Kubernetes uses images for deployments. I am using the standard NGINX image for demonstration.
Steps β
Helm Create Command
Helm charts are configured using directory structure and we generate the chart directory using the helm CLI. The command is :
helm create [chart_name]
I am naming my chart as nginx-chart-demo
and we get a directory of name nginx-chart-demo which contains everything.
Directory structure -
nginx-chart-demo/
βββ Chart.yaml
βββ values.yaml
βββ charts/
βββ templates/
βββ _helpers.tpl
βββ deployment.yaml
βββ hpa.yaml
βββ ingress.yaml
βββ NOTES.txt
βββ serviceaccount.yaml
βββ service.yaml
βββ tests/
The Helm chart directory contains the following items:
charts - The directory that stores dependent charts
templates - The directory for configuration files
Chart.yaml - The file containing chart metadata
values.yaml - The file with default chart parameter values
What is Chart.yaml about ?
We put the details of our chart in Chart.yaml file. You can replace the default contents and remove comments for better readability.
What are templates and values.yaml for ?
There are multiple files in the templates directory. These files are applied to the cluster when you perform a helm install, so remove or create files as needed.
Suppose you have a basic NGINX deployment for Kubernetes and you want this configuration using helm, hereβs how you can do it:
You can create one directly using helm, I will show you using the original deployment.yaml file to make it easy to understand.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-chart-demo
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Convert this to the templated templates/deployment.yaml file. You already have a template in that file, just remove what you don't need and add whatever you need. The final file would look something like this β
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
app: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.containerPort }}
Now, what are these curly bracket objects? They are part of the template feature I mentioned above. The format is {{ .Object.Parameter }}
, and the values.yaml
file populates it. This way, you don't have to change deployment YAMLs every time or worry about indentation. Isn't it amazing?
Feed the values in the values.yaml
file like this β
replicaCount: 2
image:
repository: nginx
tag: latest
containerPort: 80
Now if you see the values.yaml file and the deployment file closely, you will understand how the templating feature works. you can populate any template files by putting values here. mostly used parameters are already there by default in values.yaml
therefore you can simply put values there. Hereβs a templated service.yaml file for example β
apiVersion: v1
kind: Service
metadata:
name: {{ include "nginx-chart-demo.fullname" . }}
labels:
app: {{ include "nginx-chart-demo.name" . }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
selector:
app: {{ include "nginx-chart-demo.name" . }}
and populate values.yaml like this β
service:
type: ClusterIP
port: 80
Validate the Helm Chart
Run helm lint /path/nginx-chart-demo
Render the Helm Chart
Run helm template [release-name] [chart-path]
to get to know how rendered files look like before actually applying it in kubernetes. very helpful in avoiding errors. you can save the output in a file through linux using helm template nginx-chart-demo . > rendered.yaml
After you validate the rendered files, you actually install it in k8s
Install the Helm Chart
Run helm install [release-name] [chart-path]
to install the file. Once you have completed this, you can enjoy rest of the helm features. check my Part 1 of Helm Explained blog to learn more.
That's it from my side. Please leave comments if you have any doubts, and I will answer them. Subscribe to my newsletter for more !
Connect with me on LinkedIn | GitHub.
Thanks for reading :)