helm template und Debugging
Charts lokal rendern ohne Installation.
Lernziele
Nach dieser Lektion hast du einen systematischen Debugging-Workflow für Charts: helm lint für statische Prüfungen, helm template zum lokalen Rendern, --debug für den Blick auf kaputtes YAML und helm install --dry-run für die Probe gegen den echten Cluster. Du kannst die häufigsten Fehlerbilder — YAML-Parse-Fehler, Nil-Pointer, Einrückungsfehler — schnell ihrer Ursache zuordnen und weißt, wie du bei einem bereits installierten Release nachsiehst, was wirklich deployt wurde.
Das Problem: Der Fehler zeigt sich erst im Cluster
Templates haben eine unangenehme Eigenschaft: Sie sehen wie YAML aus, sind aber keins — erst das Rendering erzeugt YAML, und erst die Kubernetes-API bewertet, ob daraus gültige Ressourcen werden. Wer ein Chart ändert und direkt helm upgrade gegen Staging fährt, verlagert die Fehlersuche an den teuersten Ort: Ein Tippfehler in einem nindent fällt dann als fehlgeschlagenes Upgrade auf, womöglich mit halb angewendeten Ressourcen.
Die Lösung ist eine Pipeline aus immer schärferen Prüfungen, von billig nach teuer: lint → lokal rendern → gegen den Cluster trocken laufen. Jede Stufe fängt eine eigene Fehlerklasse.
Stufe 1: helm lint — die statische Prüfung
helm lint ./mychart
helm lint ./mychart -f values-prod.yaml
helm lint prüft Chart-Struktur und Konventionen (fehlende Pflichtfelder in Chart.yaml, fehlende Icons als Info, problematische Muster) und rendert dabei die Templates — Render-Fehler tauchen also auch hier auf. Es meldet drei Schweregrade: ERROR (Chart unbrauchbar), WARNING und INFO. Wichtig fürs Erwartungsmanagement: Lint validiert nicht, ob deine Manifeste gültige Kubernetes-Ressourcen sind — ein Deployment mit replicas: "drei" geht durch. Lint gehört trotzdem als erster, schneller Check in jede CI-Pipeline.
Stufe 2: helm template — rendern, ohne den Cluster anzufassen
Das Arbeitspferd beim Chart-Entwickeln:
helm template my-release ./mychart -f values-prod.yaml | less
helm template rendert vollständig clientseitig — kein Cluster nötig, nichts wird installiert. Damit beantwortest du die wichtigste Frage beim Templating überhaupt: Was kommt eigentlich raus? Zwei Flags machen es präzise:
# Nur eine Datei rendern statt des ganzen Charts
helm template my-release ./mychart --show-only templates/deployment.yaml
# Bei Render-Fehlern: das fehlerhafte YAML trotzdem ausgeben
helm template my-release ./mychart --debug
--debug ist der Schlüssel bei YAML-Parse-Fehlern: Ohne das Flag sagt dir Helm nur „YAML parse error on mychart/templates/deployment.yaml: line 23” — aber Zeile 23 des gerenderten Outputs, den du nie gesehen hast. Mit --debug bekommst du das defekte YAML mit ausgegeben und kannst die Zeile direkt anschauen. Meist findest du dort einen falsch eingerückten Block (fehlendes nindent) oder den Output eines toYaml an falscher Position.
Die Grenzen von helm template musst du kennen: Es kennt keinen Cluster. .Capabilities meldet Default-Werte statt der echten Cluster-Fähigkeiten, und die lookup-Funktion (die live Ressourcen aus dem Cluster lesen kann) liefert schlicht ein leeres Ergebnis. Ein Chart, das davon abhängt, rendert lokal anders als beim echten Install.
Stufe 3: helm install —dry-run — die Probe gegen den Cluster
helm install my-release ./mychart --dry-run --debug
--dry-run simuliert die Installation: Helm rendert, kontaktiert den Cluster und prüft die Manifeste, legt aber nichts an und schreibt kein Release-Secret. Damit fängst du die Fehlerklasse, die helm template nicht sehen kann — etwa eine API-Version, die der Zielcluster nicht mehr anbietet. Dasselbe funktioniert mit helm upgrade --dry-run gegen ein existierendes Release.
Wer noch strenger validieren will, kombiniert mit Schema-Tools: helm template ./mychart | kubeconform -strict prüft das gerenderte YAML gegen die Kubernetes-Schemata — beliebt in CI-Pipelines, weil es ohne Cluster läuft und trotzdem „ist das ein gültiges Deployment?” beantwortet.
Das installierte Release sezieren: helm get
Wenn nicht das Chart, sondern ein laufendes Release das Rätsel ist, fragst du Helm, was es weiß:
helm get manifest my-release # die gerenderten Manifeste der aktiven Revision
helm get values my-release # nur die überschriebenen Values
helm get values my-release --all # inklusive Chart-Defaults
helm get manifest my-release --revision 2 # frühere Revision
Das nutzt direkt das Release-Secret aus Lektion 3 — du siehst exakt, was Helm damals an die API geschickt hat. Der Klassiker: helm get manifest mit dem Live-Zustand vergleichen (kubectl get deploy my-app -o yaml), um manuelle Änderungen am Release vorbei zu entlarven. Für den Vergleich vor einem Upgrade ist das helm-diff-Plugin verbreitet: helm diff upgrade my-release ./mychart zeigt, was sich ändern würde — ein de-facto-Standard in CI-Reviews.
Praxis: drei Fehlerbilder erzeugen und lesen lernen
Baue dir die drei häufigsten Fehler absichtlich — wer das Fehlerbild einmal gesehen hat, erkennt es im Ernstfall sofort:
helm create broken
# Fehlerbild 1: Nil-Pointer — Zugriff auf nicht existente verschachtelte Values
# In templates/deployment.yaml einfügen: {{ .Values.foo.bar }}
echo ' x: {{ .Values.foo.bar }}' >> broken/templates/deployment.yaml
helm template broken ./broken
# → "nil pointer evaluating interface {}.bar" — foo existiert nicht, .bar darauf crasht
# Gerüst zurücksetzen für das nächste Fehlerbild
rm -rf broken && helm create broken
# Fehlerbild 2: kaputte Einrückung — nindent vergessen
# In templates/deployment.yaml resources-Block ersetzen durch:
# resources: {{ toYaml .Values.resources }}
helm template broken ./broken --set resources.limits.cpu=100m
# → "YAML parse error" — jetzt mit --debug das gerenderte YAML ansehen:
helm template broken ./broken --set resources.limits.cpu=100m --debug | less
# Fehlerbild 3: gültiges YAML, ungültige Ressource
# replicas: {{ .Values.replicaCount | quote }} macht aus der Zahl einen String
helm template broken ./broken | less # rendert problemlos!
helm install broken ./broken --dry-run # erst der Cluster lehnt ab
Der dritte Fall ist der lehrreichste: helm template ist zufrieden, weil der Output syntaktisch sauberes YAML ist — dass replicas ein Integer sein muss, weiß nur die API. Genau deshalb braucht der Workflow beide Stufen.
Typische Stolperfallen
Zeilennummern falsch interpretiert: „line 23” in der Fehlermeldung meint das gerenderte YAML, nicht deine Template-Datei. Ohne --debug suchst du an der falschen Stelle.
Lokal gerendert, im Cluster anders: helm template füllt .Capabilities mit Defaults und lässt lookup leer ausgehen. Charts, die darauf bauen, müssen mit --dry-run gegen einen echten Cluster geprüft werden.
helm lint als Vollvalidierung missverstanden: Lint prüft Chart-Konventionen und Renderbarkeit, nicht Kubernetes-Korrektheit. Für die braucht es --dry-run oder Schema-Tools wie kubeconform.
Mit anderen Values debuggt als deployt: Der Fehler tritt nur mit den Prod-Values auf, gerendert wird aber mit Defaults. Immer dieselben -f- und --set-Argumente an helm template geben wie ans echte Upgrade — und bei laufenden Releases mit helm get values die tatsächlichen Werte holen.
Interview-Vorbereitung
Die typische Frage lautet „Wie debuggst du ein Helm-Chart?” — und sie zielt auf Systematik, nicht auf ein einzelnes Kommando. Starke Antwort als Eskalationskette: helm lint (statisch, CI-tauglich) → helm template, gern mit --show-only und --debug (lokales Rendern, Parse-Fehler) → helm install --dry-run (Validierung gegen die echte API) → bei laufenden Releases helm get manifest/values und das diff-Plugin. Wer dazu sagt, welche Fehlerklasse jede Stufe fängt, hebt sich deutlich ab.
Follow-ups:
- „Unterschied
helm templateundhelm install --dry-run?” — template ist rein clientseitig (kein Cluster,lookupleer,.CapabilitiesDefaults); dry-run rendert mit Cluster-Kontakt und validiert gegen die API. - „Ein Upgrade schlägt mit YAML parse error fehl — dein Vorgehen?” — mit denselben Values
helm template --debugausführen, gerendertes YAML an der genannten Zeile prüfen, meist Einrückung/nindent. - „Wie findest du heraus, was ein Release wirklich deployt hat?” —
helm get manifest, bei Bedarf mit--revision, und gegen den Live-Zustand diffen. - „Reicht
helm lintin der CI?” — als erste Stufe ja, aber ergänzt um Rendern plus Schema-Validierung (z. B. kubeconform) oder dry-run.
Zusammenfassung
Chart-Debugging ist eine Kette immer schärferer Prüfungen: helm lint fängt Struktur- und Konventionsfehler, helm template (mit --show-only, --debug) zeigt das gerenderte YAML und entlarvt Parse- und Logikfehler, helm install --dry-run validiert gegen die echte Cluster-API, und helm get manifest/values öffnet die Blackbox laufender Releases. Merke: Zeilennummern beziehen sich auf gerendertes YAML, und clientseitiges Rendern kennt weder lookup noch echte .Capabilities.
Bisher bestand jedes Chart aus genau einer Anwendung. Die nächste Lektion zeigt, wie Charts andere Charts einbinden — Dependencies, Sub-Charts und das Umbrella-Pattern.