Helm: The Kubernetes Package Manager
Managing Kubernetes manifests for a single microservice is manageable. But what happens when you have 50 services, across 3 environments (Dev, Staging, Prod), each needing slightly different configurations?
You end up with YAML Sprawl: hundreds of duplicate files where only the imageTag or replicaCount differs.
[!IMPORTANT] Helm solves this by treating Kubernetes applications as Packages (Charts). It combines a single Template with multiple Values files to generate the final YAML.
1. The “Why”: Solving YAML Sprawl
Without Helm, your repository looks like this:
/manifests
/dev
deployment.yaml (replicas: 1)
service.yaml
/staging
deployment.yaml (replicas: 2)
service.yaml
/prod
deployment.yaml (replicas: 10)
service.yaml
If you need to add a new environment variable, you must edit three files. This is error-prone and unscalable.
With Helm, you have one source of truth:
/my-chart
/templates
deployment.yaml (replicas: {{ .Values.replicaCount }})
values-dev.yaml (replicaCount: 1)
values-staging.yaml(replicaCount: 2)
values-prod.yaml (replicaCount: 10)
2. Architecture: Charts, Templates, and Values
Helm has three core concepts:
- Chart: The package structure containing all resource definitions.
- Values: The configuration data (JSON/YAML) that is injected into templates.
- Release: An instance of a chart running in a cluster. You can install the same chart multiple times as different releases (e.g.,
mysql-prodandmysql-dev).
The Directory Structure
A standard Helm chart looks like this:
my-chart/
Chart.yaml # Metadata (name, version, appVersion)
values.yaml # Default configuration values
charts/ # Dependency charts
templates/ # The template files
deployment.yaml
service.yaml
_helpers.tpl # Reusable template snippets
3. Interactive: The Template Renderer
Visualize how Helm merges values.yaml with templates/deployment.yaml to generate the final Manifest.
values.yaml
templates/deployment.yaml
Rendered Manifest
4. Under the Hood: Tillerless Architecture (v3)
In Helm v2, a server-side component called Tiller ran inside the cluster with full cluster-admin privileges. This was a major security risk.
Helm v3 removed Tiller entirely.
- Client-Only: The Helm CLI talks directly to the Kubernetes API server using the user’s local
kubeconfigcredentials. - State Storage: Release information (Secrets, ConfigMaps) is stored directly in the namespace where the application runs.
- RBAC: Operations are constrained by the user’s RBAC roles.
5. Essential Commands
# Add a repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Install a chart (creates a Release named 'my-redis')
helm install my-redis bitnami/redis
# Upgrade with new values
helm upgrade my-redis bitnami/redis --set architecture=replication
# Dry run (see what would happen without applying)
helm install my-nginx ./nginx-chart --dry-run --debug
6. Advanced: Helm Hooks
Hooks allow you to intervene at certain points in a release lifecycle.
pre-install: Run a Job to back up a database before installing.post-install: Send a Slack notification after a successful deploy.pre-delete: Clean up external resources before deleting the release.
Example annotation in a Job:
apiVersion: batch/v1
kind: Job
metadata:
name: db-backup
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-5"
spec:
...
Helm waits for the hook to complete successfully before proceeding with the upgrade.
7. Summary
- Charts are packages of pre-configured Kubernetes resources.
- Values allow you to customize charts for different environments without code duplication.
- Helm v3 is secure by design (no Tiller) and uses standard Kubernetes Secrets for state.
- Use Hooks for complex lifecycle management like database migrations.