Helm Cheatsheet

Helm CheatsheetAlle Kapitel

Helm Cheatsheet im Volltext

Stand Helm 4.3 · Edition 2026.11

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.