Einleitung
Im ersten Teil haben wir gesehen, wo man einen bereits vorhanden Chart findet (Helm Hub) und wie man diesen auf einem Kubernetes Cluster installiert. Wir haben uns angeschaut, wie man eigene Konfigurationen an den Chart übergeben kann und wie man ein Upgrade und Rollback durchführt. Heute wollen wir noch einen Schritt weiter gehen und uns anschauen, wie man einen eigenen Chart erstellen kann.
Aufbau eines Chart
Wollen wir uns als erstes anschauen, wie ein Helm Chart aufgebaut ist. Am einfachsten erstellen wir uns hierfür einen eigenen Chart. Helm bietet uns einen einfachen Befehl, mit dem wir das Grundgerüst unseres eigenen Chart erstellen können.
~ ❯ helm create mychart
Creating mychart
Schauen wir uns an, was passiert ist. Es wurde ein Ordner erstellt, in dem die erforderlichen Konfigurationen liegen.
~ ❯ ls mychart
Chart.yaml charts templates values.yaml
Chart.yml
In dieser Datei befinden sich die Metadaten des Charts, wie Name, Beschreibung, Typ und Version. ApiVersion muss immer gesetzt werden und ist für Helm 3 “v2”.
~/mychart ❯ cat Chart.yaml
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
Verzeichnis: charts
Dieses Verzeichnis ist leer. Wir haben hier die Möglichkeit bereits bestehende Charts hinzuzufügen, welche für unseren Chart benötigt werden, also Abhängigkeiten. Eine weitere und von Helm bevorzugte Möglichkeit Abhängigkeiten hinzuzufügen, ist als dependencies Feld in der Chart.yaml
Datei. Wir können hier Abhängigkeiten hinzufügen und anschliessend mit dem Befehl helm dependency update
diese Abhängigkeiten in den charts Ordner herunterladen.
Für unser einfaches Beispiel brauchen wir diese Funktion aber erstmal nicht.
dependencies:
- name: apache
version: 1.2.3
repository: http://example.com/charts
- name: mysql
version: 3.2.1
repository: http://another.example.com/charts
Weitere Informationen dazu findet man auf der Helm Seite.
Verzeichnis: templates
Nun kommen wir zu dem Herzstück unseres Charts. In diesem Verzeichnis finden sich alle Konfigurationsdateien, welche wir für die Installation auf dem Kubernetes Cluster benötigen. Alle Dateien, die sich im templates Verzeichnis befinden, werden durch die Helm Template Rendering Engine gesendet. Die Ergebnisse der Templates werden gesammelt und anschliessend zu Kubernetes gesendet.
~/mychart ❯ ls templates
NOTES.txt _helpers.tpl deployment.yaml hpa.yaml ingress.yaml service.yaml serviceaccount.yaml tests
Wir sehen hier verschiedene Dateien, welche bereits von Helm für uns angelegt wurden.
-
NOTES.txt
:- Das ist der Hilfetext für einen Chart. Dieser wird dem Benutzer angezeigt, wenn er helm install ausführen
-
deployment.yaml
,service.yaml
,hpa.yaml
,ingress.yaml
,serviceaccount.yaml
:- Grundgerüste um eine Kubernetes Resource zu erstellen
-
_helpers.tpl
:- Hier befinden sich Helper für Templates, welche im Chart wiederverwendet werden können.
-
tests
:- Hier befinden sich Tests um die Funktionalität des Charts im Cluster zu verifizieren.
values.yaml
Die values.yaml
Datei ist wichtig um die Templates zu parsen. Hier befinden sich alle Default Werte, welche vom Benutzer mit helm install
oder helm upgrade
überschrieben werden können.
Mit diesem Wissen können wir nun unseren ersten eigenen Chart entwickeln.
Der erste eigene Chart
Wollen wir mit einem einfach Beispiel starten. Dafür löschen wir im Ordner templates erstmal alle Dateien, damit wir unser kleines Tutorial von Grund auf beginnen können.
rm -rf mychart/templates/*
Anschliessend erstellen wir unser erstes eigenes Template. Wir erstellen eine Datei mit dem Namen configmap.yaml
mit folgendem Inhalt:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
name: {{.Values.myName}}
In der Datei haben wir nun eine unbekannte Syntax.
{{ .Release.Name }}
und {{.Values.myName}}
. Beides sind spezielle Platzhalter, welche durch die Template Rendering Engine ersetzt werden.
{{ .Release.Name }}
wird, wie der Name schon sagt, dynamisch durch den Namen des Release ersetzt, welchen wir beim Installieren angeben.
{{.Values.myName}}
wird durch das Property myName aus der Datei values.yaml
ersetzt. Schauen wir uns dafür diese Datei einmal genauer an.
myName: b-nova
Nun haben wir bereits einen vollständig lauffähigen und installierbaren Chart. Schauen wir uns an, was bei der Installation passiert. Dafür können wir dem install Befehl das Flag --dry-run
anhängen um die Installation lediglich zu simulieren. Mit --debug
aktivieren wir “verbose” Output.
~ ❯ helm install myRelease ./mychart --dry-run --debug
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: ~/mychart
NAME: myRelease
LAST DEPLOYED: Thu Feb 4 19:07:54 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
myName: b-nova
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myRelease-configmap # <-- {{ .Release.Name }}
data:
name: b-nova # <-- {{.Values.myName}}
Wie wir sehen können wurden unsere Platzhalter wie gewünscht ersetzt. Nun können wir unseren Chart installieren. Wir wollen aber bei der Installation nicht den Default Name “b-nova” nutzen, sondern wollen einen eigenen Namen vergeben. Weiter oben haben wir bereits gesehen, dass wir die Werte durch Angabe einer eigenen values.yaml
Datei, oder durch das --set
Flag bei der Installation überschreiben können. Wir wollen an dieser Stelle die zweite Variante versuchen.
~ ❯ helm install bnova-chart ./mychart --debug --set myName=whats_my_name
install.go:173: [debug] Original chart version: ""
install.go:190: [debug] CHART PATH: /Users/swelsch/mychart
client.go:122: [debug] creating 1 resource(s)
NAME: bnova-chart
LAST DEPLOYED: Thu Feb 4 19:18:16 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
myName: whats_my_name
COMPUTED VALUES:
myName: whats_my_name
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: bnova-chart-configmap
data:
name: whats_my_name
Success! Der Chart wurde erfolgreich installiert und der Default-Name wurde mit dem dynamischen Wert ersetzt. Jetzt wollen wir noch einmal verifizieren, ob unsere ConfigMap auch wirklich richtig deployed wurde. Wir schauen also mit kubectl
direkt auf dem Cluster nach.
~/mychart ❯ kubectl get configmap
NAME DATA AGE
bnova-chart-configmap 1 4m40s
Wie wir sehen wurde die ConfigMap mit dem richtigen Namen angelegt. Schauen wir uns zur Vollständigkeit auch noch den Inhalt an.
~/mychart ❯ kubectl describe configmap bnova-chart-configmap
Name: bnova-chart-configmap
Namespace: default
Labels: app.kubernetes.io/managed-by=Helm
Annotations: meta.helm.sh/release-name: bnova-chart
meta.helm.sh/release-namespace: default
# Data
name:
----
whats_my_name
Events: <none>
Den gesamten Code findet ihr im im b-nova Github
Auch der Inhalt entspricht dem erwarteten Ergebnis. Wir haben damit erfolgreich unseren ersten Chart erstellt und auf unserem Cluster installiert.
Next Steps:
Helm Charts hat im Managed Container Umfeld eine grosse Zukunft. Wir werden die Entwicklung von Helm daher gespannt weiterverfolgen. Im nächsten TechUp will ich mit euch die folgenden Themen an einem praktischen Beispiel anschauen:
-
Monocular - das Frontend für Helm
-
Ein eigenes Repository hosten
-
Template:
-
Template Functions und Pipelines
-
Flow Control
-
Built-In Objects
-
Named Templates
-
Subcharts
-
Debugging Templates
-
Post Rendering
-
File Handling
-
-
Best practices
Viel Spass und stay tuned!