Helm.sh
Helm.sh
In der Welt der Containerorchestrierung ist effizientes Deployment entscheidend. Der Paket-Manager Helm selbst bezeichnet sich als:
„Der beste Weg, Anwendungen für Kubernetes zu finden, zu teilen und einzusetzen“ [1]
Die Verwendung von Helm ist eng mit der Funktionsweise des Open-Source-Systems Kubernetes (K8s) verbunden. Helm fungiert als eine Abstraktionsebene für Kubernetes und zielt darauf ab, Administratoren und Entwicklern die Verwaltung, Entwicklung und Bereitstellung von Software in Kubernetes-Clustern zu erleichtern. Dabei erfordert die Vermittlung des Prinzips hinter der Paketverwaltung ein grundlegendes Verständnis von Kubernetes, welches im Folgenden vermittelt werden soll.
Kubernetes
Kubernetes treibt als System zur Orchestrierung, Bereitstellung und allgemeinen Verwaltung von containerisierten Anwendungen seit 2014 den Paradigmenwechsel zur Containerisierung von Software und deren Abhängigkeiten voran. So soll eine konsistente Bereistellung von Systemen sowie eine Portabilität über verschiedene Umgebungen erzielt werden.
Über Helm bereitgestellte Software profitiert damit von vielen leistungsfähigen nennenswerten Funktionen, die Kubernetes durch den Betrieb von Containern in einem Cluster realisiert, darunter Skalierung, Lastverteilung und allgemeine Widerstandsfähigkeit des Systems. Signifikant ist dabei nicht zuletzt der deklarative Ansatz, bei dem ein gewisser vorkonfigurierter Zielzustand beschrieben wird. Unabhängige, komponierbare Steuerungsprozesse treiben den aktuellen Zustand des Systems dabei kontinuierlich in Richtung des bereitgestellten Soll-Zustandes. [2]
Ein solches Kubernetes-Cluster besteht dabei grundlegend aus sogenannten Nodes, die auf einer oder mehreren Maschinen laufen können. Dabei fungiert einer dieser Nodes als Main Node, während die Übrigen als Worker Nodes bezeichnet werden. Der Main Node übernimmt eine allgemeine Steuerungsfunktion für die Worker Nodes und verfügt dafür über verschiedene Komponenten wie den Controller-Manager oder einen API-Server als Schnittstelle für Administratoren.

Auch die Worker Nodes verfügen über essentielle Komponenten, wobei die wichtigsten die sogenannten Pods sind. Diese Pods umfassen jeweils einen oder mehrere Container, in denen wiederum die letztendlich bereitzustellenden Anwendungen in isolierten Umgebungen laufen.
Der erreichte Endzustand dieser Konfiguration wird als Deployment bezeichnet und beschreibt nicht nur die Anzahl der laufenden Pods in den jeweiligen Nodes, sondern auch weitere Eigenschaften wie das Verhalten der Container beim Einspielen von Updates oder ähnliches.
In der Praxis sind komplexe Anwendungen oft modular aufgebaut, was die Notwendigkeit einer Kommunikation der Pods untereinander erfordert. Dafür werden die Anwendungen in den Pods über sogenannte Services abgebildet, die als eine Art Reverse-Proxy dienen und die Netzwerkkomplexität für den Entwickler abstrahieren. Der Service fungiert dann als Kommunikationsendpunkt für eine gewisse bereitgestellte Anwendung des Clusters.

Das illustrierte Beispiel zeigt den Betrieb eines Webserver und einer Datenbank in einem Kubernetes-Cluster. Potentielle Anfragen eines beliebigen Webserver-Pods sind dabei nicht an die Datenbank-Pods direkt gerichtet, sondern werden zunächst an den abstrahierenden Datenbank-Service adressiert. Dieser leitet die Anfrage letztendlich an einen verfügbaren Datenbank-Pod weiter, wobei die Auswahl des Pods von Faktoren wie der aktuellen Auslastung abhängen kann.
Damit nun auch eine Kommunikation von extern erfolgen kann, kommt zusätzlich ein sogenannter Ingress-Controller zum Einsatz. Mittels Konfiguration durch Ingress-Resourcen werden bestimmte Pfade und Hostnamen auf bereitgestellte Services abgebildet. Der Ingress-Controller realisiert damit eine Verarbeitung und Weiterleitung von Anfragen aus dem Internet, sodass die betriebenen Anwendungen auch von Clients außerhalb des Clusters addressiert werden können.

Grundkonzept von Helm.sh
Damit Kubernetes Ressourcen nicht manuell angelegt werden müssen kann Helm verwendet werden, ein auf Go basierender Paketmanager für Kubernetes. Das Ziel besteht darin, Updates und Rollbacks effizienter zu gestalten. Dafür verwendet es insgesamt drei Grundkonzepte:
Charts
Diese sind vergleichbar mit Homebrew formulaes, apt dpkg oder yum rpm Dateien. Charts sind praktisch eine Sammlung von Dateien, die eine zusammenhängende Menge von Kubernetes-Ressourcen beschreiben. Dafür gibt es zum einen die chart.yml
. Diese beinhaltet die Definition der Metadaten des Paketes, z. B. die Angabe der apiVersion
, den Namen des Charts, sowie die Beschreibung oder den Typ des Charts, etc.
Optionale Parameter sind möglich, wie zum Beispiel dependencies
, maintainers
, keyWords
oder kubeVersion
. Der Typ kann sowohl Application (Standard) oder Library sein. Letzteres beinhaltet üblicherweise keine Ressourcen-Objekte und ist nicht installierbar.
Die values.yml
stellt den zentralen Ort für Konfigurationen bereit und beinhaltet Standardwerte für Konfigurationseinstellungen. Die darin definierten Werte können anschließend innerhalb von Templates verwendet werden. Die Wortseparierung erfolgt mittels CamelCase. Eine Definition der Werte ist sowohl verschachtelt als auch flach möglich. Zudem können definierte Standardwerte überschrieben werden, um die Charts an unterschiedliche Umgebungen anpassen zu können. Dadurch wird eine hohe Flexibilität und die Wiederverwendbarkeit von Charts ermöglicht.
Die Dateien chart.yml
und values.yml
können dann jeweils für Templates verwendet werden, bspw. in einer Kubernetes deployment.yml
-Datei. Diese Templates stellen die eigentlichen Kernkomponenten eines Charts dar. Es sind Kubernetes-Manifest-Dateien, über welche dynamische Inhalte gerendert werden können. Zudem verwenden sie verschiedene Werte aus values.yml
, um spezifische Aspekte der Kubernetes-Ressourcen zu entwickeln. Als Beispiel können hier die Anzahl der Replikate aufgeführt werden. Insgesamt entsteht eine dynamische Gestaltung der Helm Charts durch die Verwendung von Templates. Dadurch kann der gleiche Chart für verschiedene Installationen mit unterschiedlichen Konfigurationen verwendet werden.
Repositories
Erstellte Helm Charts können in Repositories gespeichert werden. Diese können selbst gehostet werden, wie z. B. über das firmeninterne Nexus. Auf Wunsch kann das eigene Repository bei Artifact Hub angegeben werden. Daraufhin werden die Pakete indexiert und in der Suche angezeigt. Artifact Hub stellt dabei eine Vielzahl von vorgefertigten Charts für gängige Anwendungen zur Verfügung.
Release
Ein Release bezeichnet eine Instanz eines installierten Charts innerhalb eines Kubernetes-Clusters. Helm ermöglicht es, verschiedene Releases des selben Charts mit unterschiedlichen Konfigurationen zu verwalten.
Beispielhafter Workflow
- Der Softwareentwickler entwickelt ein Chart mit den darin enthaltenen Templates.
- Dieses wird anschließend in das firmeninterne Repository verschoben.
- Die Cluster werden von einem Administrator verwaltet. Dieser nutzt Helm, muss jedoch nicht genau wissen wie der Chart aufgebaut ist. Er muss eventuell nur wissen, welche Konfigurationen notwendig sind.
- Der Administrator kann nun per Kommandozeile der erstellte Chart herunterladen bzw. aktualisieren und in das Kubernetes-Cluster deployen. Dadurch entfällt die Notwendigkeit des manuellen Anlegens der Kubernetes-Ressourcen
- Das Deployment erfolgt über den Kubernetes-API-Server, welcher auf dem Main Node läuft und die Charts und Konfigurationen kombiniert, die zum Erstellen eines Releases benötigt werden. Aktualisierung und Deinstallation von Releases sind hierüber ebenfalls möglich.
Anwendungsbeispiel 1: Öffentliches Helm Chart
Installation von Minikube und Helm
Es gibt verschiedene Wege, um sich ein eigenes kleines lokales Kubernetes-Cluster aufzusetzen. In diesem Fall soll Minikube verwendet werden. In dieser Anleitung geht man davon aus, dass Minikube auf einem Linux System mit der x86-64 Prozessorarchitektur installiert werden soll. Auf der Minikube Website findet man weitere Anleitungen für andere Betriebssysteme und Prozessorarchitekturen. Minikube kann dann über folgende Kommandos installiert werden:
$ curl -LO \ https://storage.googleapis.com/minikube/releases/latest/minikube-linuxamd64 $ sudo install minikube-linux-amd64 /usr/local/bin/minikube
Um das Cluster hochzufahren, muss eine Container-Virtualisierungssoftware wie etwa Docker installiert sein. Das Cluster kann man dann hochfahren über die Eingabe von:
$ minikube start
Ab jetzt kann mit dem Kubernetes Cluster mithilfe des Kommandos kubectl interagiert werden, welches bei der Installation von Minikube automatisch mitinstalliert wird. Um sich von der Funktionsweise von kubectl zu überzeugen, kann folgendes Kommando ausgeführt werden, welches die Nodes, aus dem das Cluster besteht, auflistet:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready control-plane 42d v1.28.3
Zudem muss noch ein Addon auf dem Minikube Cluster aktiviert werden:
$ minikube addons enable ingress
Abschließend kann dann noch Helm über die Kommandozeile installiert werden:
$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Installation des Nextcloud Charts
Für dieses Beispiel gehen wir davon aus, dass man einen Nextcloud Server auf dem Kubernetes Cluster installieren möchte. Auf Artifact Hub bietet Nextcloud ein offizielles Nextcloud Helm Chart an. Die Seite des Charts gibt neben Installationsanweisungen auch darüber Auskunft, wie man der Chart bei der Installation konfigurieren kann. Die folgenden Schritte beschreiben chronologisch die Installation des Nextcloud Helm Charts, lassen sich aber theoretisch auch auf die Installation eines beliebigen anderen Charts übertragen.
1. Verweis auf das Nextcloud Repo anlegen
Um der Chart über Helm auf dem lokalen Cluster zu installieren, muss zunächst eine Referenz auf das Repo, in dem der Chart liegt, hinterlegt werden, damit Helm bei der Installation weiß, welches genaue Chart installiert werden soll.
$ helm repo add nextcloud https://nextcloud.github.io/helm/
"nextcloud" has been added to your repositories
2. Konfigurationsdatei anlegen
Um der Chart bei der Installation zu konfigurieren, legt man eine Datei config.yaml
an, in der die angestrebte Konfiguration über Key-Value-Paare beschrieben wird:
nextcloud: host: mynextcloud.xyz username: user01 password: password123 ingress: enabled: true ingressClass: "nginx" mariadb: enabled: true auth.username: "admin" auth.password: "1337H@xx0r" auth.rootPassword: "1337H@xx0r"
Mit dieser Konfiguration sorgt man dafür, dass der Nextcloud Server unter der Domain mynextcloud.xyz erreichbar ist und ein Benutzer mit dem Namen user01 und dem Passwort password123 angelegt wird. Da der Server auch von außen bspw. über den Browser ansprechbar sein soll, wird zusätzlich ein Ingress Objekt dazu konfiguriert. Damit die vom Server verwalteten Dateien auch nach einem Neustart des Servers noch vorhanden sind, soll neben dem Nextcloud Server abschließend noch eine MariaDB installiert werden.
3. Installation des Charts
Nun kann der Chart unter der Angabe der im vorigen Schritt erstellten Konfigurationsdatei installiert werden. Der Chart wird hierbei im demo Namespace installiert:
$ : helm -n demo install my-nextcloud nextcloud/nextcloud -f config.yaml NAME: my-nextcloud LAST DEPLOYED: Thu Jan 25 11:50:56 2024 NAMESPACE: demo STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: ...
Die Installation des Helm Charts – also das Release – trägt den gewählten Namen my-nextcloud, was man aus der Ausgabe des Kommandos erkennen kann.
Um zu sehen, was im Hintergrund auf dem Kubernetes Cluster passiert ist, lässt man sich die Pods, Ingress Objekte und Services im demo Namespace anzeigen:
$ kubectl -n demo get pods,ingress,svc NAME READY STATUS RESTARTS AGE pod/my-nextcloud-688c657846-n2jzt 1/1 Running 0 80s pod/my-nextcloud-mariadb-0 1/1 Running 0 80s NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/my-nextcloud nginx mynextcloud.xyz 192.168.49.2 80 81s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-nextcloud ClusterIP 10.100.85.36 8080/TCP 81s service/my-nextcloud-mariadb ClusterIP 10.101.116.73 3306/TCP 81s
Hier sieht man nun, dass durch die Installation des Charts Kubernetes Ressourcen angelegt wurden. So repräsentieren die zwei Pods den Nextcloud Server sowie die MariaDB Instanz. Ebenso wurde ein Ingress-Objekt erstellt, das angibt, dass der Nextcloud Server unter der angegebenen Domain zu erreichen ist. Die zwei bereitgestellten Services stellen sicher, dass die Pods im Cluster erreicht werden können. Wie man an dieser Stelle sehen kann, spiegelt der Zustand des Clusters mit den angelegten Kubernetes Ressourcen genau die Konfiguration wider, die man bei der Installation des Charts mithilfe der config.yaml
übergeben hat.
3. DNS-Eintrag anlegen
Um den Nextcloud Server über die angegebene Domain erreichen zu können, muss im letzten Schritt nur noch ein lokaler DNS-Eintrag angelegt werden, mit dem die Domain mynextcloud.xyz auf die IP-Adresse des Clusters aufgelöst wird. Die IP-Adresse des Clusters erhält man über:
$ minikube ip 192.168.49.2
Dann erstellt man einen DNS-Eintrag in der Datei /etc/hosts. Hier muss die IP-Adresse, die man aus dem Output des vorigen Commands erhält, gefolgt von der Domain mynextcloud.xyz eingetragen werden.
Ein mögliches Beispiel sieht man in der folgenden Abbildung, in der die Domain auf die IP-Adresse 192.168.49.2 auflöst.
127.0.0.1 localhost 192.168.49.2 mynextcloud.xyz
Damit ist die Installation des Nextcloud Helm Charts abgeschlossen und kann nun genutzt werden. Hierzu einfach mynextcloud.xyz im Browser eingeben.
Upgrade des installierten Nextcloud Charts
Neben der Installation ist es auch möglich, die Konfiguration eines Helm Releases nach der Installation abzuändern. Der installierte Nextcloud Server soll nun nicht mehr auf die MariaDB angewiesen sein. Dazu passt man zunächst die config.yaml
an und kommentiert den nicht mehr benötigten Teil aus:
nextcloud: host: mynextcloud.xyz username: user01 password: password123 ingress: enabled: true ingressClass: "nginx" # mariadb: # enabled: true # auth.username: "admin" # auth.password: "1337H@xx0r" # auth.rootPassword: "1337H@xx0r"
Jetzt kann man der Helm Chart mit der geänderten Konfiguration upgraden.
$ helm -n demo upgrade my-nextcloud nextcloud/nextcloud -f config.yaml Release "my-nextcloud" has been upgraded. Happy Helming! ...
Wenn man sich nun erneut die Pods und Services auf dem Cluster anzeigen lässt, so fällt auf, dass der MariaDB-Pod und der zugehörige Service verschwunden sind.
kubectl -n demo get pods,ingress,svc NAME READY STATUS RESTARTS AGE pod/my-nextcloud-69ddd8f55f-5jvhh 1/1 Running 0 113s NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/my-nextcloud nginx mynextcloud.xyz 192.168.49.2 80 8m49s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-nextcloud ClusterIP 10.100.85.36 8080/TCP 8m49s
Deinstallation des installierten Nextcloud Charts
Abschließend möchten wir das Release deinstallieren, um unser Cluster in den Ausgangszustand vor der Installation zurückzuversetzen. Dazu folgenden Command in der Kommandozeile eingeben:
$ helm -n demo uninstall my-nextcloud release "my-nextcloud" uninstalled
Mit der Deinstallation des Charts werden alle erstellten Kubernetes Ressourcen vollständig entfernt.
Anwendungsbeispiel 2: Eigenes Helm Chart
Scenario
Wir arbeiten in einem Unternehmen und haben die Aufgabe jeder Abteilung des Unternehmens zu ermöglichen eine eigene Website auf dem Kubernetes-Cluster bereitzustellen. Hierzu erstellen wir ein Helm Chart, welches unternehmensintern bereitgestellt wird.
Der Helm Chart
Der folgende Helm Chart erstellt einen NGINX Server, welcher eine einfache HTML Website darstellt. Die Domain der Website und der Inhalt können dabei von der installierenden Person konfiguriert werden. So kann jede Abteilung mit demselben Helm Chart individuelle Webseiten bereitstellen.
Dateien:
department-website-chart/ app-chart/ templates/ configmap.yaml deployment.yaml ingress.yaml service.yaml Chart.yaml values.yaml
Ein Helm Chart besteht immer aus einer Chart.yaml
, einer values.yaml
und mehreren Template-Files.
Charts.yaml
apiVersion: v2 name: bis-app description: sample nginx deployment type: application version: 1.0 appVersion: 1.0
Hier sind die Meta-Informationen des Helm Charts festgehalten, wie Name und Version unseres Charts.
Weitere Infos: https://helm.sh/docs/topics/charts/#the-chartyaml-file
values.yaml
host: department1.local department: "department1" message: "Welcome on our website!" replicas: 1
Hier werden alle variablen Konfigurationen unseres Helm Charts mit zugehörigen Default-Werten festgehalten. Die hier aufgelisteten Parameter können beim Installieren und beim Upgraden des Helm Charts für den entsprechenden Use-Case überschrieben werden.
templates/configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-nginx-config data: nginx.conf: | events { worker_connections 1024; } http { server { listen 80; location / { return 200 "Greeting from Department {{ .Values.department }}! {{ .Values.message }}"; } } }
Die Templates im Ordner templates enthalten die jeweiligen Kubernetes Ressources, welche durch den Helm Chart angelegt werden.
Eine ConfigMap ist ein Kubernetes-Objekt, welches Konfigurationen beinhaltet, die von anderen Kubernetes-Objekten genutzt werden können.
In diesem Beispiel benutzen wir die ConfigMap für unsere NGINX Konfiguration.
Mit {{ .Values.department }}
und {{ .Values.message }}
greifen wir hier auf die Werte unserer Einträge aus der values.yaml
zu. Beim Installieren werden die vom Nutzer festgelegten Values (bzw. die Default-Values vom Nutzer nicht überschrieben) an die entsprechenden Stellen eingesetzt.
Neben den values können noch auf weitere Werte zurückgegriffen werden, wie z.B. {{ .Release.Name }}
welches uns den bei der Installation festgelegten Namen der Installation zurückgibt.
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Release.Name }} labels: app: {{ .Release.Name }} spec: replicas: {{ .Values.replicas }} selector: matchLabels: app: {{ .Release.Name }} strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: {{ .Release.Name }} annotations: checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} checksum/values: {{ printf "%s-%s" .Values.department .Values.message | sha256sum }} spec: containers: - name: {{ .Release.Name }} image: nginx:stable ports: - containerPort: 80 volumeMounts: - name: config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf volumes: - name: config configMap: name: {{ .Release.Name }}-nginx-config
Die Deployment Kubernetes-Ressource beschreibt wie der Pod welcher unseren NGINX Container ausführt aussehen soll und wie häufig er bereitgestellt werden soll. Hier wird die zuvor definierte ConfigMap verwendet, um die NGINX Konfiguration als nginx.conf
Datei in dem Container zu erstellen.
Weitere Infos zu Deployments in der Kubernetes Dokumentation.
service.yaml
apiVersion: v1 kind: Service metadata: name: {{ .Release.Name }}-service spec: type: ClusterIP selector: app: {{ .Release.Name }} ports: - protocol: "TCP" port: 80 targetPort: 80
Die Service Kubernetes-Ressource ermöglicht es, innerhalb des Clusters mit den in der deployment.yaml
definierten Pods zu kommunizieren.
Weitere Infos zu Services in der Kubernetes Dokumentation.
ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ .Release.Name }}-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: rules: - host: {{ .Values.host }} http: paths: - path: / pathType: Prefix backend: service: name: {{ .Release.Name }}-service port: number: 80
Der Ingress beschreibt eine Route, über die von extern auf den zuvor definierten Service zugegriffen werden kann. Ein Ingress-Controller sammelt alle Ingress-Ressourcen in einem Cluster und leitet eingehende Anfragen anhand dieser Regeln weiter.
In unserem Fall sagen wir, dass alle Anfragen an den Host, welcher in der values.yaml
hinterlegt ist (über host: {{ .Values.host }}
), an den Service, den wir in templates/service.yaml
definiert haben, weitergeleitet werden.
Weitere Infos zu Ingress und Ingress-Controllern in der Kubernetes Dokumentation.
Helm Chart bereitstellen
Damit der Helm Chart von den Abteilungen unseres Unternehmens genutzt werden kann, müssen wir diesen den Helm Chart zunächst bereitstellen.
Hierzu erstellen wir zunächst einen neuen Ordner charts
department-website-chart/ app-chart/ … charts/
In diesem Ordner führen wir in der Konsole folgenden Befehl aus:
$ helm package app-chart -d charts Successfully packaged chart and saved it to: charts/bis-app-1.tgz
Die erstellte Datei bis-app-1.tgz
(die 1 im Namen ist die Version des Charts) enthält den gesamten Helm Chart und kann so nun an einzelne Personen im Unternehmen verteilt werden.
Gehen wir davon aus, wir haben unser Helm Chart erweitert. Dann erhöhen wir die Version des Charts in der Charts.yaml
Datei, z.B. auf 1.1 (version: 1.1). Nun müssen wir den Chart erneut packen.
$ helm package app-chart -d charts Successfully packaged chart and saved it to: charts/bis-app-1.1.tgz
Diese neu erstellte Datei müssten wir nun erneut an alle Personen im Unternehmen verteilen, welche bereits eine frühere Chart Version installiert haben. Diese manuelle Verteilung des Charts ist jedoch unpraktisch und sorgt dafür, dass alte Chart Versionen eventuell nicht geupdatet werden. Auch bei der Verwendung von CI/CD ist ein manuelles Verteilen der Releases nicht möglich. Daher möchten wir uns Helm-Repositories als eine bessere Lösung anschauen, um Charts bereitzustellen.
Hierzu indizieren wir zunächst den chart
Ordner
$ helm repo index charts
Wir erhalten die Datei charts/index.yaml
apiVersion: v1 entries: bis-app: - apiVersion: v2 appVersion: "1" created: "2024-01-23T13:46:16.938718324+01:00" description: sample nginx deployment digest: c964f1a73aa1920286359578496a52341b77d4d226ad32cd6dfdb421c59fd4cb name: bis-app type: application urls: - bis-app-1.1.tgz version: "1.1" - apiVersion: v2 appVersion: "1" created: "2024-01-23T13:46:16.939021608+01:00" description: sample nginx deployment digest: 552c9bdf46b657dae607483912088d245c0a11b34a4ae35644c9a863ae61b10b name: bis-app type: application urls: - bis-app-1.tgz version: "1" generated: "2024-01-23T13:46:16.938178662+01:00"
Diese Datei listet alle gepackten Helm Charts in Ordner charts
inklusive deren Metainformation auf.
Der Ordner charts
kann nun mit einem beliebigen Webserver bereitgestellt und direkt als Helm Repository verwendet werden. Als schnelle und einfache Möglichkeit, Dateien über einen Webserver bereitzustellen, nutzen wir für das Beispiel Github-Pages.
Hierzu muss der Ordner in ein Github-Repository gepusht werden und für das Repository Github-Pages aktiviert werden.
Ob euer Helm Repository erreichbar ist könnt ihr überprüfen, indem ihr versucht die index.yaml
Datei von eurer Github-Page anzufragen:
$ curl https://<Username>.github.io/<repository>/charts/index.yaml
Da die Github Page öffentlich erreichbar ist, sind auch die Helm Charts öffentlich erreichbar. Unternehmensintern müsste der Webserver entweder durch Zugangsdaten abgesichert werden oder nur aus dem internen Netz erreichbar sein.
Chart installieren
Nun wollen wir den erstellten Helm Chart über das eigene Repository installieren. Hierzu müssen wir das neu erstellte Repository zunächst lokal hinterlegen.
$ helm repo add bis-repo https://<Username>.github.io/<repository>/charts/ "bis-repo" has been added to your repositories
Mit dem folgenden Befehl kann überprüft werden, welche Repositories lokal hinterlegt sind:
$ helm repo list NAME URL bis-repo https://<Username>.github.io/<repository>/charts/
Mit dem hinterlegten Repository können wir nun einen Namespace erstellen und unser Helm Chart dort installieren:
$ kubectl create ns bis namespace/bis created $ helm install bis bis-repo/bis-app -n bis NAME: bis LAST DEPLOYED: Tue Jan 23 14:09:25 2024 NAMESPACE: bis STATUS: deployed REVISION: 1 TEST SUITE: None
Der install
Befehl ist wie folgt aufgebaut
helm install <release-name> <repo>/<chart>[:<chart-version>] -n <kubernetes-namespace>
Wenn wir nun die einzelnen Kubernetes Ressourcen ausgeben, sehen wir, dass alles im Helm Chart Definierte erstellt wurde. Hier als Beispiel einmal die erstellten Pods und der Ingress.
$ kubectl get pod -n bis NAME READY STATUS RESTARTS AGE bis-6ff46c7499-24bgx 1/1 Running 0 2m17s $ kubectl get ingress -n bis NAME CLASS HOSTS ADDRESS PORTS AGE bis-ingress nginx department1.local 192.168.58.2 80 3m50s
Wenn wir nun die Website department1.local
aufrufen, bekommen wir folgende Antwort.
$ curl department1.local Greeting from Department department1! Welcome on our website!
Die angezeigte Nachricht können wir nun durch Überschreiben einiger Values unseres Helm Releases anpassen:
$ helm upgrade bis bis-repo/bis-app -n bis --set message="Greetings to BIS!" --set replicas=3 Release "bis" has been upgraded. Happy Helming! NAME: bis LAST DEPLOYED: Tue Jan 23 14:20:55 2024 NAMESPACE: bis STATUS: deployed REVISION: 2 TEST SUITE: None
Einerseits haben wir die Replicas auf 3 gesetzt. Dadurch wurden anstelle nur eines Pods nun drei Pods gestartet.
$ kubectl get pods -n bis NAME READY STATUS RESTARTS AGE bis-6d6549c7fb-b9wnh 1/1 Running 0 37s bis-6d6549c7fb-nb68f 1/1 Running 0 39s bis-6d6549c7fb-z75j4 1/1 Running 0 40s
Des Weiteren haben wir die Nachricht, welche vom Webserver zurückgegeben wird, angepasst.
$ curl department1.local Greeting from Department department1! Greetings to BIS!
Zweite Abteilung
Jetzt wollen wir das Gleiche noch einmal für eine zweite Abteilung in unserem Unternehmen umsetzen. Diese soll ebenfalls eine eigene Website bekommen, welche auf demselben Kubernetes Cluster läuft.
Hierzu erstellen wir zunächst eine neue Datei department2-values.yaml
welche die Konfiguration für unser Helm Release beinhaltet.
host: department2.local department: "department2" replicas: 2
Dann erstellen wir einen neuen Namespace und installieren den Chart für unsere Abteilung2.
$ kubectl create ns bis2 namespace/bis2 created $ helm install bis bis-repo/bis-app -n bis2 -f department2-values.yaml NAME: bis LAST DEPLOYED: Tue Jan 23 14:27:25 2024 NAMESPACE: bis2 STATUS: deployed REVISION: 1 TEST SUITE: None
Wir können nun beide Webseiten aufrufen.
$ curl department1.local Greeting from Department department1! Greetings to BIS! $ curl department2.local Greeting from Department department2! Welcome on our website!
Abschließend können wir uns von Helm noch einmal alle aktuell installierten Helm Charts anzeigen lassen
$ helm ls -A NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION bis bis 2 2024-01-23 14:20:55.470634413 +0100 CET deployed bis-app-1.1 1.1 bis bis2 1 2024-01-23 14:27:25.781652628 +0100 CET deployed bis-app-1.1 1.1
Fazit
Anhand des ersten Anwendungsbeispiels, bei dem das öffentlich zugängliche Helm Chart von Nextcloud auf einem Kubernetes Cluster installiert wurde, lassen sich einige der Vorteile, die Helm bietet, erkennen. Die Installation eines Charts entspricht dem gebündelten Deployment von Kubernetes Ressourcen. Im Gegensatz zur herkömmlichen Interaktion mit einem Cluster müssen die Kubernetes Ressourcen nicht einzeln händisch angelegt werden, sondern können über einen einzigen Helm Command schnell und einfach auf das Cluster gebracht werden. Das Gleiche gilt für den Vorgang des Löschens eines Releases bei dem alle von Helm angelegten Ressourcen gebündelt gelöscht werden. Des Weiteren kann man am ersten Anwendungsbeispiel erkennen, dass der Anwender zu keinem Zeitpunkt dazu gezwungen war, direkt mit dem Kubernetes Cluster zu interagieren. Helm schafft mit seiner Nutzerschnittstelle ein Abstraktionslevel, das den internen Aufbau und die Funktionsweise von Kubernetes vor dem Anwender versteckt. Den Entwicklern von Helm war es wichtig, dass sich Helm sowohl an mit der Funktionsweise von Kubernetes vertraute Anwender als auch an solche richtet, die über wenig bis kaum Erfahrung und technisches Wissen im Bereich von Kubernetes verfügen.
Am zweiten Anwendungsbeispiel kann man erkennen, dass Helm die Abdeckung verschiedener Anwendungsfälle mit nur einem Chart ermöglicht, wodurch die Notwendigkeit für neue Charts entfällt. Wir konnten problemlos zwei Webserver für unterschiedliche Abteilungen erstellen, indem wir lediglich Konfigurationsparameter anpassten, ohne den Code ändern zu müssen. Ein entscheidender Vorteil von Helm liegt zudem in seiner Fähigkeit, das installierte Chart zusammen mit seiner Version auf dem Cluster zu dokumentieren. Dadurch wird eine umfassende Versionsverwaltung gewährleistet, die Transparenz über den aktuellen Stand sowie potenzielle Änderungen mit einem Update oder zwischen den Deployments schafft. Diese Dokumentation ermöglicht eine klare Nachvollziehbarkeit jeder Chart Version. Des Weiteren erleichtert Helm die Reproduzierbarkeit eines bestimmten Zustands erheblich, da sowohl die Konfiguration als auch der Status des Charts als Code gespeichert werden können. Dadurch wird eine konsistente Bereitstellung und Verwaltung von Anwendungen gewährleistet, was wiederum die Zuverlässigkeit und Effizienz der Entwicklungs- und Betriebsprozesse verbessert.
Es lässt sich festhalten, dass das Deployment von Charts über Helm große Vorteile bietet. Helm trägt wesentlich dazu bei, Anwendungen auf Kubernetes Clustern einfach und schnell zur Verfügung zu stellen und spielt damit im Bereich der betrieblichen Informationssysteme eine nicht unwesentliche Rolle.
Einzelnachweise
- Was ist Kubernetes? (2022, 17. Juli). Kubernetes. https://kubernetes.io/de/docs/concepts/overview/what-is-kubernetes/
- Helm | Helm. (o. D.). https://helm.sh/
- Helm | Docs Home. (o. D.). https://helm.sh/docs/