Helm: The Package Manager for Kubernetes
As we all know, k8s manages container resources across multiple nodes, but every container needs a corresponding pod yaml file to manage it.
What this post is really about is yaml sprawl. Writing one Deployment and one Service for a single application is no big deal, but once the cluster fills up with applications, the number of config files balloons at a visible rate: changing one image tag means digging through several files, and spinning up a new environment means copying the whole batch of configs and tweaking parameters one by one. At that point, maintaining yaml by hand is no longer realistic.
Starting from a pile of yaml
Consider the problem first: suppose a namespace has dozens of pods that need to be deployed together — a mysql cluster, a kafka cluster (which itself requires a zookeeper cluster first), a Redis cluster for the application, some MQ queue clusters, plus the application deployments themselves. With microservices, you might be looking at 50–100 applications or even more.
If someone asked you to hand-write yaml config files for a scenario like that, I suspect you'd refuse. Even if you managed to get through one deployment, what happens when the cluster in a remote data center needs to be deployed all over again? And how do you guarantee that the configuration across clusters in different data centers stays perfectly consistent?
These yaml files also carry implicit deployment ordering and plenty of duplicated settings — image registry addresses, resource quotas, storage class names — copied into nearly every file. Once a shared parameter changes, missing a single spot becomes a liability.
So the problem is clear: we need a tool that can centrally manage all the yaml config files and make them reusable.
Helm: the package manager for k8s
That's where Helm comes in. Its role is similar to the Yum package manager on CentOS, or apt on Debian — except this time the packages are for the k8s environment.
Each package in Helm is called a Chart, and a Chart is a directory. Its core contents boil down to three parts: Chart.yaml describes the package's metadata such as name and version; values.yaml holds the default configuration values, which can be overridden at install time; and the templates/ directory contains k8s resource files written with template syntax. At install time, Helm renders the values into the templates, generates the actual yaml, and submits it to the cluster. The result of one installation is called a Release.
The key to configuration reuse lies in this templating mechanism: different data centers and environments share the same Chart, each maintaining only a small values file of its own, so the problem of inconsistent configuration between data centers simply dissolves. Charts can also declare dependencies — relationships like "zookeeper must exist before kafka is deployed" can be handed off to sub-charts instead of relying on humans to remember the order.
Application publishers can use Helm to package applications, manage dependencies, manage versions, and publish applications to a software repository for unified management. When it's time to deploy on k8s, a single command brings up the entire set of pod applications.
The commands you need day to day are few:
# Add a Chart repository (using the popular bitnami repo as an example)
helm repo add bitnami https://charts.bitnami.com/bitnami
# Refresh the locally cached repository index
helm repo update
# Deploy a full application with one command; the Chart creates all required resources automatically
helm install my-mysql bitnami/mysql
# List the Releases deployed in the current namespace
helm list
Upgrades and rollbacks after deployment are also handled by Helm, with every change recorded as a new revision:
# Override the defaults with a custom values file and upgrade
helm upgrade my-mysql bitnami/mysql -f my-values.yaml
# Roll back to the previous revision if the upgrade goes wrong
helm rollback my-mysql
Helm's official site:
A graphical option: Kubeapps
The official docs are quite thorough and worth studying. On top of that, let me recommend a UI management tool for Helm that makes managing enterprise Helm packages more convenient.
kubeapps
Kubeapps is itself a web application deployed inside the cluster. From its pages you can browse Charts in your repositories, install them by filling in a form, and view or upgrade existing Releases. For teams where giving everyone command-line access to the cluster isn't practical, a tool like this saves a lot of hassle.
Pitfalls and caveats
1) Keep your custom configuration in your own values file
Prefer passing a standalone values file with -f to override defaults, rather than editing the Chart's own values.yaml. The former carries over cleanly when the Chart is upgraded; changes made the latter way are easily overwritten and lost when the Chart is updated.
2) Think before you uninstall
helm uninstall deletes all the resources associated with a Release. For stateful applications like mysql, check the storage volume retention policy before pulling the trigger, or you may wipe out the data along with everything else.
3) Chart version and app version are two different things
In Chart.yaml, version refers to the Chart's own packaging version, while appVersion corresponds to the version of the software inside. Before upgrading, be clear about which one is changing — otherwise you might think you're only tweaking templates when you're actually upgrading the application too.
Wrapping up
Helm gathers the yaml scattered everywhere into Charts, solves configuration reuse and multi-environment consistency with templates plus values, and collapses deployment, upgrade, and rollback into single commands. Hand-written yaml can hold up while things are small, but once applications multiply, adopting Helm's package management layer early saves an enormous amount of repetitive work down the road. Pair it with a UI tool like Kubeapps and the barrier for team collaboration drops considerably as well.
COMMENTS