Zum Hauptinhalt springen
Version: 3.19.0

Library Charts

Ein Library Chart ist ein spezieller Typ von Helm Chart, der Chart-Primitive oder -Definitionen bereitstellt, die von Helm-Templates in anderen Charts verwendet werden können. So lassen sich Code-Snippets über mehrere Charts hinweg gemeinsam nutzen, wodurch Wiederholungen vermieden und Charts DRY gehalten werden.

Das Library Chart wurde in Helm 3 eingeführt, um offiziell gemeinsam genutzte Charts oder Helper Charts anzuerkennen, die von Chart-Maintainern bereits seit Helm 2 verwendet werden. Durch die Definition als eigener Chart-Typ bietet es:

  • Eine Möglichkeit zur expliziten Unterscheidung zwischen gemeinsam genutzten Charts und Anwendungs-Charts
  • Logik zur Verhinderung der Installation eines gemeinsam genutzten Charts
  • Kein Rendering von Templates in einem gemeinsam genutzten Chart, die Release-Artefakte enthalten könnten
  • Die Möglichkeit für abhängige Charts, den Kontext des importierenden Charts zu nutzen

Ein Chart-Maintainer kann ein gemeinsam genutztes Chart als Library Chart definieren und sicher sein, dass Helm das Chart auf eine standardisierte und konsistente Weise behandelt. Darüber hinaus können Definitionen aus einem Anwendungs-Chart geteilt werden, indem einfach der Chart-Typ geändert wird.

Ein einfaches Library Chart erstellen

Wie bereits erwähnt, ist ein Library Chart ein spezieller Typ von Helm Chart. Das bedeutet, dass Sie mit der Erstellung eines Grundgerüst-Charts beginnen können:

$ helm create mylibchart
Creating mylibchart

Zunächst entfernen Sie alle Dateien im Verzeichnis templates, da wir in diesem Beispiel eigene Template-Definitionen erstellen werden.

$ rm -rf mylibchart/templates/*

Die Values-Datei wird ebenfalls nicht benötigt.

$ rm -f mylibchart/values.yaml

Bevor wir mit dem Erstellen von gemeinsam genutztem Code beginnen, gehen wir kurz einige relevante Helm-Konzepte durch. Ein benanntes Template (manchmal auch Partial oder Subtemplate genannt) ist einfach ein Template, das in einer Datei definiert und mit einem Namen versehen wird. Im Verzeichnis templates/ wird jede Datei, die mit einem Unterstrich (_) beginnt, nicht als Kubernetes-Manifest ausgegeben. Daher werden Hilfs-Templates und Partials üblicherweise in _*.tpl- oder _*.yaml-Dateien abgelegt.

In diesem Beispiel erstellen wir eine gemeinsam nutzbare ConfigMap, die eine leere ConfigMap-Ressource definiert. Wir definieren die gemeinsame ConfigMap in der Datei mylibchart/templates/_configmap.yaml wie folgt:

{{- define "mylibchart.configmap.tpl" -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data: {}
{{- end -}}
{{- define "mylibchart.configmap" -}}
{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}}
{{- end -}}

Das ConfigMap-Konstrukt wird im benannten Template mylibchart.configmap.tpl definiert. Es handelt sich um eine einfache ConfigMap mit einer leeren Ressource, data. In dieser Datei gibt es ein weiteres benanntes Template namens mylibchart.configmap. Dieses benannte Template bindet ein anderes benanntes Template mylibchart.util.merge ein, das 2 benannte Templates als Argumente entgegennimmt: das Template, das mylibchart.configmap aufruft, und mylibchart.configmap.tpl.

Die Hilfsfunktion mylibchart.util.merge ist ein benanntes Template in mylibchart/templates/_util.yaml. Es handelt sich um ein praktisches Hilfsmittel aus The Common Helm Helper Chart, da es die 2 Templates zusammenführt und gemeinsame Teile in beiden überschreibt:

{{- /*
mylibchart.util.merge will merge two YAML templates and output the result.
This takes an array of three values:
- the top context
- the template name of the overrides (destination)
- the template name of the base (source)
*/}}
{{- define "mylibchart.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- toYaml (merge $overrides $tpl) -}}
{{- end -}}

Dies ist wichtig, wenn ein Chart gemeinsamen Code verwenden möchte, den es mit seiner eigenen Konfiguration anpassen muss.

Zum Schluss ändern wir den Chart-Typ zu library. Dazu muss mylibchart/Chart.yaml wie folgt bearbeitet werden:

apiVersion: v2
name: mylibchart
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
type: library

# 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.
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 and it is recommended to use it with quotes.
appVersion: "1.16.0"

Das Library Chart ist nun bereit zum Teilen und seine ConfigMap-Definition kann wiederverwendet werden.

Bevor Sie fortfahren, lohnt es sich zu überprüfen, ob Helm das Chart als Library Chart erkennt:

$ helm install mylibchart mylibchart/
Error: library charts are not installable

Das einfache Library Chart verwenden

Es ist nun Zeit, das Library Chart zu verwenden. Das bedeutet, wieder ein Grundgerüst-Chart zu erstellen:

$ helm create mychart
Creating mychart

Entfernen wir wieder die Template-Dateien, da wir nur eine ConfigMap erstellen möchten:

$ rm -rf mychart/templates/*

Wenn wir eine einfache ConfigMap in einem Helm-Template erstellen möchten, könnte sie etwa so aussehen:

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data:
myvalue: "Hello World"

Wir werden jedoch den bereits in mylibchart erstellten gemeinsamen Code wiederverwenden. Die ConfigMap kann in der Datei mychart/templates/configmap.yaml wie folgt erstellt werden:

{{- include "mylibchart.configmap" (list . "mychart.configmap") -}}
{{- define "mychart.configmap" -}}
data:
myvalue: "Hello World"
{{- end -}}

Sie sehen, dass sich die Arbeit vereinfacht, indem die gemeinsame ConfigMap-Definition geerbt wird, die Standardeigenschaften für ConfigMaps hinzufügt. In unserem Template fügen wir die Konfiguration hinzu, in diesem Fall den Datenschlüssel myvalue und seinen Wert. Die Konfiguration überschreibt die leere Ressource der gemeinsamen ConfigMap. Dies ist möglich dank der Hilfsfunktion mylibchart.util.merge, die wir im vorherigen Abschnitt erwähnt haben.

Um den gemeinsamen Code verwenden zu können, müssen wir mylibchart als Abhängigkeit hinzufügen. Fügen Sie Folgendes am Ende der Datei mychart/Chart.yaml hinzu:

# My common code in my library chart
dependencies:
- name: mylibchart
version: 0.1.0
repository: file://../mylibchart

Dies bindet das Library Chart als dynamische Abhängigkeit aus dem Dateisystem ein, das sich auf derselben übergeordneten Pfadebene wie unser Anwendungs-Chart befindet. Da wir das Library Chart als dynamische Abhängigkeit einbinden, müssen wir helm dependency update ausführen. Dieser Befehl kopiert das Library Chart in Ihr Verzeichnis charts/.

$ helm dependency update mychart/
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts

Wir sind nun bereit, unser Chart zu deployen. Vor der Installation lohnt es sich, zunächst das gerenderte Template zu überprüfen.

$ helm install mydemo mychart/ --debug --dry-run
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart

NAME: mydemo
LAST DEPLOYED: Tue Mar 3 17:48:47 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
mylibchart:
global: {}
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
port: 80
type: ClusterIP
serviceAccount:
annotations: {}
create: true
name: null
tolerations: []

HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
myvalue: Hello World
kind: ConfigMap
metadata:
labels:
app: mychart
chart: mychart-0.1.0
release: mydemo
name: mychart-mydemo

Das sieht nach der ConfigMap aus, die wir wollen, mit dem überschriebenen Datenwert myvalue: Hello World. Lassen Sie uns das Chart installieren:

$ helm install mydemo mychart/
NAME: mydemo
LAST DEPLOYED: Tue Mar 3 17:52:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

Wir können das Release abrufen und sehen, dass das eigentliche Template geladen wurde.

$ helm get manifest mydemo
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
myvalue: Hello World
kind: ConfigMap
metadata:
labels:
app: mychart
chart: mychart-0.1.0
release: mydemo
name: mychart-mydemo

Vorteile von Library Charts

Da Library Charts nicht als eigenständige Charts fungieren können, bieten sie folgende Funktionalität:

  • Das .Files-Objekt verweist auf die Dateipfade des übergeordneten Charts, nicht auf den lokalen Pfad des Library Charts
  • Das .Values-Objekt ist identisch mit dem des übergeordneten Charts, im Gegensatz zu Anwendungs-Subcharts, die den Abschnitt der Values erhalten, der unter ihrem Header im übergeordneten Chart konfiguriert ist

The Common Helm Helper Chart

Note: The Common Helm Helper Chart repo on Github is no longer actively maintained, and the repo has been deprecated and archived.

Dieses Chart war das ursprüngliche Muster für Library Charts. Es bietet Hilfsmittel, die Best Practices der Kubernetes-Chart-Entwicklung widerspiegeln. Der besondere Vorteil: Sie können es bei der Entwicklung Ihrer Charts sofort verwenden, um praktischen gemeinsamen Code zu nutzen.

Hier ist eine schnelle Möglichkeit, es zu verwenden. Weitere Details finden Sie in der README.

Erstellen Sie wieder ein Grundgerüst-Chart:

$ helm create demo
Creating demo

Verwenden wir den gemeinsamen Code aus dem Helper Chart. Bearbeiten Sie zunächst das Deployment demo/templates/deployment.yaml wie folgt:

{{- template "common.deployment" (list . "demo.deployment") -}}
{{- define "demo.deployment" -}}
## Define overrides for your Deployment resource here, e.g.
apiVersion: apps/v1
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "demo.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "demo.selectorLabels" . | nindent 8 }}

{{- end -}}

Und nun die Service-Datei demo/templates/service.yaml wie folgt:

{{- template "common.service" (list . "demo.service") -}}
{{- define "demo.service" -}}
## Define overrides for your Service resource here, e.g.
# metadata:
# labels:
# custom: label
# spec:
# ports:
# - port: 8080
{{- end -}}

Diese Templates zeigen, wie das Erben von gemeinsam genutztem Code aus dem Helper Chart Ihre Arbeit auf die Konfiguration oder Anpassung der Ressourcen reduziert.

Um den gemeinsamen Code verwenden zu können, müssen wir common als Abhängigkeit hinzufügen. Fügen Sie Folgendes am Ende der Datei demo/Chart.yaml hinzu:

dependencies:
- name: common
version: "^0.0.5"
repository: "https://charts.helm.sh/incubator/"

Hinweis: Sie müssen das incubator-Repository zur Helm-Repository-Liste hinzufügen (helm repo add).

Da wir das Chart als dynamische Abhängigkeit einbinden, müssen wir helm dependency update ausführen. Dieser Befehl kopiert das Helper Chart in Ihr Verzeichnis charts/.

Da das Helper Chart einige Helm 2-Konstrukte verwendet, müssen Sie Folgendes zu demo/values.yaml hinzufügen, um das nginx-Image zu laden, da dies im Helm 3-Grundgerüst-Chart aktualisiert wurde:

image:
tag: 1.16.0

Sie können mit den Befehlen helm lint und helm template testen, ob die Chart-Templates korrekt sind, bevor Sie sie deployen.

Wenn alles in Ordnung ist, deployen Sie mit helm install!