Skip to content

Helm Charts: Package Management for Kubernetes

DodaTech 3 min read

In this tutorial, you'll learn about Helm Charts: Package Management for Kubernetes. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Helm is the Kubernetes package manager that bundles related Kubernetes resources into charts, enabling repeatable deployments with parameterized templates and dependency management.

What You'll Learn

This tutorial covers creating Helm charts from scratch, Go template syntax, values files, chart dependencies, lifecycle hooks, testing charts, and publishing to a chart Repository.

Why It Matters

Manual YAML management becomes unmanageable beyond a few services. Helm charts reduce deployment errors, enable CI/CD integration, and provide versioned releases that can be shared across teams.

Real-World Use

GitLab uses Helm charts to deploy the entire GitLab platform on Kubernetes. Airbnb uses Helm with custom plugins for multi-environment deployments across staging and production clusters.

Creating Your First Chart

Use the create command to scaffold a new chart.

helm create mychart

# Chart directory structure
helm create mychart && ls mychart/

The chart directory contains Chart.yaml, values.yaml, templates/, and charts/ folders.

Chart.yaml Structure

apiVersion: v2
name: mychart
description: A Helm chart for deploying web applications
type: application
version: 0.1.0
appVersion: "1.0.0"
dependencies:
- name: postgresql
  version: "12.x"
  repository: https://charts.bitnami.com/bitnami

Template Functions and Pipelines

Helm uses Go templates with built-in functions and pipelines.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.app.name | default "myapp" | quote }}
  labels:
    app: {{ .Values.app.name }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: {{ .Values.service.port }}

Values File

# values.yaml
replicaCount: 3
image:
  repository: nginx
  tag: latest
service:
  port: 80
app:
  name: web-app
ingress:
  enabled: true
  host: app.example.com

Using Named Templates

Named templates (partials) reduce duplication.

{{- define "mychart.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
{{- end -}}

Reference them with the include function.

metadata:
  labels:
    {{- include "mychart.labels" . | nindent 4 }}

Chart Dependencies

Manage subcharts as dependencies.

# Add dependency repository
helm repo add bitnami https://charts.bitnami.com/bitnami

# Update dependencies
helm dependency update mychart/

# Build dependencies into charts/ directory
helm dependency build mychart/

Lifecycle Hooks

Helm hooks run actions at specific points in the release lifecycle.

apiVersion: batch/v1
kind: Job
metadata:
  name: pre-install-job
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      containers:
      - name: migration
        image: migrate/migrate
        command: ["migrate", "up"]
      restartPolicy: Never

Testing Charts

Write tests in the templates/tests/ directory.

apiVersion: v1
kind: Pod
metadata:
  name: mychart-test
  annotations:
    "helm.sh/hook": test
spec:
  containers:
  - name: curl-test
    image: curlimages/curl
    command: ["curl", "http://mychart:80"]
  restartPolicy: Never
# Run chart tests
helm test myrelease

Publishing to a Repository

Package and host charts in a repository.

# Package chart
helm package mychart/

# Index the repository
helm repo index .

# Upload to storage or registry
helm push mychart-0.1.0.tgz oci://registry.example.com/charts

Practice Questions

  1. What is the difference between Chart version and appVersion? Chart version tracks the chart definition changes. appVersion tracks the application version being deployed.

  2. How do you create a chart with a dependency on PostgreSQL? Add PostgreSQL to the dependencies list in Chart.yaml, then run helm dependency update.

  3. What are Helm hooks used for? Hooks run jobs at lifecycle events like pre-install, post-install, pre-upgrade, and pre-delete.

  4. How do you pass custom values during installation? Use --set key=value or -f custom-values.yaml with helm install.

  5. What command packages a chart for distribution? helm package mychart/ creates a .tgz archive in the current directory.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro