Theory
Reading time: ~15 minutes · Prerequisites: Basic Kubernetes and kubectl familiarity
1. The Problem: Managing Kubernetes Manifests at Scale
Every Kubernetes application is defined by a collection of YAML manifests — Deployments, Services, ConfigMaps, Secrets, Ingresses, and more. For a simple "hello world" application, you might write two or three files. But real-world applications quickly balloon: a typical microservice might need a Deployment, a Service, an Ingress, a ConfigMap, a Secret, a ServiceAccount, a HorizontalPodAutoscaler, and a PodDisruptionBudget. Multiply that across a dozen services and three environments (dev, staging, production), and you are managing hundreds of YAML files.
Worse, these files are often nearly identical across environments — differing only in a replica count, an image tag, or a domain name. Without a templating or packaging layer, teams resort to copy-pasting manifests and making manual edits, a process that is both error-prone and impossible to audit reliably.
This is the problem Helm was created to solve.
2. What Is Helm?
Helm is the package manager for Kubernetes. It packages Kubernetes manifests into a unit called a chart, applies user-provided configuration through values, and tracks every deployment as a versioned release. The analogy to traditional package managers is deliberate: a Helm chart is to Kubernetes what a .deb package is to Debian, or a Homebrew formula is to macOS.
With Helm, you can:
- Template manifests — replace hard-coded values with Go template expressions that are filled in at install time
- Package and share — bundle an entire application into a single archive (
.tgz) and publish it to a repository - Version deployments — every
helm installorhelm upgradecreates a new revision that can be inspected or rolled back - Manage dependencies — a chart can declare dependencies on other charts, and Helm resolves and installs them automatically
Key Insight
Helm does not replace kubectl. Under the hood, Helm renders templates into standard Kubernetes YAML and submits them to the API server. You can always inspect the rendered output with helm template before applying anything to your cluster.
3. Helm 3 Architecture
Helm went through a major architectural change between versions 2 and 3. Understanding this history helps explain design decisions you will encounter.
Helm 2 and Tiller
Helm 2 used a two-component architecture: the helm CLI on the client side, and a server-side component called Tiller that ran as a pod inside the cluster. When you ran helm install, the CLI sent the chart to Tiller, which rendered the templates and applied the resulting manifests to Kubernetes.
Tiller was problematic for several reasons. It required broad permissions (often cluster-admin) to function, creating a significant security surface. In multi-tenant clusters, any user who could reach Tiller effectively had cluster-wide access. Release metadata was stored as ConfigMaps, which were difficult to secure and manage.
Helm 3: Client-Only
Helm 3, released in November 2019, removed Tiller entirely. The helm CLI now talks directly to the Kubernetes API server using the credentials from your kubeconfig file. This means Helm respects your existing RBAC policies — if your user account cannot create Ingresses, then helm install will fail when it tries to create one, just as kubectl apply would.
Release metadata is now stored as Kubernetes Secrets (type helm.sh/release.v1) in the same namespace as the release. This makes them easier to secure with standard Kubernetes RBAC and encryption-at-rest. You can inspect them directly:
# List Helm release secrets in the default namespace
kubectl get secrets -l owner=helm
# Inspect a specific release secret (base64-encoded, gzipped)
kubectl get secret sh.helm.release.v1.my-nginx.v1 -o yaml
Helm 2 End of Life
Helm 2 reached end of life in November 2020. All new projects should use Helm 3. If you encounter Helm 2 charts or documentation, be aware that the Tiller-based architecture no longer applies.
4. Core Concepts in Detail
Charts
A chart is a directory (or a .tgz archive of that directory) containing everything needed to deploy an application. The minimum structure is:
mychart/
Chart.yaml # Required: name, version, description, apiVersion
values.yaml # Default configuration values
templates/ # Go templates that render to Kubernetes manifests
deployment.yaml
service.yaml
_helpers.tpl # Reusable template snippets (partials)
The Chart.yaml file is the chart's identity. It declares the chart name, version (following SemVer), an optional appVersion (the version of the application being deployed), and any dependencies on other charts.
Releases
Every time you run helm install, Helm creates a release — a named instance of a chart running in a specific namespace. You can install the same chart multiple times with different release names (e.g., nginx-staging and nginx-production), each with its own values and independent lifecycle.
Each helm upgrade creates a new revision of the release. You can view the history and roll back to any previous revision:
# View release history
helm history my-nginx
# Roll back to revision 2
helm rollback my-nginx 2
Repositories
A chart repository is an HTTP server that hosts an index.yaml file listing available charts and their download URLs. Helm supports adding multiple repositories and searching across them:
# Add a repository
helm repo add bitnami https://charts.bitnami.com/bitnami
# Refresh the local index cache
helm repo update
# Search for charts matching "redis"
helm search repo redis
Helm 3 also supports OCI registries as chart repositories. This means you can store charts in the same container registries (Docker Hub, GitHub Container Registry, Amazon ECR) that you use for container images.
Values
Values are the primary mechanism for customizing a chart. Every chart ships with a values.yaml that defines sensible defaults. Users override these defaults at install or upgrade time using -f (values files) or --set (individual key-value pairs).
# values-production.yaml
replicaCount: 3
image:
tag: "1.25.3"
service:
type: LoadBalancer
resources:
limits:
cpu: 500m
memory: 256Mi
# Install with production values
helm install my-nginx bitnami/nginx -f values-production.yaml
# Override a single value on top of the file
helm install my-nginx bitnami/nginx -f values-production.yaml --set replicaCount=5
Inspecting Default Values
Before installing any chart, review its default values to understand what can be configured: helm show values bitnami/nginx. This prints the entire values.yaml with comments explaining each parameter.
5. Artifact Hub: Discovering Charts
Artifact Hub is the official CNCF-hosted registry for discovering Kubernetes packages, including Helm charts. It indexes charts from hundreds of repositories and provides a searchable web interface with documentation, version history, and security reports.
You can also search Artifact Hub from the CLI:
# Search Artifact Hub for WordPress charts
helm search hub wordpress
When evaluating a chart from Artifact Hub, look for:
- Verified publisher badge — the publisher has been verified by Artifact Hub
- Security report — automated vulnerability scanning of the chart's container images
- Recent updates — actively maintained charts receive regular version bumps
- Stars and installs — community adoption signals quality and support
6. Raw kubectl apply vs Helm: A Practical Comparison
To make the value proposition concrete, consider deploying a web application that needs a Deployment, Service, and Ingress across two environments.
The kubectl Approach
You create six YAML files (three per environment) or use Kustomize overlays. To deploy, you run kubectl apply -f ./staging/. To update the image tag, you edit the file (or use kubectl set image). To roll back, you either keep old files in Git and re-apply, or use kubectl rollout undo (which only covers Deployments, not Services or Ingresses). There is no single command that captures the entire state of your deployed application.
The Helm Approach
You create one chart with templates. Environment differences live in values-staging.yaml and values-production.yaml. To deploy staging, you run helm install myapp ./mychart -f values-staging.yaml. To update the image tag, you change the value and run helm upgrade. To roll back all resources atomically, you run helm rollback myapp 1. The entire release history — including which values were used for each revision — is stored in the cluster and can be inspected at any time.
| Capability | kubectl apply | Helm |
|---|---|---|
| Parameterization | Kustomize or manual edits | Built-in Go templates + values |
| Atomic rollback | Not supported natively | helm rollback |
| Release versioning | Requires external tooling | Automatic revision tracking |
| Dependency management | Manual | Chart dependencies in Chart.yaml |
| Sharing & reuse | Copy YAML files | Chart repositories / OCI registries |
7. Why Templates Matter
At the heart of every Helm chart is the templates/ directory, where Go template syntax transforms static YAML into dynamic, parameterized manifests. A simple example:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
spec:
containers:
- name: app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
The double-brace expressions ({{ }}) are replaced at render time with values from the release context and the user-provided values file. This single template can produce different manifests for every environment, every release name, and every configuration variant — without duplicating a single line of YAML.
Preview Before You Apply
You can render templates locally without touching a cluster: helm template my-release ./mychart -f values.yaml. This outputs the fully rendered YAML to stdout, which is invaluable for debugging and code review.
Further Reading
- Helm Quickstart Guide — official getting-started tutorial
- Charts Documentation — complete reference for chart structure, templates, and dependencies
- helm install Reference — full flag documentation for the install command
- Artifact Hub — discover and evaluate community Helm charts
Next lesson: Lesson 02 — we will build our first Helm chart from scratch, exploring the template language and chart structure in depth.