Helm Best Practices
Production-ready Charts schreiben.
Lernziele
Nach dieser Lektion kennst du die Merkmale eines produktionsreifen Charts: eine durchdachte Values-Schnittstelle mit sinnvollen Defaults und Schema-Validierung, eine hilfreiche NOTES.txt, Chart-Tests, eine Linting- und Test-Pipeline in der CI — und eine saubere Antwort auf die Frage, wie Secrets in ein Release kommen, ohne in values.yaml zu stehen.
Das Problem: Charts, die nur ihr Autor bedienen kann
Ein Chart funktioniert am Anfang fast immer — für die Person, die es geschrieben hat, mit den Values, die sie im Kopf hat. Die Bewährungsprobe kommt später: Ein anderes Team installiert es mit eigenen Werten, die CI deployt es hundertmal, jemand setzt einen Tippfehler-Value und wundert sich über ein halbkaputtes Release. Best Practices für Charts sind im Kern Antworten auf eine Frage: Wie macht man die Schnittstelle des Charts so robust, dass sie Fremdnutzung übersteht?
Die Values-Schnittstelle: Defaults, required und values.schema.json
values.yaml ist die API deines Charts (Lektion 2) — und für APIs gelten API-Regeln.
Sinnvolle Defaults: Jeder Wert, der einen vernünftigen Standard haben kann, bekommt einen — das Chart muss mit helm install demo ./chart ohne weitere Angaben etwas Funktionierendes erzeugen. Werte ohne sinnvollen Default (etwa der Hostname der Ingress) werden nicht geraten, sondern erzwungen:
host: {{ required "ingress.host muss gesetzt sein" .Values.ingress.host }}
Schema-Validierung: Eine values.schema.json im Chart-Root prüft die zusammengeführten Values bei install, upgrade, lint und template gegen ein JSON Schema — Tippfehler und Typfehler scheitern laut und früh statt leise im Manifest:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"replicaCount": { "type": "integer", "minimum": 1 },
"image": {
"type": "object",
"properties": {
"repository": { "type": "string" },
"tag": { "type": "string" }
},
"required": ["repository"]
}
},
"required": ["replicaCount"]
}
Ressourcen-Steuerung: resources (Requests/Limits) gehören als durchgereichter Block ins Chart (toYaml .Values.resources | nindent), denn sinnvolle Werte hängen von der Umgebung ab — das Chart macht sie konfigurierbar, die Values-Dateien pro Umgebung füllen sie. Ein Chart, das Limits hartkodiert oder gar nicht vorsieht, ist in Cluster mit Ressourcen-Quotas nicht installierbar bzw. nicht betreibbar.
Und eine Anti-Regel: Nicht alles templaten. Ein Value pro denkbarem Feld führt zu Charts mit hunderten Optionen, die niemand überblickt. Konfigurierbar wird, was sich zwischen Umgebungen oder Nutzern realistisch unterscheidet — für den Rest gibt es Chart-Versionen.
Secrets: was nicht in values.yaml gehört
Der häufigste Security-Fehler in Charts: Datenbank-Passwörter als Value, committet in Git, sichtbar in helm get values für jeden mit Namespace-Zugriff aufs Release-Secret. Die belastbaren Alternativen:
- External Secrets Operator: Das Chart legt eine
ExternalSecret-Ressource an, die nur referenziert, wo das Secret liegt (Vault, AWS Secrets Manager, …) — der Operator synchronisiert es in den Cluster. Das Secret selbst berührt weder Git noch Helm. - SOPS-verschlüsselte Values: Values-Dateien liegen verschlüsselt in Git und werden erst beim Deployment entschlüsselt (z. B. via
helm-secrets-Plugin oder nativ in Flux). Funktioniert, koppelt aber Schlüsselverwaltung an die Pipeline. - Vorhandene Secrets referenzieren: Das Chart erwartet per Value den Namen eines existierenden Secrets (
existingSecret-Muster, in vielen öffentlichen Charts zu sehen) — die Erzeugung ist Sache der Plattform.
Welche Variante passt, hängt vom Setup ab; gemeinsam ist allen: Der Klartext-Wert fließt nie durch values.yaml.
Vertrauen aufbauen: NOTES.txt, Tests und CI
NOTES.txt (Lektion 2) ist die Begrüßung deines Charts: Sie wird nach Install/Upgrade gerendert und angezeigt. Gut eingesetzt beantwortet sie die erste Frage jedes Nutzers — „und wie erreiche ich die Anwendung jetzt?” — dynamisch aus den Values (Ingress-Host, Port-Forward-Befehl, nächste Schritte). Eine leere oder generische NOTES.txt ist eine vertane Chance.
Chart-Tests sind Hook-Ressourcen mit helm.sh/hook: test (der test-Lifecycle-Punkt aus Lektion 9): Pods, die nach der Installation per helm test <release> ausgeführt werden und prüfen, ob das Release wirklich funktioniert — typisch ein Pod, der den Service ansprechen kann. Das helm create-Gerüst bringt unter templates/tests/test-connection.yaml ein Beispiel mit. Tests sind kein Ersatz für Monitoring, aber ein billiger Smoke-Test direkt nach dem Deployment — auch in der CI.
Die CI-Pipeline eines ernstgenommenen Charts kombiniert die Debugging-Werkzeuge aus Lektion 7: helm lint mit allen Umgebungs-Values, helm template plus Schema-Validierung (kubeconform), und für Repositories mit mehreren Charts das chart-testing-Tool (ct lint, ct install), das geänderte Charts erkennt, gegen einen Wegwerf-Cluster (z. B. kind) installiert und helm test ausführt. Dazu Versionsdisziplin: Jede Chart-Änderung bumpt version (Lektion 4), sonst bricht das Publishing.
Praxis: Schema und Test am eigenen Chart
helm create prodchart
# 1. Schema ergänzen
cat > prodchart/values.schema.json <<'EOF'
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"replicaCount": { "type": "integer", "minimum": 1 }
},
"required": ["replicaCount"]
}
EOF
# Schema in Aktion: beide Befehle schlagen fehl
helm template demo ./prodchart --set replicaCount=0
helm template demo ./prodchart --set-string replicaCount=drei
# 2. Den mitgelieferten Chart-Test ansehen und ausführen
cat prodchart/templates/tests/test-connection.yaml
helm install demo ./prodchart
helm test demo
# 3. Lint mit Umgebungs-Values als CI-Baustein
echo 'replicaCount: 3' > values-prod.yaml
helm lint ./prodchart -f values-prod.yaml
helm uninstall demo
Achte beim Schema-Test auf die Fehlermeldung: Sie nennt Feld und Regel („replicaCount: Must be greater than or equal to 1”) — genau die Sorte frühes, präzises Feedback, die ein Chart fremdnutzbar macht.
Typische Stolperfallen
Secrets in values.yaml „nur für den Anfang”: Aus dem Provisorium wird ein committetes Passwort. Von Anfang an existingSecret, External Secrets oder SOPS — nachträgliche Bereinigung heißt Git-History rewriten und Credentials rotieren.
Schema nachgerüstet, Bestand bricht: Eine strenge values.schema.json auf ein etabliertes Chart zu legen, lässt bestehende Values-Dateien mit harmlosen Extra-Feldern oder String-Zahlen durchfallen. Schema einführen heißt: Konsumenten-Values mittesten und als MAJOR-Änderung behandeln, wenn es strenger wird.
helm test ohne Aufräumen: Test-Pods sind Hook-Ressourcen — ohne hook-delete-policy sammeln sich abgeschlossene Test-Pods im Namespace. Das Gerüst setzt die Policy korrekt; eigene Tests brauchen sie auch.
Über-Templating: Jedes Feld konfigurierbar, dreifach verschachtelte Conditionals, Values-Dateien wie Romane. Die Schnittstelle klein halten — was niemand variiert, gehört fest ins Template.
Interview-Vorbereitung
Die Frage „Was macht für dich ein gutes Helm-Chart aus?” beantwortest du am stärksten über das Schnittstellen-Argument: values.yaml ist die API — sinnvolle Defaults, required für Pflichtwerte, values.schema.json als Vertrag, Ressourcen konfigurierbar. Dann Betreibbarkeit (NOTES.txt, Chart-Tests, lint/ct in der CI) und Security (keine Klartext-Secrets in Values; External Secrets oder existingSecret-Muster). Drei konkrete Mechanismen schlagen zehn Adjektive.
Follow-ups:
- „Wie validierst du Values?” —
values.schema.json(Typen, Pflichtfelder, Grenzen, wirkt bei install/upgrade/lint/template) plusrequiredim Template für kontextabhängige Pflichtwerte. - „Wie hältst du Secrets aus dem Chart raus?” — External Secrets Operator, SOPS-verschlüsselte Values oder Referenz auf ein existierendes Secret; Klartext fließt nie durch Values.
- „Wie testest du Charts in der CI?” — lint mit allen Umgebungs-Values, template + kubeconform, chart-testing mit Install in einen kind-Cluster und
helm test. - „Wann ist ein Value zu viel?” — wenn ihn kein realer Nutzer variiert; jede Option erhöht Testaufwand und kognitive Last der Schnittstelle.
Zusammenfassung
Produktionsreife Charts behandeln values.yaml als API: Defaults, die ohne Angaben funktionieren, required und values.schema.json als früher Validierungsvertrag, Ressourcen und Secrets konsequent konfigurier- statt hartkodierbar — Klartext-Secrets niemals in Values. NOTES.txt führt Nutzer zum laufenden System, Chart-Tests und eine lint/template/ct-Pipeline sichern jede Änderung ab, SemVer-Disziplin macht sie konsumierbar.
Damit hast du das gesamte Helm-Handwerk beisammen. Die letzte Lektion baut daraus deine Interview-Performance: die Standardfragen des Lernpfads im Zusammenhang, mit Antwortstrategien und Szenario-Übungen.