Cheatsheet im Volltext
Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML- und CLI-Snippets. Stand: Helm v4.3 (Edition 2026.11).
Helm 4: Stand Oktober 2026
Versionen, Support-Fenster
Helm 4 ist die aktuelle Major-Version (4.0.0 am
12.11.2025, aktuell 4.3.x seit 09.09.2026, 4.4.0
geplant für 13.01.2027). Gepflegt wird nur der neueste Minor.
Charts mit apiVersion: v2 laufen unverändert;
bestehende Helm-3-Releases übernimmt Helm 4 ohne
Migrationsschritt.
Helm 3 läuft aus: 3.22.0 (09.09.2026, überwiegend Dependency- und K8s-Client-Updates) war der letzte Minor, Security-Fixes bis 10.02.2027, danach EOL.
Skew n-3 zur einkompilierten K8s-Version: 4.3 und 3.22 → 1.37 bis 1.34, 4.2 → 1.36 bis 1.33. Neuere Cluster als die einkompilierte K8s-Version: ohne Garantie.
Breaking Changes 3 auf 4
--atomic → --rollback-on-failure,
--force → --force-replace (alte
Flags funktionieren mit Deprecation-Warnung).
--post-renderer nimmt einen
Plugin-Namen, kein Executable mehr.
helm registry login akzeptiert nur noch
Domains, keine URLs.
--wait nutzt kstatus (Strategie
watcher, Informer im Namespace): RBAC braucht
list und watch auf die Ressourcentypen
des Releases, für Deployments zusätzlich
list auf ReplicaSets und Pods.
--wait=legacy pollt wie Helm 3.
Neu in Helm 4
Server-Side Apply als Default für neue Releases (Details unter Release-Lifecycle).
Plugin-System neu: plugin.yaml verlangt
apiVersion: v1, type
(cli/v1, getter/v1,
postrenderer/v1) und runtime
(subprocess oder WASM extism/v1);
Helm-3-Plugins laufen bis Helm 5 weiter.
Multi-Dokument-Values, eigene Template-Funktionen im Go-SDK, Content-basiertes Chart-Caching, schnellere Dependency-Auflösung.
Chart-Anatomie
Verzeichnis-Layout
Chart.yaml (Metadaten, Pflicht) ·
values.yaml (Defaults) ·
values.schema.json (optionales JSON-Schema) ·
templates/ (Manifeste + _helpers.tpl)
· charts/ (gevendorte Dependencies) ·
crds/ (CRDs, siehe Anti-Patterns).
charts/, crds/,
templates/ sind für Helm reserviert.
Chart.yaml-Kernfelder
apiVersion: v2, Standard für Helm 3
und 4 (v1 = Helm 2; Charts v3
experimentell, helm create erzeugt sie nur mit
HELM_EXPERIMENTAL_CHART_V3=1 und
--chart-api-version=v3).
version: SemVer des Charts, treibt Paketname, Registry-Tag und Range-Auflösung.
appVersion: Version der paketierten App, informativ.
type: application oder
library (Library-Charts rendern selbst nichts,
liefern Template-Bausteine).
apiVersion: v2
name: shop-api
version: 1.4.0 # Chart-SemVer
appVersion: "2.8.1" # App-Version, informativ
type: application
dependencies:
- name: postgresql
version: ">=16.0.0 <17.0.0"
repository: oci://registry.example.com/charts
condition: postgresql.enabled
Templating-Patterns
include, required, tpl
include rendert ein Named Template zu einem
String, der Output lässt sich pipen
(| nindent 4), anders als bei der
template-Action.
required bricht das Rendering mit eigener Fehlermeldung ab, wenn der Values-Eintrag leer ist.
tpl evaluiert Strings aus values als
Template, für konfigurierbare Templates und
.Files.Get-Inhalte.
Named Templates (_helpers.tpl)
define-Namen sind global über
Chart + Subcharts, immer mit Chart-Namen prefixen:
shop.labels statt labels. Ablage
konventionell in templates/_helpers.tpl
(Underscore-Dateien rendern kein Manifest).
{{- define "shop.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
# Verwendung: Output pipen, nicht 'template'
metadata:
labels: {{- include "shop.labels" . | nindent 4 }}
host: {{ required "host fehlt!" .Values.host }}
conf: {{ tpl (.Files.Get "conf/app.conf") . }}
Checksum-Trick
ConfigMap-Änderung rollt das Deployment nicht automatisch, Checksum-Annotation im Pod-Template erzwingt den Rollout:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
Values-Schichtung & Secrets
Präzedenz
Chart-values.yaml < Parent-Chart-Overrides <
-f-Dateien (rechts gewinnt) <
--set-json < --set <
--set-string < --set-file <
--set-literal, feste Reihenfolge unabhängig von
der Position im Aufruf.
Subchart-Values unter dem Subchart-Namen scopen;
global: ist in allen Charts sichtbar.
Beim Upgrade ersetzen neue -f/--set-Werte
die gemerkten Overrides komplett, nur ohne neue Werte
übernimmt Helm sie. --reuse-values mergt auf
die alten Werte samt alter Chart-Defaults,
--reset-then-reuse-values auf die alten Werte und die
Defaults des neuen Charts. --reset-values verwirft sie
auch ohne neue Werte.
Secrets-Strategien
Nie Klartext-Secrets in values.yaml im Git. Gängige Muster:
helm-secrets-Plugin + SOPS/age: values verschlüsselt im Repo, Entschlüsselung beim Deploy.
External Secrets Operator / Sealed Secrets: Secret-Lifecycle außerhalb des Charts, Chart referenziert nur den Namen.
CI-Injection: --set-file aus dem
Secret-Store der Pipeline, nichts landet im Repo.
helm upgrade --install shop ./shop -n shop \
-f values.yaml -f values-prod.yaml \
--set image.tag=2.8.1 \
--set-file tls.cert=./tls.crt \
--set-json 'resources={"limits":{"cpu":"1"}}'
helm get values shop -n shop # gemerkte Overrides
Release-Lifecycle
install, upgrade, rollback
helm upgrade --install ist der idempotente
Standardpfad (CI-tauglich). helm history zeigt
Revisionen, helm rollback <rel> <rev>
setzt zurück (erzeugt neue Revision).
helm get manifest|values|notes inspiziert den
Ist-Stand. --rollback-on-failure rollt
fehlgeschlagene Upgrades automatisch zurück (Install:
uninstall) und setzt ohne explizites --wait implizit
--wait=watcher.
Ab 4.3 löscht helm uninstall
nur Objekte, deren Label app.kubernetes.io/managed-by
auf Helm steht und deren Annotationen
meta.helm.sh/release-name und -namespace
zum Release passen; fremde oder nicht lesbare bleiben stehen und
werden gelistet.
Jedes helm upgrade stempelt die Metadaten neu, vor dem
Uninstall also ein Upgrade fahren, wenn Labels fehlen.
3-way merge, Server-Side Apply
Helm 3: Three-Way Strategic Merge Patch aus altem Manifest, Live-State und neuem Manifest, out-of-band-Änderungen bleiben erhalten, soweit nicht im Chart überschrieben.
Helm 4: Server-Side Apply
(Field-Ownership beim API-Server) als Default für
neue Releases. Upgrades/Rollbacks
latchen auf die bisherige Apply-Methode des
Releases (--server-side=auto); Umstellung explizit
per --server-side=true|false.
helm upgrade --install shop ./shop -n shop \ --rollback-on-failure --wait --timeout 5m helm history shop -n shop helm rollback shop 3 -n shop helm get manifest shop -n shop --revision 3 helm uninstall shop -n shop --keep-history
Hooks & Tests
Hook-Mechanik
Annotation helm.sh/hook macht ein Template zum
Hook: pre-install, post-install,
pre-upgrade, post-upgrade,
pre-delete, post-delete,
pre-rollback, post-rollback,
test.
Reihenfolge via helm.sh/hook-weight (String!,
aufsteigend). Job/Pod-Hooks blockieren bis
Completion, Fehler = Release fehlgeschlagen.
Delete-Policies, Ownership
Hook-Ressourcen gehören nicht zum Release,
helm uninstall räumt sie nicht ab.
helm.sh/hook-delete-policy:
before-hook-creation (Default),
hook-succeeded, hook-failed.
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-db-migrate"
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: registry.example.com/shop/migrate:2.8.1
Chart-Tests
Tests sind Hooks mit helm.sh/hook: test,
konventionell unter templates/tests/. Nach Deploy
ausführen: helm test <release>, der
Test-Pod muss erfolgreich terminieren (Smoke-Test gegen den
Service).
Dependencies
dependencies-Feld
Subcharts deklarativ in Chart.yaml;
helm dependency update löst Ranges auf,
lädt .tgz nach charts/ und schreibt
Chart.lock (dependency build baut
reproduzierbar aus dem Lock).
condition (z.B. redis.enabled)
schaltet Subcharts, tags bündeln mehrere,
alias instanziiert dasselbe Chart mehrfach.
dependencies:
- name: redis
version: "21.x.x"
repository: oci://registry.example.com/charts
condition: redis.enabled
- name: postgresql
version: ">=16.0.0 <17.0.0"
repository: "@internal" # Alias aus 'helm repo add'
tags: [datastores]
helm repo add internal https://charts.example.com helm dependency update ./shop # Ranges -> Chart.lock helm dependency build ./shop # exakt aus Chart.lock
OCI-Registries
Chart als OCI-Artefakt
helm push lädt das gepackte Chart in eine
OCI-Registry, Referenz mit oci://-Prefix,
ohne Chart-Namen und Tag (kommen aus
Chart.yaml). pull, install,
upgrade, show, template
akzeptieren oci:// + --version; Pinning
per Digest @sha256:.... Login in Helm 4 nur mit
Domain.
TLS: Die eMudhra-Intermediates (CVE-2026-111943) filtert Go erst ab 1.27.3/1.26.10, Helm 4.3.1 (Go 1.27.2) und 3.22.1 (Go 1.26.9) noch nicht.
helm registry login registry.example.com helm package ./shop # -> shop-1.4.0.tgz helm push shop-1.4.0.tgz oci://registry.example.com/charts helm install shop \ oci://registry.example.com/charts/shop --version 1.4.0 # immutable per Digest: helm install shop \ oci://registry.example.com/charts/shop@sha256:<digest>
Lint, Template & Diff
Validierungs-Pipeline
helm lint --strict: statische Chart-Prüfung.
helm template: Offline-Rendering, in CI gegen
Schema-Validatoren wie kubeconform pipen.
helm install --dry-run=server: rendert mit
Cluster-Zugriff (lookup funktioniert), ohne zu
installieren. --dry-run gibt gerenderte Secrets
unmaskiert aus (data base64, stringData
im Klartext), in CI-Logs --hide-secret setzen.
helm diff upgrade (Plugin): zeigt vor
dem Upgrade den Diff gegen das Manifest des letzten Release, Drift
im Cluster erst mit --three-way-merge.
Helm 4 prüft Plugin-Signaturen (.prov) per
Default, Git-URLs sind nicht prüfbar: darum das signierte
Release-.tgz installieren,
--verify=false nur als bewusste Ausnahme. Den
importierten Key per Fingerprint prüfen. Im Default-Keyring
liest Helm erst ab 4.3 auch pubring.kbx (GnuPG ab
2.1), davor --keyring auf einen binär exportierten
Keyring (gpg --export) setzen.
helm lint ./shop --strict helm template shop ./shop -f values-prod.yaml \ | kubeconform -strict -summary helm install shop ./shop --dry-run=server curl -sL https://github.com/databus23.gpg | gpg --import gpg --fingerprint EA17A2A206AFF8CD # muss lauten: # C564 5EF4 7482 257A 1F80 6D2B EA17 A2A2 06AF F8CD REL=https://github.com/databus23/helm-diff/releases helm plugin install \ $REL/latest/download/helm-diff-linux-amd64.tgz helm diff upgrade shop ./shop -f values-prod.yaml
Provenance & Signing
Signieren, Verifizieren
helm package --sign erzeugt neben dem
.tgz eine Provenance-Datei .tgz.prov
(PGP-signiert; Secret Key als Export,
gpg --export-secret-keys). Zum Prüfen liest Helm
ab 4.3 auch pubring.kbx und ASCII-armored
Keyrings.
Prüfung: helm verify chart.tgz bzw.
Installation mit --verify, die
.prov muss neben dem Chart abrufbar sein.
gpg --export-secret-keys > ~/.gnupg/secring.gpg helm package --sign --key 'release@example.com' \ --keyring ~/.gnupg/secring.gpg ./shop helm verify shop-1.4.0.tgz helm install shop shop-1.4.0.tgz --verify
Anti-Patterns
Was du nicht tun solltest
Chart-Version wiederverwenden: gleiche
version neu pushen bricht Caches und SemVer-basierte
GitOps-Ranges, pro Änderung bumpen.
Klartext-Secrets in values.yaml im Git: SOPS/helm-secrets, External Secrets oder CI-Injection nutzen.
kubectl edit am Release vorbei: Bei
SSA-Releases bricht danach jedes Upgrade mit Field-Conflict ab,
solange der Chart für das editierte Feld einen anderen Wert
setzt; --force-conflicts holt die Felder
zurück. Änderungen über values fahren.
CRDs in templates/: helm uninstall
löscht die CRD und mit ihr alle Custom Resources dieses Typs,
Schutz: helm.sh/resource-policy: keep.
CRDs in crds/ werden nur bei der Installation
angelegt, nie geupgradet
oder gelöscht, CRD-Lifecycle separat managen. Ohne
--wait (Default hookOnly) wartet Helm 4
erst ab 4.3.1, bis diese CRDs etabliert sind; vorher scheitern
Custom Resources im selben Release sporadisch an no matches
for kind.
App-Logik in Hooks: Hook-Ressourcen gehören nicht zum Release, kein Cleanup bei uninstall, delete-policy setzen, Jobs idempotent bauen.
Upgrade ohne Diff/Dry-Run in Prod:
helm diff bzw. --dry-run=server
gehören vor jedes produktive Upgrade.
Fehlende watch-RBAC (Helm 4): Auch ohne
--wait (Default hookOnly) beobachtet Helm
Hook-Ressourcen per kstatus-Informer im Namespace der
Hook-Ressourcen. Fehlen
list und watch für deren Typen,
scheitern Hooks und jede Wait-Operation, auch die implizite von
--rollback-on-failure.