⎈ Helm Lektion 4/12 ~8 Min. Fortgeschritten

Repositories und Chart-Publishing

Charts finden, hosten und versionieren.

📝 Meine Notizen

Lernziele

Nach dieser Lektion weißt du, was ein Chart-Repository technisch ist — ein HTTP-Server mit index.yaml —, kannst Charts mit helm package paketieren und ein eigenes Repository veröffentlichen. Du verstehst, warum Chart-Versionen SemVer folgen müssen, wie Konsumenten Versionen pinnen, und kannst einordnen, warum klassische Repositories zunehmend von OCI-Registries abgelöst werden.

Das Problem: Wie kommt ein Chart zu seinen Nutzern?

Du hast ein Chart gebaut (Lektion 2) und lokal installiert. Jetzt sollen es fünf andere Teams nutzen, deine CI soll eine bestimmte Version deployen, und in sechs Monaten will jemand nachvollziehen, welche Chart-Version damals in Produktion lief. „Liegt im Git-Repo, Ordner charts/” beantwortet keine dieser Anforderungen sauber: keine unveränderlichen Versionen, kein definierter Bezugskanal, keine Möglichkeit, helm install my-chart --version 1.2.3 zu sagen.

Dafür gibt es Chart-Repositories — denselben Mechanismus, über den du in den letzten Lektionen Bitnami-Charts bezogen hast, nur diesmal aus der Perspektive des Herausgebers.

Anatomie eines Repositories: HTTP-Server plus index.yaml

Ein klassisches Chart-Repository ist bewusst primitiv: ein beliebiger HTTP-Server, der .tgz-Archive und eine index.yaml ausliefert. Die index.yaml ist das Inhaltsverzeichnis — pro Chart alle verfügbaren Versionen mit Beschreibung, Digest und Download-URL.

Was bei helm repo add und Co. wirklich passiert:

  • helm repo add myrepo https://example.com/charts speichert nur Name und URL lokal.
  • helm repo update lädt die index.yaml aller Repositories in den lokalen Cache.
  • helm search repo nginx durchsucht diesen Cache — nicht das Netz.
  • helm install app myrepo/mychart --version 1.2.3 schlägt die Download-URL im Cache nach und lädt das .tgz.

Daraus folgt eine wichtige Konsequenz: Wenn helm search repo eine frisch veröffentlichte Version nicht findet, ist fast immer der Cache veraltet — helm repo update fehlt. Weil ein Repository nur statische Dateien sind, kannst du es fast überall hosten: GitHub Pages, ein S3-Bucket, ein nginx. ChartMuseum war lange der dedizierte Repository-Server mit Upload-API; für neue Setups ist der Weg über OCI-Registries (Lektion 10) inzwischen die naheliegendere Wahl, weil er ohne eigene Chart-Infrastruktur auskommt.

Publishing: package, index, hochladen

Der Publishing-Workflow für ein klassisches Repository hat drei Schritte:

# 1. Chart paketieren → mychart-0.2.0.tgz
helm package mychart/

# 2. index.yaml erzeugen bzw. aktualisieren
mkdir -p repo && mv mychart-0.2.0.tgz repo/
helm repo index repo/ --url https://example.com/charts

# 3. Inhalt von repo/ auf den Webserver laden

Wichtig bei Schritt 2: helm repo index überschreibt eine vorhandene index.yaml. Wenn du zu einem bestehenden Repository nur eine neue Version hinzufügen willst, brauchst du --merge:

helm repo index repo/ --url https://example.com/charts --merge repo/index.yaml

Sonst verschwinden alle alten Versionen aus dem Index — ein klassischer Publishing-Unfall, der bei Konsumenten als „Chart-Version plötzlich nicht mehr auffindbar” aufschlägt. In der Praxis übernimmt diesen Workflow fast immer die CI; für GitHub-basierte Repositories ist die chart-releaser-Action ein etabliertes Werkzeug, das Pakete als GitHub-Releases ablegt und die index.yaml auf GitHub Pages pflegt.

Versionierung: SemVer als Vertrag

Die Chart-version aus Chart.yaml ist im Repository die Identität des Artefakts — und sie muss SemVer folgen (MAJOR.MINOR.PATCH). Das ist mehr als Formalie, es ist ein Vertrag mit den Konsumenten:

  • PATCH (0.2.0 → 0.2.1): Bugfix im Template, keine Änderung an der Values-Schnittstelle.
  • MINOR (0.2.1 → 0.3.0): neue, abwärtskompatible Möglichkeiten — z. B. ein neuer optionaler Value.
  • MAJOR (0.3.0 → 1.0.0): Breaking Change — ein Value wurde umbenannt, ein Default geändert, eine Ressource entfernt.

Konsumenten verlassen sich darauf, wenn sie Versionsbereiche angeben — etwa version: "~0.2.0" in den Dependencies eines anderen Charts (Lektion 8) oder beim Pinnen in der CI. Zwei Regeln machen ein Repository vertrauenswürdig: Eine einmal veröffentlichte Version wird nie verändert (wer 0.2.0 überschreibt, macht Builds unreproduzierbar und bricht Digest-Prüfungen), und jede inhaltliche Änderung bumpt die Version. In der CI gehört deshalb auf Konsumentenseite immer --version an den Install-Befehl — ohne Pin nimmt Helm die neueste Version, und dein Deployment ändert sich, ohne dass sich an deinem Code etwas geändert hat.

Praxis: ein lokales Repository bauen und konsumieren

Ein Repository ist nur ein Webserver mit statischen Dateien — das kannst du komplett lokal nachstellen:

# Chart bauen und in zwei Versionen paketieren
helm create mychart
helm package mychart/ -d repo/

# Version bumpen und erneut paketieren:
# in mychart/Chart.yaml "version: 0.1.0" auf "version: 0.2.0" ändern, dann:
helm package mychart/ -d repo/

# Index erzeugen und Repository ausliefern
helm repo index repo/ --url http://localhost:8080
python3 -m http.server 8080 --directory repo/ &

# Als Konsument: hinzufügen, suchen, gepinnt installieren
helm repo add local http://localhost:8080
helm repo update
helm search repo local/mychart --versions
helm install demo local/mychart --version 0.1.0

# Aufräumen
helm uninstall demo
helm repo remove local
kill %1

Wirf dabei einen Blick in repo/index.yaml: Du siehst beide Versionen mit urls und digest — mehr Magie steckt nicht dahinter. Und helm search repo --versions zeigt dir, dass standardmäßig nur die neueste Version gelistet wird; ohne --versions übersiehst du ältere Stände.

Typische Stolperfallen

Veralteter Repo-Cache: „Die Version existiert, aber Helm findet sie nicht” — in neun von zehn Fällen fehlt helm repo update. Such-Ergebnisse kommen aus dem lokalen Cache, nicht vom Server.

helm repo index ohne --merge: Überschreibt den Index und löscht alle alten Versionen aus dem Inhaltsverzeichnis. Die .tgz-Dateien liegen noch da, sind aber nicht mehr auffindbar.

Veröffentlichte Versionen überschreiben: Ein neues 0.2.0 über das alte zu legen, ändert den Digest und macht jeden reproduzierbaren Build zur Lüge. Version vergessen zu bumpen? Dann eben 0.2.1 veröffentlichen.

Installation ohne --version in der CI: Ohne Pin installiert die Pipeline „latest aus dem Index” — ein fremdes Chart-Release kann dein Produktionsdeployment ändern. Version pinnen und Upgrades als bewussten, getesteten Schritt behandeln.

Interview-Vorbereitung

Auf „Wie funktioniert ein Helm-Repository?” antwortest du am stärksten mit der Entzauberung: ein HTTP-Server mit .tgz-Archiven und einer index.yaml als Inhaltsverzeichnis; helm repo update synchronisiert den lokalen Cache, gegen den search und install arbeiten. Dann der Publishing-Flow (packagerepo index --merge → Upload) und ein Satz zur Einordnung: ChartMuseum und statische Repos sind der klassische Weg, OCI-Registries der modernere — Details dazu in Lektion 10.

Wahrscheinliche Follow-ups:

  • „Warum müssen Chart-Versionen SemVer folgen?” — Konsumenten pinnen und nutzen Versionsbereiche; SemVer kommuniziert, ob ein Upgrade gefahrlos ist.
  • „Was passiert bei helm repo update?” — die index.yaml aller Repos wird neu in den lokalen Cache geladen; sonst nichts.
  • „Wie würdest du ein internes Chart-Repository hosten?” — statisch (GitHub Pages, S3) für Einfachheit oder die vorhandene Container-Registry per OCI; entscheidend sind Zugriffskontrolle und CI-Integration.
  • „Darf man eine veröffentlichte Chart-Version ersetzen?” — nein: Reproduzierbarkeit und Digests; stattdessen neue Version veröffentlichen.

Zusammenfassung

Ein klassisches Chart-Repository ist ein HTTP-Server mit index.yaml und .tgz-Archiven; helm repo add/update pflegen einen lokalen Cache, gegen den gesucht und installiert wird. Publishing heißt helm package, helm repo index --merge und Hochladen — typischerweise per CI. Chart-Versionen sind SemVer, unveränderlich und werden von Konsumenten gepinnt. OCI-Registries lösen dieses Modell zunehmend ab, weil Charts dort die Infrastruktur der Container-Images mitnutzen.

Damit ist der Grundlagen-Block komplett: Du kannst Charts verstehen, installieren, zurückrollen und verteilen. Die nächste Lektion öffnet die Template-Engine — Values, Go-Templates und die Funktionen, mit denen aus Platzhaltern echte Manifeste werden.