Helm — Kubernetes Package Manager
Installation
Download the helm
executable from GitHub1:
wget https://get.helm.sh/helm-v3.17.1-linux-amd64.tar.gz
tar -xzf helm-v3.17.1-linux-amd64.tar.gz
cp linux-adm64/helm /usr/local/bin
Overview
Helm2 — Package manager for Kubernetes
- Based on a client-only architecture, connects with the Kubernetes API (like
kubectl
) - Simplifies the reusable & reproducible deployment of Kubernetes applications
- Provides a structured way maintain Kubernetes applications
- Abstracts the complexity of Kubernetes manifests
- Tracks versions of releases …enables upgrade & roll-back
Basic terminology:
- Chart — Helm package (similar to DEB, RPM, etc)
- Repository — Collection of charts
- Release — Instance of a chart running in Kubernetes
Helm installs charts into Kubernetes …new release for each installation
# search charts
1helm search hub $string
# use a chart repository
2helm repo add bitnami https://charts.bitnami.com/bitnami
helm search repo bitnami
helm install bitnami/mysql --generate-name
- 1
- Search ArtifactHub3 for Helm charts from different repositories
- 2
-
Add a repository to make charts available for installation,
search
for packages by name,install
a package …auto generate a name--generate-name
1# list all releases in a specific namespace
helm list
# …all namespaces
helm list -A
# …apply a regex to the releases
helm list --filter 'ara[a-z]+'
# retrieve detailed information about a specific release
2helm status $release_name
# remove a release
helm uninstall $release_name
- 1
- Summary of all releases: Release names, namespace, revision, last update
- 2
- Check the health and details of a specific release: Revision number, chart version, namespace & created resources
Customization
# installs a chart with the specified release name
helm install $release_name $chart
# generate the name a release name
helm install -g $chart
# print resources form a release
helm get manifest $release_name
Release Name — Unique identifier for a specific instance of a Helm chart
- Specified by the user when installing a chart (unless auto-generated)
- Must be unique within a namespace in the Kubernetes cluster.
- Used to identify and manage the deployed resources
- Naming conventions …lowercase letters, numbers & hyphens
Values — Configuration settings passed to a chart
- Enable users to customize an application…
- …specific configuration settings to adjust to their environment
- …mechanism to overwrite the default values from a chart
# see what options are configurable on a char
helm show values $chart
# specify a YAML file to overwrite default keys
cat > values.yaml <<EOF
mariadb.auth.database: example
mariadb.auth.username: admin
EOF
helm install -f values.yaml #…
# overwrite values on the command line
helm install --set $key=$value,$key=$value #…
# display configuration of a chart
helm get values $chart
Development
helm create $chart
# validate the format
helm lint $chart
# package the chart up for distribution
helm package $chart
Reference the chart development documentation4
Chart.yaml # chart metadata
LICENSE
README.md
values.yaml # default configuration
charts/ # (optional) other subcharts
crds/ # custom resource definitions
templates/ # templates…combined with values …generate Kubernetes manifest templates/NOTES.txt # (optional) text file with usage notes
What is a chart?
- Collection of files describing Kubernetes resources
- Files organized in a particular directory structure
- File bundled into a package with semantic versions5
Components of a chart:
- CRDs (Custom Resource Definitions) — Declaring new types of Kubernetes objects
- Installed before the rest of a chart…
- …must be plain YAML documents (no template support)
Naming convention *.yaml
for YAML files, *.tpl
for helpers
Values
Values — Separates environment configuration from the Kubernetes application
- Customize charts without modifying the underlying chart templates
- Recommended to keep values trees shallow, favoring flatness
- Deleting a default key by overwriting it with
null
Namespace objects — Values that are passed into a template
- Dot
.
separates each namespaced element - Leading dot indicates top-most namespace
- Built-in values always begin with a capital letter…
- …convention to initial lower case letters to distinguish local names
Objects | Description |
---|---|
.Release |
Object describes the release itself |
.Chart 6 |
Provides metadata from Chart.yaml |
.Values |
Defaults for this object are defined in the values.yaml file |
.Files |
Access to all non-special files in a chart (not templates) |
.Capabilities |
Capabilities the Kubernetes cluster supports |
.Template |
Information about the current template |
.Subcharts |
Provides access to the object scope subcharts |
Labels
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-pod"
labels:
app.kubernetes.io/name: "{{ .Chart.Name }}"
app.kubernetes.io/instance: "{{ .Release.Name }}"
app.kubernetes.io/version: "{{ .Chart.Version }}"
app.kubernetes.io/managed-by: "{{ .Release.Service }}"
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
- Labels are typically defined in the templates
- Best practice…
- Consistent labeling across your resource
- Avoid overlapping labels
Consider to use helpers.tpl
to make labels consistent in all templates:
{{/* Standard application labels */}}
{{- define "mychart.labels.standard" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/version: {{ .Chart.Version }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
Use the include
function to read labels from helpers.tpl
metadata:
name: {{ .Release.Name }}-service
labels:
{{ include "mychart.labels.standard" . | indent 4 }}
spec:
selector:
{{ include "mychart.labels.standard" . | indent 4 }}
Templates
Example template:
templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
# using a template function to modfiy a value
myvalue: {{ quote .Values.myvalue }}
Templates — Generate Kubernetes manifests
- Mechanism to configure applications for different environments
- Follow the standard conventions for Go templates7
- …combined with
values.yaml
inside a chart - A template directive is enclosed in
{{
and}}
blocks
Debugging helm chart templates:
# render templates & print …no deployment
helm install --dry-run --debug $release_name $chart
#
helm template --debug #…
Example for template functions & pipelines:
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
- Template functions8 — Transform data from a value object
default
— Specify a default value inside of the templatelookup
— Look up resources in a running cluster
- Template pipelines — Chain together a series of template commands
- Flow control9 supports
if…else
to create conditional blocks - Control white-space:
{{-
trim left white space,}}*
remove newline characters
Hooks
Hooks — Perform operations at strategic points in a release lifecycle
- Uses cases:
- Tasks that need to before/after certain events10
- Load
ConfigMap
/Secret
…prepare, backup, test
Footnotes
Installing Helm, Helm Documentation
https://helm.sh/docs/intro/install
https://github.com/helm/helm/releases↩︎Helm Project
https://helm.sh/docs
https://github.com/helm↩︎ArtifactHub
https://artifacthub.io↩︎Chart Development, Helm Documentation
https://helm.sh/docs/topics/charts
https://helm.sh/docs/howto/charts_tips_and_tricks↩︎Semantic Versioning 2.0.0
https://semver.org/spec/v2.0.0.html↩︎Chart.yaml
File, Helm Documentation
https://helm.sh/docs/topics/charts/#the-chartyaml-file↩︎Go Template Package
https://pkg.go.dev/text/template↩︎Helm Template Function
https://helm.sh/docs/chart_template_guide/function_list
https://masterminds.github.io/sprig↩︎Flow Control, Helm Documentation
https://helm.sh/docs/chart_template_guide/control_structures↩︎Available Hooks, Helm Documentation
https://helm.sh/docs/topics/charts_hooks/#the-available-hooks↩︎