Helm#
In the v1 notes we wrote every manifest by hand: deployments, configmaps, services, gateways. That’s fine for a handful of resources you own. It falls apart the moment you want Prometheus + Grafana + Loki - three interdependent applications that together ship hundreds of YAML lines, with version matrices between them.
Helm is the package manager for Kubernetes. Instead of raw manifests you install charts: versioned, templatized bundles that ship with sane defaults you can override. Think apt/npm, but the package installs into your cluster.
Chart Anatomy#
mychart/
├── Chart.yaml # name, version (chart version), appVersion (app version)
├── values.yaml # default configuration
├── values.schema.json # optional: JSON schema validating values
├── charts/ # subchart dependencies (vendored or pulled via dependencies)
├── crds/ # CRDs installed BEFORE templates, never upgraded/rolled back
├── templates/
│ ├── _helpers.tpl # reusable template snippets (labels, names)
│ ├── deployment.yaml
│ └── service.yaml
└── .helmignoreThings beginners usually miss:
versionvsappVersion:versionis the chart’s own version (can bump many times for the same app);appVersionis the app’s version it deploys. Pin upgrades withhelm upgrade --version <chart-version>crds/is special: CRDs there are applied before everything else on install, but Helm does not upgrade or roll them back with the rest of the chart. That’s why the Helm maintainers warn you not to manage volatile resources in itcharts/and dependencies: a chart can declare dependencies inChart.yaml(dependencies:withcondition:flags);helm dependency buildvendors them. That’s howkube-prometheus-stackpulls in grafana, alertmanager and prometheus as subcharts
Values and Their Precedence#
This is the part that bites everyone eventually. Helm merges values from multiple sources, and the precedence is fixed:
- Chart’s
values.yaml(lowest) - Each
-f my-values.yaml(later-fwins over earlier ones) - Each
--set key=valueflag (highest)
--setconvenience is a trap: values set via--setdon’t live in any file, so six months later nobody knows where the config came from.helm get values <release>shows the user-supplied values, which is your recovery tool. My rule: everything reproducible goes in a values file,--setonly for throwaway experiments.
Also note that --set has its own parsing quirks (type coercion, commas in lists, null semantics via --set key=null). For anything non-trivial, -f with a file is more honest.
To see the defaults you’re about to inherit:
helm show values prometheus-community/prometheusAnd since some charts ship a values.schema.json, bad values fail fast at install time instead of producing broken manifests.
Hooks and Weights#
Helm doesn’t just apply YAML; it also executes lifecycle actions via annotations:
metadata:
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeededTypical use: a pre-install/pre-upgrade Job that migrates a database schema before the new pods roll out. hook-weight controls ordering between hooks.
Where Does Release State Live?#
helm history, rollback and friends work because Helm stores release state in the cluster - by default as Secrets named sh.helm.release.v1.<release>.v<revision> in the release namespace. Delete those secrets and Helm forgets everything. This also means: kubectl deletions and Helm state can drift apart (see the troubleshooting notes for the helm uninstall vs kubectl delete mess this can cause).
Özet - üçlü ilişki:
- Chart = tarifeli YAML paketi (versiyonlanmış, template’li)
- Release = chart’ın cluster’a kurulmuş instance’ı (aynı chart’tan N tane olabilir)
- Values = kurulumun parametreleri (precedence sırası: chart defaults <
-f<--set) - Her
helm upgradebir revision üretir; rollback bu revision’lar üzerinden çalışır
How to Inspect a Chart Before Installing It#
Blind helm install is how people end up with 4Gi PVCs they didn’t ask for. Inspect first:
- Add the repo and refresh its index:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update- Dump the chart’s default values and read them:
helm show values prometheus-community/prometheus | lessSearch for retention, persistentVolume, resources - these are the knobs you’ll almost certainly want to override.
- Render the full manifest set locally, without touching the cluster:
helm template monitor prometheus-community/prometheus > rendered.yaml
helm templaterenders from files only; it doesn’t know what’s already in your cluster. Use it for quick reads, not final verification.
- Do the dry run, which also catches API version and namespace issues:
helm install monitor prometheus-community/prometheus --dry-run --debugHow to Install Prometheus with Custom Values#
- Install with defaults to establish a baseline:
helm install monitor prometheus-community/prometheus
kubectl get pods --watchYou should see monitor-prometheus-server running.
- Override settings the reproducible way. Create
monitor-values.yaml:
server:
persistentVolume:
size: 4Gi
retention: 7dNote the nesting:
server.persistentVolume.size- the file mirrors the chart’svalues.yamlhierarchy. A flatsize: 4Giat the top would silently do nothing.
- Apply it with
upgrade:
helm upgrade monitor prometheus-community/prometheus -f monitor-values.yaml- Prove the values took effect:
helm get values monitor
kubectl get pvcHow to Roll Back a Bad Upgrade#
- Break something on purpose - scale the server to an absurd replica count:
helm upgrade monitor prometheus-community/prometheus \
--set server.replicaCount=5 --reuse-values- Watch it hurt:
kubectl get pods -l app=prometheus
helm history monitorEach upgrade created a revision; deployed shows the active one.
- Roll back to the previous revision:
helm rollback monitor <previous-revision>
kubectl get pods --watch- Verify what’s actually deployed:
helm get values monitor
helm rollbackrestores the release state but does not revert your values files in git. Fix the file too, or your nexthelm upgradere-introduces the problem.
for more kustomize