Das passende Training Kubernetes Helm Training – Charts, Deployments & Praxis (2 Tage)
Dem Community-Chart fehlt ein Ingress? Dann ändere ich es nicht, sondern baue ein kleines Chart daneben
Ganz ehrlich: In meinem eigenen Cluster gibt es nur Helm-Charts. Und wenn dem Chart eines Maintainers etwas fehlt, ändere ich dieses Chart nicht. Ich baue ein zweites, kleines daneben.
Typisches Beispiel: Das Chart startet die Anwendung und legt den Service an. Ein Ingress-Objekt, mit dem ich über den IngressController auf diesen Service zugreife, bietet es nicht an. Ich brauche aber eins.
Warum ich das Original in Ruhe lasse
Die naheliegende Lösung: Chart herunterladen, das Template für den Ingress selbst ergänzen, fertig. Funktioniert. Bis der Maintainer die nächste Version veröffentlicht.
Dann musst du deine Änderung neu einpflegen. Diff lesen, Konflikte lösen, prüfen, ob das Template noch zum neuen Chart passt. Bei jedem Update. Das ist sehr mühsam, und irgendwann schiebst du das Update vor dir her, weil du es nicht anfassen willst. Dann hängst du auf einer alten Version, nur wegen drei Template-Dateien.
Mein Weg: Das Community-Chart bleibt, wie es ist. Ich ändere nur seine Values, soweit es die anbietet, und aktualisiere es wie jedes andere Chart. Was fehlt, liefert ein eigenes kleines Chart, das nur diese eine Sache enthält.
Das kleine Chart neben dem großen
Für den fehlenden Ingress sieht das so aus:
apiVersion: v2
name: monitoring-extras
version: 0.1.0 # jede Änderung: hochzählen (macht Helm nicht selbst)host: monitoring.example.org
serviceName: monitoring-server
servicePort: 80apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
spec:
ingressClassName: traefik
rules:
- host: {{ .Values.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Values.serviceName }}
port:
number: {{ .Values.servicePort }}Die Namen sind Beispiele. IngressClass und Service müssen zu deinem Cluster passen, und das kleine Chart kommt in denselben Namespace wie der Service.
Zwei Charts, zwei Releases, zwei Versionen in helm list. Ändert sich am Ingress etwas, zähle ich 0.1.0 auf 0.1.1 hoch. Das große Chart bleibt unangetastet, und sein nächstes Update läuft ohne Handarbeit durch.
Und die Grenze, die wichtigste Zeile hier: Bietet das fremde Chart die Option über seine Values, nehme ich die. Ein Chart für etwas, das ein Schalter erledigt, wäre Bürokratie im Blaumann. Nachvollziehbar bleibt es trotzdem: Auch dieses helm upgrade steht als eigene Revision in helm history.
Warum es ein Chart sein muss und kein loses Manifest
Der Einwand: „Dann leg den Ingress doch einfach per kubectl apply an." Geht. Aber ein loses Manifest hat keine Versionsnummer, die du einem anderen Team nennen könntest. Und genau die brauchst du, wenn etwas schiefgeht.
Im Helm-Training gibt es dazu eine Übung, die das besser erklärt als jede Folie. Version 0.5.1 ist drauf, alles läuft. Dann die nächste Version: helm upgrade, Enter. Und Kubernetes sagt nein.
Da hat sich im Manifest etwas geändert, das du nach dem Anlegen nicht mehr ändern darfst. Einmal gesetzt, bleibt gesetzt. Release löschen, neu installieren.
Das Spannende ist nicht der Fehler. Das Spannende ist, wie kurz die Diagnose ist: „0.5.1 läuft, ab der nächsten Version musst du neu installieren." Ein Satz, und jeder im Raum weiß Bescheid. Keiner fragt: „Welche Datei? Wer hat da dran rumgefummelt? War das vor oder nach der Mittagspause?"
Genau das meine ich mit gemeinsamer Sprache. Wenn ich mich mit einem anderen Team abstimme, weil etwas schiefläuft, dann über eine konkrete Chart-Version. Die kann jeder nachschlagen, jeder installieren, jeder mit der vorherigen vergleichen.
Einkaufszettel, Kassenbon, Kühlschrank
Jetzt kommt der Einwand: „Wir haben doch Git, da steht jede Änderung drin." Klar. Git ist der Einkaufszettel. Da steht, was du vorhast. Ob’s gekauft wurde, steht da nicht.
Helm hat den Kassenbon. helm list zeigt mir für jedes Release das Chart samt Versionsnummer. helm history zeigt die Revisionen, jede mit der Chart-Version, die dabei ausgerollt wurde. Und der Bon liegt nicht in irgendeinem Repo, sondern im Cluster selbst, als Secret im Namespace des Releases.
Einen Haken hat der Kassenbon, und den sage ich gleich dazu: Er zeigt, was Helm abgeschickt hat. Ob noch alles im Kühlschrank liegt, zeigt er nicht. Holt nachts jemand per kubectl edit was raus, steht das auf keinem Bon. Darum gibt es bei mir keine Handarbeit neben Helm. (Warum Mischen ohnehin nur Ärger macht, steht in kubectl apply oder edit.)
Für alle, die’s schwarz auf weiß wollen, das Kleingedruckte aus der Doku:
| Fakt | Stand | Quelle |
|---|---|---|
version und appVersion in der Chart.yaml | version ist Pflicht, im SemVer-Format; appVersion ist davon unabhängig und rein informativ | Helm-Doku, Charts |
Was helm history zeigt | je Revision: Zeitpunkt, Status, Chart (Name und Version), App-Version, Beschreibung | Helm-Doku, helm history (Helm 4.3) |
| Wie viele Revisionen Helm aufhebt | standardmäßig die letzten 10 je Release, einstellbar mit --history-max bei helm upgrade | Helm-Doku, helm upgrade |
| Unveränderliche Felder | Der Label-Selector eines Deployments ist in apps/v1 nach dem Anlegen unveränderlich | Kubernetes-Doku, Deployments |
Meine klare Ansage
Ein Community-Chart fasse ich nicht an. Fehlt ihm etwas, zum Beispiel der Ingress, kommt die fehlende Ressource in ein eigenes kleines Chart daneben. So übersteht jedes Update des Maintainers meine Anpassung, und ich habe für beides eine Nummer, über die zwei Teams reden können.
Die Grenze bleibt genauso klar: Erst die Values des bestehenden Charts. Nur was die nicht können, wandert in das Begleit-Chart.
Eigene Charts bauen, versionieren und mit helm history nachvollziehen, was wann lief, üben wir in meinem Kubernetes Helm Training. Die Übung mit 0.5.1 ist auch dabei.