If you've worked with Kubernetes for a while, you've probably experienced this:
You start with one YAML file.
Then another.
Then another.
Soon your project contains:
k8s/
├── deployment.yaml
├── service.yaml
├── configmap.yaml
├── secret.yaml
├── ingress.yaml
├── serviceaccount.yaml
├── hpa.yaml
└── pvc.yaml
At first, everything feels manageable.
Then you have development, staging, and production environments.
Now you're maintaining multiple versions of the same YAML files.
And suddenly you're thinking:
"There has to be a better way."
There is.
Helm.
Helm is often described as the package manager for Kubernetes, but that description doesn't tell the whole story.
In this article, we'll understand why Helm exists, how Helm charts work, and how you can use Helm to manage real Kubernetes applications.
The Problem With Raw Kubernetes YAML
Let's imagine you deploy a simple application.
You need:
Deployment
Service
ConfigMap
Ingress
Secret
Without Helm, you might have:
deployment.yaml
service.yaml
configmap.yaml
ingress.yaml
secret.yaml
Now suppose your development environment uses:
replicas: 1
while production needs:
replicas: 5
You could maintain separate YAML files:
dev/
deployment.yaml
prod/
deployment.yaml
But as your application grows, this becomes difficult to maintain.
You start duplicating configuration.
That's where Helm becomes useful.
What Exactly Is Helm?
Helm is a tool for managing Kubernetes applications using charts.
A Helm chart packages Kubernetes resources and templates into a reusable application definition.
Think of it like this:
Kubernetes YAML
↓
Templates + Configuration
↓
Helm
↓
Kubernetes Resources
Instead of manually maintaining every variation of your YAML files, you can create a reusable chart.
Helm's Core Idea
Imagine you have this Deployment:
replicas: 3
With Helm, you can make the replica count configurable:
replicas: {{ .Values.replicaCount }}
Then your values.yaml can contain:
replicaCount: 3
For development:
replicaCount: 1
For production:
replicaCount: 5
Same template.
Different values.
That's one of the biggest advantages of Helm.
What Is a Helm Chart?
A Helm chart is a directory containing the files needed to define and package a Kubernetes application.
A typical chart looks like:
my-app/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── configmap.yaml
└── charts/
Let's understand these files.
1. Chart.yaml
This file contains metadata about the chart.
Example:
apiVersion: v2
name: my-app
description: A Kubernetes application
type: application
version: 1.0.0
appVersion: "1.0"
It tells Helm things such as:
- Chart name
- Chart version
- Application version
- Chart type
- Description
Think of it as the chart's identity card.
2. values.yaml
This is one of the most important Helm files.
It contains configurable values.
For example:
replicaCount: 3
image:
repository: nginx
tag: "1.27"
service:
type: ClusterIP
port: 80
Instead of hardcoding these values inside every Kubernetes manifest, your templates can reference them.
For example:
replicas: {{ .Values.replicaCount }}
Now the same chart can be configured differently for different environments.
3. templates/
This directory contains Kubernetes resource templates.
For example:
templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
└── configmap.yaml
These aren't necessarily static Kubernetes manifests.
They contain Helm template expressions.
Example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-app
template:
metadata:
labels:
app: {{ .Release.Name }}-app
spec:
containers:
- name: app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
Now the template can change based on values.
The Magic of .Values
One of the first Helm concepts you should learn is:
.Values
It provides access to values from your chart configuration.
Suppose:
replicaCount: 3
Then:
{{ .Values.replicaCount }}
produces:
3
Similarly:
image:
repository: nginx
tag: "1.27"
can be accessed using:
{{ .Values.image.repository }}
and:
{{ .Values.image.tag }}
This is how Helm connects your configuration with your Kubernetes templates.
Creating Your First Chart
You can create a new chart with:
helm create my-app
Helm generates a chart structure for you.
You'll get something similar to:
my-app/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
└── ...
This is a great starting point for learning.
But don't blindly keep every generated file.
Understand what each file does and remove unnecessary complexity.
Installing a Helm Chart
Once your chart is ready:
helm install my-release ./my-app
Here:
my-release
is the release name.
And:
./my-app
is the chart.
Conceptually:
Helm Chart
↓
helm install
↓
Kubernetes API
↓
Deployment
Service
ConfigMap
Ingress
...
What Is a Helm Release?
This is another important concept.
A chart is the package/template.
A release is an installed instance of that chart.
For example:
Chart:
my-app
You can install it multiple times:
Release 1 → development
Release 2 → staging
Release 3 → production
The same chart can be used for multiple installations with different configurations.
That's extremely useful.
Installing With Custom Values
Suppose your default values.yaml contains:
replicaCount: 1
You want production to use 5 replicas.
You can provide another values file:
replicaCount: 5
For example:
values.yaml
values-production.yaml
Then:
helm install production ./my-app \
-f values-production.yaml
Now the production release uses the production configuration.
Development vs Production
This is where Helm becomes especially useful.
You might have:
values-dev.yaml
values-staging.yaml
values-prod.yaml
For development:
replicaCount: 1
image:
tag: dev
Staging:
replicaCount: 2
image:
tag: staging
Production:
replicaCount: 5
image:
tag: stable
The templates remain the same.
Only the configuration changes.
This gives you:
One Chart
│
├── Development
├── Staging
└── Production
Upgrading a Release
Applications change.
You might update:
image:
tag: "2.0"
Then upgrade the release:
helm upgrade my-release ./my-app
Helm applies the updated configuration to Kubernetes.
Conceptually:
Version 1
↓
helm upgrade
↓
Version 2
This becomes particularly useful in CI/CD pipelines.
Rolling Back
Now imagine version 2 has a problem.
You want to return to the previous release.
Helm maintains release history.
You can inspect it:
helm history my-release
Then roll back:
helm rollback my-release 1
Conceptually:
Release 1
↓
Release 2
↓
Problem
↓
Rollback
↓
Release 1
This can make application deployment management much easier.
Helm and CI/CD
Helm becomes even more powerful when combined with CI/CD.
Imagine a developer pushes code:
Developer
↓
Git Push
↓
CI Pipeline
↓
Build Docker Image
↓
Push Image
↓
Helm Upgrade
↓
Kubernetes
For example:
helm upgrade my-app ./chart \
--set image.tag=abc123
The image tag could correspond to a Git commit or CI build identifier.
Now your deployment process becomes repeatable.
Helm + Docker + Kubernetes
This combination is extremely common in cloud-native workflows.
Think about the entire journey:
Source Code
↓
Docker Build
↓
Docker Image
↓
Container Registry
↓
Helm
↓
Kubernetes
↓
Running Application
Each tool solves a different problem.
Docker packages the application.
A registry stores the image.
Helm packages and configures Kubernetes resources.
Kubernetes orchestrates the workload.
Helm Dependencies
Real applications can depend on other services.
For example:
My Application
│
├── PostgreSQL
├── Redis
└── Message Queue
Helm supports chart dependencies.
Your chart can define dependencies in its configuration.
Conceptually:
Application Chart
│
├── Database Chart
├── Redis Chart
└── Other Dependency
This can make complex application deployments easier to package and manage.
However, you should still understand what you're deploying instead of treating dependencies as magic.
Helm Hooks
Helm also supports hooks.
Hooks can allow certain resources or jobs to run at particular stages of a release lifecycle.
For example, you might have a migration job that needs to run during a deployment.
Conceptually:
Helm Upgrade
↓
Migration Job
↓
Application Deployment
Hooks are powerful, but they should be used carefully because they can introduce deployment complexity.
Helm Templates Can Become Complicated
Here's an important warning.
Helm is powerful.
But it's possible to write terrible Helm charts.
You can end up with:
{{ if }}
{{ range }}
{{ with }}
{{ include }}
{{ tpl }}
{{ required }}
{{ default }}
nested inside each other until nobody knows what's happening.
Don't optimize for clever YAML.
Optimize for:
Readable configuration.
A good Helm chart should be understandable by another engineer.
Useful Helm Commands
Here are some commands worth knowing.
List releases
helm list
Install a chart
helm install my-app ./my-app
Upgrade
helm upgrade my-app ./my-app
Uninstall
helm uninstall my-app
Show release history
helm history my-app
Roll back
helm rollback my-app 1
Render templates locally
helm template my-app ./my-app
This last command is particularly useful.
It lets you see the Kubernetes YAML Helm will generate before you deploy it.
Debugging Helm
Suppose your deployment isn't behaving as expected.
Don't immediately blame Kubernetes.
First inspect what Helm rendered.
Run:
helm template my-app ./my-app
You can also use:
helm lint ./my-app
This checks the chart for common issues.
Then inspect the release:
helm get all my-app
And finally inspect the actual Kubernetes resources:
kubectl get pods
kubectl describe pod <pod-name>
kubectl logs <pod-name>
A useful troubleshooting chain is:
Helm Values
↓
Helm Template
↓
Rendered YAML
↓
Kubernetes Resource
↓
Pod
↓
Application
Find where the problem actually appears.
Helm Is Not a Replacement for Kubernetes
This is an important distinction.
Helm doesn't replace Kubernetes.
It helps you package and manage Kubernetes resources.
Think:
Kubernetes
↓
Runs and manages workloads
while:
Helm
↓
Packages and configures Kubernetes applications
They solve different problems.
A Real-World Project
If you're learning Helm, build this project:
Deploy a Three-Tier Application
Architecture:
Internet
│
▼
Ingress
│
▼
Frontend
│
▼
Backend
/ \
▼ ▼
Redis PostgreSQL
Create a Helm chart containing:
my-app/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-prod.yaml
└── templates/
├── frontend.yaml
├── backend.yaml
├── service.yaml
├── ingress.yaml
├── configmap.yaml
└── secret.yaml
Then deploy:
Development
↓
Helm
↓
Kubernetes
and:
Production
↓
Helm
↓
Kubernetes
Same chart.
Different values.
That's the real power of Helm.
The Kubernetes + Helm Learning Path
If you're serious about Kubernetes, I recommend learning Helm after you understand the Kubernetes fundamentals.
A good progression is:
Linux
↓
Networking
↓
Docker
↓
Kubernetes Basics
↓
Pods
↓
Deployments
↓
Services
↓
ConfigMaps & Secrets
↓
Volumes
↓
Ingress
↓
RBAC
↓
Helm
↓
CI/CD
↓
GitOps
↓
Production Kubernetes
Don't rush to Helm before understanding the resources Helm is generating.
When you understand Kubernetes first, Helm becomes much easier.
Want to Learn Kubernetes and Helm?
I've created a CKA Complete Study Guide — Certified Kubernetes Administrator for learners who want a structured path through Kubernetes administration and practical concepts.
It covers the kind of knowledge you need to move from:
Kubernetes Beginner
↓
Core Concepts
↓
Cluster Administration
↓
Troubleshooting
↓
Advanced Kubernetes
↓
CKA Preparation
📘 Get the CKA Complete Study Guide
If you're building a Cloud/DevOps career, I recommend combining the Kubernetes book with hands-on labs.
Don't just read:
Read → Practice → Break → Troubleshoot → Repeat
That's how Kubernetes knowledge sticks.
More Resources for Your DevOps Journey
If you're building your complete DevOps toolkit, you can also check out:
🐳 Docker Mastery
🏗️ Terraform Associate Crash Course
🔀 Git Mastery
☁️ DevOps Complete Pack
🐹 Mastering Go
Final Thoughts
Helm becomes much easier once you understand the problem it solves.
Without Helm:
Many YAML files
↓
Manual configuration
↓
Environment-specific duplication
↓
Harder maintenance
With Helm:
Chart
↓
Templates
↓
Values
↓
Release
↓
Kubernetes
The important thing isn't memorizing:
helm install
helm upgrade
helm rollback
The important thing is understanding:
What is the chart?
What is a release?
Where do values come from?
How are templates rendered?
What YAML does Helm actually generate?
How does Kubernetes use that YAML?
Once you understand that flow, Helm stops feeling like another complicated DevOps tool.
It becomes what it really is:
A practical way to package, configure, deploy, and manage Kubernetes applications.
And if you're serious about Kubernetes administration and CKA preparation, check out:
📘 CKA Complete Study Guide — Certified Kubernetes Administrator
Don't just learn Kubernetes commands. Understand the system behind them. Build it. Deploy it. Break it. Fix it. Then automate it.
Top comments (0)