Understanding Helm - The Kubernetes Package Manager

Simplify and streamline your Kubernetes application deployments

Featured image



Overview

Helm is the package manager for Kubernetes, providing functionality to package, share, and use software built for Kubernetes. Think of it as apt/yum/homebrew for Kubernetes - a tool that simplifies the installation and management of applications and services.

graph TD A[Helm Client] --> B[Kubernetes API] B --> C[Kubernetes Cluster] D[Chart Repository] --> A A --> E[Chart] E --> F[Release] F --> C style A fill:#1E88E5,stroke:#0D47A1,color:#FFF style D fill:#43A047,stroke:#2E7D32,color:#FFF style E fill:#FB8C00,stroke:#EF6C00,color:#FFF style F fill:#8E24AA,stroke:#6A1B9A,color:#FFF


What is Helm?

Helm uses a package format called a chart, which is a collection of files describing a related set of Kubernetes resources. A single chart might be used to deploy something simple, like a memcached pod, or something complex, like a full web app stack with HTTP servers, databases, caches, and more.

Charts are easy to create, version, share, and publish — making them valuable for streamlining deployments in a Kubernetes environment.

Helm Evolution

Helm was initially created by Deis (later acquired by Microsoft) and was donated to the Cloud Native Computing Foundation (CNCF) in 2018. Helm v3, released in November 2019, represented a significant architectural change from Helm v2, removing the server-side Tiller component and improving security.


Key Components

Component Description Notes
Chart Package format for Kubernetes resources Contains YAML templates, values files, and metadata for Kubernetes applications
Repository Location to share and collect charts Public repositories like Artifact Hub or private repositories can be used
Release Instance of a chart running in a cluster Each installation of a chart creates a new release, allowing multiple instances of the same chart
Values Configuration for chart templates Can be provided in values.yaml or via command line
Template YAML files with Go templating Generates Kubernetes manifests when combined with values

Helm supports chart repositories that can be used to store and share Helm charts. The distributed community helm chart repository is located at Artifact Hub.

Artifact Hub is a web-based application that enables you to find, install, and publish packages and configurations for CNCF projects, including publicly available decentralized Helm charts.



Getting Started with Helm


Installation

Before installing Helm, ensure you have the following prerequisites:


Installation Methods

Method Commands
Binary Release
wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz
tar -zxvf helm-v3.12.0-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
Script Install
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
Package Managers
# macOS with Homebrew
brew install helm

# Windows with Chocolatey
choco install kubernetes-helm

# With Snap
sudo snap install helm --classic

You can check the installation method according to your OS in the official installation guide.

Verify Installation

helm version

Configuring Helm

After installation, you may want to add repositories to find and use existing charts:

# Add the official Stable charts repository
helm repo add stable https://charts.helm.sh/stable

# Add Bitnami repository (popular maintained charts)
helm repo add bitnami https://charts.bitnami.com/bitnami

# Update repo information
helm repo update

# List configured repositories
helm repo list



Understanding Helm Charts

Chart Structure

A chart is organized as a collection of files inside a directory. The directory name is the name of the chart.

Standard Chart Directory Structure
    mychart/
      ├── Chart.yaml            # Metadata about the chart
      ├── values.yaml           # Default configuration values
      ├── values.schema.json    # Optional JSON Schema for validating values
      ├── charts/               # Directory containing dependency charts
      ├── crds/                 # Custom Resource Definitions
      ├── templates/            # Kubernetes manifest templates
      │   ├── NOTES.txt         # Usage notes displayed after installation
      │   ├── deployment.yaml   # Kubernetes deployment manifest template
      │   ├── service.yaml      # Kubernetes service manifest template
      │   ├── _helpers.tpl      # Template helpers and named templates
      │   └── ...               # Other resource templates
      └── README.md             # Optional readme file

Basic Chart Files

File Example
Chart.yaml
apiVersion: v2
name: my-application
description: A Helm chart for a Kubernetes application
type: application
version: 1.0.0         # Chart version
appVersion: "2.3.4"    # Application version
dependencies:
  - name: mongodb
    version: 13.6.4
    repository: https://charts.bitnami.com/bitnami
    condition: mongodb.enabled
maintainers:
  - name: Your Name
    email: your.email@example.com
values.yaml
replicaCount: 2

image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "1.21.6"

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 50m
    memory: 64Mi

mongodb:
  enabled: true
  auth:
    rootPassword: "password"
templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "mychart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "mychart.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

Chart Templating

Helm uses Go templates to enable dynamic manifest generation. Some key templating features include:

  1. Values References: Access configuration with .Values.key.subkey
  2. Built-in Objects: Use .Chart, .Release, .Capabilities, etc.
  3. Functions and Pipelines: quote, indent, toYaml, etc.
  4. Control Structures: if/else, with, range
  5. Named Templates: Create reusable components with define and template

Example template with control flow:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- if eq .Values.environment "production" }}
  log-level: "error"
  {{- else }}
  log-level: "debug"
  {{- end }}
  
  {{- with .Values.config }}
  database-url: {{ .dbUrl | quote }}
  timeout: {{ .timeout | default 30 }}
  {{- end }}
  
  settings: |
    {{- range $key, $val := .Values.settings }}
    {{ $key }}: {{ $val | quote }}
    {{- end }}



Helm Commands and Workflow

Common Helm Commands

🔧 Command 📄 Purpose 💻 Example
search Find charts helm search hub wordpress
helm search repo stable
install Install a chart helm install my-release bitnami/wordpress
helm install -f values.yaml my-app ./mychart
📊 status Check release status helm status my-release
upgrade Upgrade a release helm upgrade --set image.tag=v2 my-release ./chart
rollback Rollback to previous version helm rollback my-release 1
delete Remove a release helm delete my-release
list Show all releases helm list --all-namespaces
helm list --pending
lint Validate chart helm lint ./chart
template Render templates locally helm template ./mychart
helm template --debug ./mychart
package Package a chart helm package ./mychart
dependency Manage chart dependencies helm dependency update ./mychart
create Create a new chart helm create mychart

Typical Helm Workflow

sequenceDiagram participant D as Developer participant H as Helm Client participant R as Repository participant K as Kubernetes D->>H: helm create mychart D->>H: helm lint mychart D->>H: helm template mychart D->>H: helm install mychart H->>K: Apply manifests K-->>H: Confirm resources created H-->>D: Report release status D->>H: helm upgrade mychart H->>K: Apply changes D->>H: helm rollback mychart H->>K: Revert to previous state D->>H: helm package mychart D->>R: Push chart to repository Note over D,K: Future installations D->>H: helm search repo mychart H->>R: Query repository R-->>H: Return search results D->>H: helm install from repo

Values Management

Helm allows you to specify values in multiple ways, with the following precedence (highest to lowest):

  1. --set flag values (command line)
  2. --values / -f flag values (values files specified on command line)
  3. Default values in dependent charts
  4. Default values in the chart’s values.yaml

Example of layered values:

# Install with custom values file and override specific values
helm install -f prod-values.yaml --set replicaCount=3,image.tag=v1.2.3 my-release ./mychart



Creating and Managing Helm Charts

Creating a New Chart

# Create a chart scaffold
helm create mychart

# The directory structure will be created with default templates

Developing and Testing

# Lint your chart to check for issues
helm lint ./mychart

# Render templates locally without installing
helm template ./mychart

# Install your chart with debug info
helm install --debug --dry-run my-release ./mychart

Packaging and Distributing

# Package chart into .tgz archive
helm package ./mychart

# Create a local chart repository
mkdir -p ./my-helm-repo
mv mychart-0.1.0.tgz ./my-helm-repo
helm repo index ./my-helm-repo --url https://example.com/charts

# Add your repository
helm repo add myrepo https://example.com/charts
Best Practices for Chart Development
  • Version Control - Always version your charts and use semantic versioning
  • Values Management - Keep default values.yaml minimal but functional
  • Template Organization - Use _helpers.tpl for common functions and maintain consistent naming
  • Documentation - Include comprehensive README.md and NOTES.txt for users
  • Testing - Use helm lint regularly and implement chart tests
  • Dependencies - Clearly define chart dependencies and version constraints
  • Security - Follow security best practices for container images and RBAC


Chart Hooks

Helm provides hooks that allow chart developers to intervene at certain points in a release’s lifecycle:

Example hook:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-database-init
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      containers:
      - name: db-init-job
        image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
        command: ["./init-db.sh"]
      restartPolicy: Never



Advanced Helm Concepts

Chart Dependencies

Helm charts can depend on other charts, which is useful for creating complex applications:

# Chart.yaml
dependencies:
  - name: postgresql
    version: 11.6.12
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled
  - name: redis
    version: 17.0.10
    repository: https://charts.bitnami.com/bitnami
    alias: cache

Managing dependencies:

# Update dependencies
helm dependency update ./mychart

# Build dependencies (download and unpack)
helm dependency build ./mychart

Library Charts

Library charts are special charts that do not create Kubernetes objects directly but provide reusable templates and helpers:

# Chart.yaml for a library chart
apiVersion: v2
name: my-library
type: library
version: 1.0.0

Helm Plugins

Extend Helm’s functionality with plugins:

# Install a plugin
helm plugin install https://github.com/databus23/helm-diff

# Use the plugin
helm diff upgrade my-release bitnami/wordpress

Helm in CI/CD Pipelines

Integrating Helm with CI/CD

Helm works well in CI/CD pipelines. Here's a simplified GitLab CI example:

    stages:
      - lint
      - package
      - deploy

    lint-chart:
      stage: lint
      script:
        - helm lint ./charts/my-app

    package-chart:
      stage: package
      script:
        - helm package ./charts/my-app
        - helm repo index .
      artifacts:
        paths:
          - ./*.tgz

    deploy-staging:
      stage: deploy
      script:
        - helm upgrade --install my-app-staging ./charts/my-app 
          --set environment=staging
      environment:
        name: staging



Comparing Helm with Other Kubernetes Deployment Tools

Tool Key Features Best For
Helm - Package manager approach
- Templating system
- Rollback capability
- Large ecosystem of charts
- Teams familiar with package managers
- Applications needing versioning
- Reusable component distribution
Kustomize - Configuration layering
- No templating language
- Patches for modifications
- Native kubectl integration
- Environment-specific overlays
- GitOps workflows
- Teams wanting to avoid templating
Argo CD - GitOps controller
- Continuous deployment
- Works with Helm and Kustomize
- UI for visualization
- GitOps-oriented teams
- Multi-cluster management
- Continuous deployment needs
Flux - GitOps toolkit
- Automated git → cluster sync
- Works with Helm
- Notification system
- GitOps workflows
- Kubernetes-native approach
- Teams wanting extensibility



References and Resources

Official Documentation

Community Resources

Books and In-depth Learning