Helm Charts für Platform-Teams: Standards statt Wildwuchs
Chart-Design, Values, OCI und Review-Prozesse.
von PlatPrep
“Habt ihr ein internes Helm Chart?” In neun von zehn Fällen lautet die Antwort: “Ja, irgendwo gibt es das.” Was sich dahinter verbirgt, ist meistens ein gewachsenes Chart, das irgendwann vor zwei Jahren jemand gebaut hat, seitdem sieben verschiedene Teams daran gedoktert haben, und dessen values.yaml inzwischen 180 Zeilen lang ist.
Das ist kein Helm-Problem. Das ist ein Design-Problem.
Library Charts: einmal definieren, überall durchziehen
Library Charts (type: library in der Chart.yaml) sind der Weg, gemeinsame Templates zu konsolidieren, ohne dass jedes Team seine eigene Deployment-YAML-Variante pflegt. Du definierst Named Templates — etwa ein platform.deployment, das Standard-SecurityContext, Resource-Struktur und Probe-Setup mitbringt — und Teams binden das Library Chart als Dependency ein:
# Chart.yaml im Team-Chart
dependencies:
- name: platform-lib
version: "2.x"
repository: oci://harbor.example.com/platform/charts
# templates/deployment.yaml im Team-Chart
{{ include "platform.deployment" . }}
Änderst du den SecurityContext-Default zentral, zieht das beim nächsten Release überall durch. Der Haken, den man kennen muss: Es zieht eben erst beim nächsten Release durch. Teams, die ihre Dependency auf 2.3.1 gepinnt haben und nie aktualisieren, laufen monatelang mit alten Defaults. Ohne automatisierte Dependency-Updates — Renovate kann Helm-Dependencies in Chart.yaml bumpen — verkommt das Library-Chart-Modell zur Illusion von Zentralität.
Schema-Validierung: Fehler vor dem Deploy statt im Pod
Ein values.schema.json im Chart-Verzeichnis lässt Helm bei install, upgrade und lint validieren, ob Pflichtfelder gesetzt sind und Typen stimmen:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"required": ["image", "team"],
"properties": {
"replicas": { "type": "integer", "minimum": 1 },
"team": { "type": "string", "pattern": "^[a-z0-9-]+$" }
}
}
Der Unterschied im Alltag ist enorm: Statt eines Pods, der mit einem kryptischen Fehler crasht, weil team fehlte und damit ein Label leer blieb, bekommt das Team sofort eine lesbare Fehlermeldung — bevor irgendetwas im Cluster landet. Das Schema ist nebenbei auch Dokumentation: Es beantwortet die Frage “welche Values gibt es überhaupt?” verbindlicher als ein veraltetes README.
OCI statt Chart Museum
helm push direkt zu Harbor oder ECR ist inzwischen Standard (OCI-Support ist seit Helm 3.8 stabil). Du brauchst keinen eigenen ChartMuseum-Dienst mehr, Versionierung und Zugriffskontrolle laufen über die Registry — genau wie bei Container-Images, inklusive derselben Robot Accounts und Scan-Infrastruktur. Teams pinnen auf eine Version oder lassen Renovate Updates vorschlagen. In GitOps-Setups referenzieren Argo CD und Flux OCI-Charts direkt; ein separater Helm-Repo-Index entfällt.
Die Monster-Chart-Falle
Wo Platform-Teams gern reintappen: ein Chart bauen, das alle Use Cases abdeckt. Ingress optional, HPA optional, Sidecar optional, beliebige Custom Annotations. Jede Team-Anfrage führt zu “können wir noch eine Option hinzufügen?”, und nach einem Jahr versteht niemand mehr, welche Kombinationen überhaupt getestet sind. Die values.yaml wird zum API-Vertrag mit hunderten Feldern — und jedes Feld ist ein Versprechen, das du nie wieder brechen kannst, ohne Teams zu brechen.
Besser: getrennte, schlanke Charts pro Workload-Typ. Eines für HTTP-Services, eines für Background-Worker, eines für CronJobs. Jedes mit klaren Defaults und minimalem Interface. Die Faustregel: Wenn 80 Prozent der Teams ein Feld nie anfassen, gehört es nicht in die Values, sondern fest ins Template. Teams mit wirklich exotischen Anforderungen nutzen Kustomize als Post-Renderer (helm install --post-renderer) — dann bleibt der Sonderfall beim Team, statt das Chart für alle aufzublähen.
Testen, bevor es ein Team trifft
Drei Schichten haben sich bewährt, jede billig:
helm template plus Schema-Lint in der Chart-CI fängt Syntax- und Typfehler. helm-unittest testet Template-Logik gezielt — etwa dass bei ingress.enabled: false wirklich kein Ingress gerendert wird. Und ct (chart-testing) installiert das Chart bei jedem PR in einen Wegwerf-Cluster (kind) und prüft, ob die Release-Pipeline durchläuft. Dazu helm test als Smoke-Test nach dem Deployment: ein Pod, der prüft, ob der Service antwortet, kombiniert mit --wait. Das klingt nach viel Apparat, ist aber einmal aufgesetzt und verhindert die teuerste Fehlerklasse: ein Chart-Release, das vierzig Teams gleichzeitig kaputtmacht.
Versionierung ist Kommunikation
Semantic Versioning, Changelogs, eine klare Breaking-Change-Policy — Teams, die auf Major-Versionen pinnen, müssen rechtzeitig wissen, was sich ändert. Ein bewährtes Muster: Breaking Changes nur in Major-Releases, angekündigt im Platform-Changelog, mit Migrationshinweis und einer Übergangsfrist, in der die alte Major-Version noch Patches bekommt. Das ist mehr Prozess als Technik, aber genau dieser Teil entscheidet, ob App-Teams dem zentralen Chart vertrauen oder anfangen, es zu forken — und ein geforktes Golden-Path-Chart ist der Anfang vom Wildwuchs, den du eigentlich loswerden wolltest.
Wenn du Helm von Grund auf sauber lernen willst, inklusive Templating und Release-Mechanik: Lernpfad Helm.