Helm is the package manager for Kubernetes, like apt, yum, or Homebrew for traditional operating systems. It simplifies the deployment and management of applications on Kubernetes clusters by packaging all necessary components into a single, manageable unit.
Helm Client:
Helm Library:
Creating a Helm chart involves setting up a predefined directory structure with at least two files: Chart.yaml
for metadata about the chart and values.yaml
for default configuration values.
Structure: A basic chart directory will have the following layout:
Chart.yaml
: Contains metadata about the chart such as name, version, and description.
values.yaml
: Specifies default configuration values for the chart.
templates/
: This directory contains template files that generate Kubernetes manifest files based on the values provided.
Templating: Helm uses a templating engine to substitute values in the chart templates, creating Kubernetes manifests tailored to specific deployments. This allows for dynamic adjustment of resources, labels, and configurations without altering the original chart files.
Scenario:
A startup, "DevOps Solutions" adopts Helm to streamline their Kubernetes deployments. You're a consultant tasked with creating a basic Helm Chart for n8n. It should be customizable for different environments using values.
git clone https://github.com/perplexedyawdie/helm-learn.git
creating-charts
cd helm-learn/creating-charts
docker compose up -d --build
ubuntu
container.ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2222
# password: test123
helm create my-n8n
tree .
# Output should look similar to this
#`-- my-n8n
# |-- Chart.yaml
# |-- charts
# |-- templates
# | |-- NOTES.txt
# | |-- _helpers.tpl
# | |-- deployment.yaml
# | |-- hpa.yaml
# | |-- ingress.yaml
# | |-- service.yaml
# | |-- serviceaccount.yaml
# | `-- tests
# | `-- test-connection.yaml
# `-- values.yaml
Chart.yaml
, values.yaml
, my-n8n/templates/NOTES.txt
and my-n8n/templates/_helpers.tpl
so we can remove the rest since we'll be adding our own manifest files.rm -rf my-n8n/templates/*.yaml my-n8n/templates/tests
nano my-n8n/Chart.yaml
# appVersion: "1.27.2"
nano my-n8n/templates/NOTES.txt
# Welcome to n8n.
# Wait a few minutes until the status changes to RUNNING.
# After it is ready, access it from: http://localhost:2223
values.yaml
file with the following data.# Default values for my-n8n.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: n8nio/n8n
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.27.2"
containerPorts:
- name: http
port: 5678
service:
type: NodePort
port: 30200
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# Additional volumes on the output Deployment definition.
volumes:
- name: n8n-data
persistence:
claimName: n8n-data
# Additional volumeMounts on the output Deployment definition.
volumeMounts:
- name: n8n-data
mountPath: "/home/node/.n8n"
deployment.yaml
, service.yaml
and, pvc.yaml
files inside the my-n8n/templates
folder.# my-n8n/templates/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: n8n-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi # Adjust the size as per your requirement
# my-n8n/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: n8n
spec:
replicas: 1
selector:
matchLabels:
app: n8n
template:
metadata:
labels:
app: n8n
spec:
containers:
- name: n8n
image: n8nio/n8n
ports:
- name: http
- containerPort: 5678
volumeMounts:
- name: n8n-data
mountPath: /home/node/.n8n
volumes:
- name: n8n-data
persistentVolumeClaim:
claimName: n8n-data
# my-n8n/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: n8n
spec:
type: NodePort
ports:
- port: 5678
targetPort: 30200
protocol: TCP
selector:
app: n8n
values.yaml
file to generate the manifest that will be deployed on K8S.# my-n8n/templates/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Values.persistence.claimName }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi # Adjust the size as per your requirement
# my-n8n/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ printf "%s-%s" .Release.Name .Chart.Name }}
spec:
replicas: 1
selector:
matchLabels:
app: n8n
template:
metadata:
labels:
app: n8n
spec:
containers:
- name: n8n
image: {{ printf "%s:%s" .Values.image.repository .Values.image.tag }}
ports:
{{- range .Values.containerPorts }}
- name: {{ .name }}
containerPort: {{ .port }}
{{- end }}
volumeMounts:
{{- range .Values.volumeMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- end }}
volumes:
{{- range .Values.volumes }}
- name: {{ .name }}
persistentVolumeClaim:
claimName: {{ $.Values.persistence.claimName }}
{{- end }}
# my-n8n/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ printf "%s-%s" .Release.Name .Chart.Name }}
spec:
type: {{ .Values.service.type }}
ports:
- port: 5678
targetPort: 5678
nodePort: {{ .Values.service.port }}
protocol: TCP
selector:
app: n8n
my-n8n
then run the linter.helm lint my-n8n
helm install my-n8n ./my-n8n
kubectl get all
Great effort! You just learned how to create and configure a Helm chart and then deploy it to a Kubernetes cluster!