Kubernetes has completely changed the way we deploy software. It’s powerful, scalable and… honestly often quite overwhelming. Maybe you know the feeling: you understand the basics of pods and services, but suddenly you’re drowning in a flood of manifest files. What was manageable in a small project quickly becomes chaos within the team.
In this article I’ll show you the tool that no modern tech stack should be without: Helm. We’ll look at why it’s the de facto standard for Kubernetes deployments and how it helps you keep your infrastructure as clean as your code.
Let’s tame the chaos.
The problem with “Raw” Kubernetes
Hand on heart: your first steps with Kubernetes probably looked like mine. You followed a tutorial, wrote a deployment.yaml, maybe a service.yaml, and booted everything up with kubectl apply -f .. Magical, right?
But then everyday life came. You need an environment for Dev, one for Staging and one for Production. Suddenly you have:
deployment-dev.yaml(Replicas: 1)deployment-staging.yaml(Replicas: 2)deployment-prod.yaml(Replicas: 5, andere CPU-Limits, andere Env-Vars)
Now if you want to change one thing (e.g. the image tag), you have to touch three files. The risk of you making a typo or forgetting a file in Production feels like 100%. You are violating the DRY principle (Don’t Repeat Yourself), which is sacred to us when it comes to coding but is often ignored when it comes to infrastructure.
Welcome to “YAML hell”. And here’s the way out: Helmet.
What exactly is a helmet?
Very simple: If Kubernetes is the operating system, then Helm is the package manager.
Think npm for Node.js, pip for Python or apt for Ubuntu.
Helm basically does two things:
- It bundles complex Kubernetes applications into a reusable package (called Chart).
- It allows you to configure these packages without having to rewrite the actual files.
Instead of manually managing dozens of YAML files, you install a package with one command. But the real power for us developers lies under the hood: in the templates.
The Magic: Templates & Values
(Your new best friend) This is where the real shift in mindset happens. In “Raw” Kubernetes, values are hard-coded. In Helm, values are variables.
Imagine you have your deployment.
Without helmet (static & inflexible):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1 # <--- Hartkodiert. Schlecht für Prod.
template:
spec:
containers:
- name: my-app
image: my-company/app:v1.0.0 # <--- Hartkodiert. Muss bei jedem Release geändert werden.
With Helmet (Dynamic & Reusable):
In Helm the file looks like this (often templates/deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
spec:
replicas: {{ .Values.replicaCount }} # <--- Variable!
template:
spec:
containers:
- name: my-app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" # <--- Variable!
Do you see the {{ ... }} syntax? This is Go templating. Helm now looks into a separate file called values.yaml to fill these placeholders.
Your values.yaml is the only thing you still touch:
# values.yaml
replicaCount: 1
image:
repository: my-company/app
tag: v1.0.0
Why is this awesome? You now have one template for all environments.
- For Dev use the standard
values.yaml. - For Prod, just overwrite the
replicaCountto 5 when installing. The template remains untouched. No more copy-paste errors.
Anatomy, terms and the command line
The vocabulary
Only 3 termsTo understand Helm, you don’t have to memorize a dictionary. There are only three concepts that matter:
- Chart: The package.
Think of a
.debfile on Linux or a.msion Windows. A chart contains all the templates your app needs. - Repository: The warehouse. The location where charts reside (like Docker Hub for images or npm registry for nodes).
- Release: The instance.
When you install a chart, a release is created. This is important: You can install the same chart five times (e.g.
wordpress-dev,wordpress-staging, etc.) - that’s five different releases.
Anatomy of a chart: Where is what?
A chart is not a black box, but simply a folder with a clear structure. If you type helm create my-chart you get exactly this:
mein-chart/
├── Chart.yaml # Metadaten (Name, Version, Beschreibung)
├── values.yaml # Deine "Knöpfe & Regler" (Hier spielt die Musik!)
├── charts/ # Abhängigkeiten (falls dein Chart z.B. eine DB braucht)
└── templates/ # Die eigentlichen K8s-Manifeste mit Platzhaltern
├── deployment.yaml
└── service.yaml
The most important file for your everyday life? The values.yaml. It is your interface for configuration.
Die Magie in Action: Templates vs. Values
Let’s look at how Helm turns static YAML into dynamic code.
The template (templates/deployment.yaml):
Here we define the structure, but leave gaps for the variable data.
apiVersion: apps/v1
kind: Deployment
metadata:
# Der Name wird dynamisch anhand des Releases generiert
name: {{ .Release.Name }}-web
spec:
# Wir greifen auf die Config zu
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
The configuration (values.yaml):
Here we define the standards (“defaults”).
replicaCount: 1
image:
repository: nginx
tag: stable
If you install now, Helm will “render” the template. It replaces {{ .Values.replicaCount }} with 1. The result is valid Kubernetes YAML that goes directly to the cluster.
Cheatsheet: The commands for everyday life
You don’t have to know all 50 Helm Commands. These cover 90% of your everyday life:
Manage repositories
helm repo add [name] [url]Adds a source (e.g. Bitnami).helm repo updateUpdates your local list (likeapt-get update).helm search repo [keyword]Searches for charts (e.g.helm search repo nginx).
Install & Upgrade
helm install [release-name] [chart-name]Installs a chart. Example:helm install my-wiki bitnami/dokuwikihelm upgrade [release-name] [chart-name]The most important command in CI/CD: Updates a release with a new image or new config.helm listShows you what is currently running in your cluster.helm uninstall [release-name]Clean up and delete everything that belongs to the chart.
Pro-Tip: Use
helm install --dry-run --debug. This will show you the generated YAML without installing it. Perfect for debugging before you break something.
The real power: overwriting values
Why are we doing this? So that we can use different values for Production than for Dev without changing the chart.
You have two options to override the values.yaml:
Option A: The Quick-Fix (Command Line)
Perfect for quick tests or small changes.
helm install my-app ./my-chart --set replicaCount=3
Option B: The professional way (own file)
You create your own file for the environment, e.g. values-prod.yaml.
helm install my-app ./my-chart -f values-prod.yaml
The values-prod.yaml then only contains the differences to the standard (e.g. more replicas, ingress activated). This is Infrastructure as Code in its purest form.
![[EN] Helm für Einsteiger: Schluss mit der Kubernetes-YAML-Hölle](/images/Helm-For-Beginners-Header.jpeg)