Introduction to Helm
We need a Kubernetes cluster
Lets create a Kubernetes cluster to play with using kind
kind create cluster --name helm --image kindest/node:v1.31.1
Getting Started with Helm
Firstly, I like to do most of my work in containers so everything is reproducible
and my machine remains clean.
Get a container to work in
Run a small `alpine linux` container where we can install and play with `helm`:
docker run -it --rm -v ${HOME}:/root/ -v ${PWD}:/work -w /work --net host alpine sh
# install curl & kubectl
apk add --no-cache curl nano
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
export KUBE_EDITOR="nano"
# test cluster access:
/work # kubectl get nodes
NAME STATUS ROLES AGE VERSION
helm-control-plane Ready control-plane 26m v1.31.1
Install Helm CLI
curl -LO https://get.helm.sh/helm-v3.17.2-linux-amd64.tar.gz
tar -C /tmp/ -zxvf helm-v3.17.2-linux-amd64.tar.gz
rm helm-v3.17.2-linux-amd64.tar.gz
mv /tmp/linux-amd64/helm /usr/local/bin/helm
chmod +x /usr/local/bin/helm
Create our first Chart
For reference in the rest of the guide, I have left my full templates in:
<GitRepo>/kubernetes/helm/example-app
cd kubernetes/helm
mkdir temp && cd temp
helm create example-app
Cleanup the template
We can delete unwanted files:
- delete everything under /templates, keeping only
_helpers.tpl
- delete
tests
folder undertemplates
Add Kubernetes files to our new Chart
Copy the following files into our example-app/templates/
folder
<GitRepo>/kubernetes/deployments/deployment.yaml
<GitRepo>/kubernetes/services/service.yaml
<GitRepo>/kubernetes/configmaps/configmap.yaml
<GitRepo>/kubernetes/secrets/secret.yaml
Test the rendering of our template
helm template example-app example-app
Install our app using our Chart
helm install example-app example-app
# list our releases
helm list
# see our deployed components
kubectl get all
kubectl get cm
kubectl get secret
Value injections for our Chart
For CI systems, we may want to inject an image tag as a build number
Basic parameter injection:
# values.yaml
deployment:
image: "aimvector/python"
tag: "1.0.4"
# deployment.yaml
image: {{ .Values.deployment.image }}:{{ .Values.deployment.tag }}
# upgrade our release
helm upgrade example-app example-app --values ./example-app/values.yaml
# see revision increased
helm list
Make our Chart more generic
Let's make our chart generic so it can be reused:
For the following objects, replace example-deploy
and example-app
to inject: "{{ .Values.name }}"
- deployment.yaml
- services.yaml
- secret.yaml
- configmap.yaml
Now that our application is generic
We can deploy another copy of it.
Rename values.yaml
to example-app.values.yaml
Create our second app values file example-app-02.values.yaml
helm install example-app-02 example-app --values ./example-app/example-app-02.values.yaml
Trigger deployment change when config changes
By default, a deployment will not rollout new pods when a configmap changes.
Some application read configuration at start up and deployment may need to roll out
new pods when a configmap changes. Let's do that:
# deployment.yaml
kind: Deployment
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
# rollout the change
helm upgrade example-app example-app --values ./example-app/example-app-01.values.yaml
If\Else and Default values
You can also set default values in case they are not supplied by the values.yaml
file.
This may help you keep the values.yaml
file small
{{- if .Values.deployment.resources }}
resources:
{{- if .Values.deployment.resources.requests }}
requests:
memory: {{ .Values.deployment.resources.requests.memory | default "50Mi" | quote }}
cpu: {{ .Values.deployment.resources.requests.cpu | default "10m" | quote }}
{{- else}}
requests:
memory: "50Mi"
cpu: "10m"
{{- end}}
{{- if .Values.deployment.resources.limits }}
limits:
memory: {{ .Values.deployment.resources.limits.memory | default "1024Mi" | quote }}
cpu: {{ .Values.deployment.resources.limits.cpu | default "1" | quote }}
{{- else}}
limits:
memory: "1024Mi"
cpu: "1"
{{- end }}
{{- else }}
resources:
requests:
memory: "50Mi"
cpu: "10m"
limits:
memory: "1024Mi"
cpu: "1"
{{- end}}
# rollout the change
helm upgrade example-app example-app --values ./example-app/example-app-01.values.yaml