Helm charts are more than just templated Kubernetes manifests; they’re a fundamental package manager for Kubernetes applications, enabling reproducible deployments and sophisticated release management.
Let’s see Helm in action. Imagine you have a simple Nginx deployment. Without Helm, you’d manage several YAML files: deployment.yaml, service.yaml, ingress.yaml, and potentially others.
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
And a values.yaml file to configure it:
# values.yaml
replicaCount: 1
image:
repository: nginx
tag: latest
Now, you can install this with Helm:
helm install my-nginx ./my-nginx-chart -f values.yaml
This command takes the templates, injects values from values.yaml (and any other specified files), and renders them into concrete Kubernetes manifests, which are then applied to your cluster. my-nginx-nginx-deployment and my-nginx-nginx-service are created. If you wanted 3 replicas, you’d change values.yaml to replicaCount: 3 and run helm upgrade my-nginx ./my-nginx-chart.
Helm solves the problem of managing complex, multi-component applications on Kubernetes. It allows you to define an application as a package (a chart), which includes all Kubernetes resources needed to run it. This package can then be versioned, shared, and deployed consistently across different environments. The templating engine (Go’s text/template) allows you to parameterize your manifests, so a single chart can deploy an application with varying configurations (e.g., different replica counts, image tags, resource limits).
Internally, a Helm chart is a directory structure. The templates/ directory holds your Kubernetes manifests, which can contain Go templating syntax. The values.yaml file provides default configuration values. The Chart.yaml file contains metadata about the chart itself, like its name, version, and maintainers. requirements.yaml (or Chart.yaml in Helm v3+) allows you to declare dependencies on other charts. When you run helm install or helm upgrade, Helm reads these files, executes the templating engine with the provided values, and then uses the Kubernetes API to create or update the resources. The Helm client maintains a release history for each deployed chart, allowing you to roll back to previous versions.
The lookup function in Helm templates is a powerful, albeit often overlooked, tool for dynamically fetching information from your Kubernetes cluster during the template rendering process. This means you can make decisions or populate values based on existing resources without needing to hardcode them. For instance, you could use lookup to find the IP address of an existing database service and configure your application to connect to it, or to determine the correct CIDR block for a network policy based on existing subnet configurations. This capability bridges the gap between static chart definitions and dynamic cluster environments, enabling more intelligent and adaptable deployments.
The next logical step after mastering basic Helm deployments is understanding how to manage complex dependencies between charts and implement advanced lifecycle hooks.