Charts de type library
Un chart de type library est un type de chart Helm qui définit des primitives ou des définitions de chart que les templates Helm d'autres charts peuvent partager. Les utilisateurs peuvent ainsi partager des extraits de code réutilisables d'un chart à l'autre, sans répétition, en gardant leurs charts DRY.
Le chart de type library a été introduit dans Helm 3 pour reconnaître officiellement les charts communs ou utilitaires utilisés par les mainteneurs de charts depuis Helm 2. En l'intégrant comme type de chart à part entière, Helm apporte :
- Un moyen de distinguer explicitement les charts communs des charts d'application
- Une logique empêchant l'installation d'un chart commun
- L'absence de rendu des templates d'un chart commun, qui pourraient contenir des artefacts de release
- La possibilité pour les charts dépendants d'utiliser le contexte du chart qui les importe
Un mainteneur de chart peut définir un chart commun comme chart de type library et avoir désormais la certitude que Helm traitera ce chart de façon standard et cohérente. Cela veut aussi dire que les définitions d'un chart d'application peuvent être partagées en changeant simplement le type du chart.
Créer un chart de type library simple
Comme mentionné précédemment, un chart de type library est un type de chart Helm. Cela signifie que vous pouvez commencer par créer un squelette de chart :
$ helm create mylibchart
Creating mylibchart
Commencez par supprimer tous les fichiers du répertoire templates, car nous
allons créer nos propres définitions de templates dans cet exemple.
$ rm -rf mylibchart/templates/*
Le fichier de valeurs ne sera pas non plus nécessaire.
$ rm -f mylibchart/values.yaml
Avant de créer le code commun, faisons un rapide rappel de quelques
concepts Helm utiles ici. Un template nommé
(parfois appelé partial ou sous-template) est simplement un template défini dans
un fichier et auquel on donne un nom. Dans le répertoire templates/, tout fichier
commençant par un tiret bas (_) n'est pas censé générer un fichier manifeste
Kubernetes. Par convention, les templates utilitaires et les partials sont donc
placés dans des fichiers _*.tpl ou _*.yaml.
Dans cet exemple, nous allons écrire un ConfigMap commun qui crée une ressource
ConfigMap vide. Nous définirons ce ConfigMap commun dans le fichier
mylibchart/templates/_configmap.yaml comme suit :
{{- 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 -}}
La structure du ConfigMap est définie dans le template nommé mylibchart.configmap.tpl.
C'est un simple ConfigMap avec une ressource vide, data. Dans ce fichier, il y a
un autre template nommé appelé mylibchart.configmap. Ce template nommé inclut un
autre template nommé mylibchart.util.merge qui prend deux templates nommés comme
arguments : le template appelant mylibchart.configmap et mylibchart.configmap.tpl.
La fonction utilitaire mylibchart.util.merge est un template nommé dans
mylibchart/templates/_util.yaml. C'est un utilitaire pratique tiré du
Common Helm Helper Chart : il fusionne
les deux templates et remplace les parties communes aux deux :
{{- /*
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 -}}
C'est important lorsqu'un chart veut utiliser du code commun qu'il doit personnaliser avec sa propre configuration.
Enfin, changeons le type de chart en library. Cela nécessite de modifier le
fichier mylibchart/Chart.yaml comme suit :
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"
Le chart de type library est maintenant prêt à être partagé et sa définition de ConfigMap peut être réutilisée.
Avant de continuer, il est utile de vérifier si Helm reconnaît le chart comme un chart de type library :
$ helm install mylibchart mylibchart/
Error: library charts are not installable
Utiliser le chart de type library simple
Il est temps d'utiliser le chart de type library. Pour cela, créez de nouveau un squelette de chart :
$ helm create mychart
Creating mychart
Supprimons à nouveau les fichiers de templates, car nous voulons créer uniquement un ConfigMap :
$ rm -rf mychart/templates/*
Pour créer un simple ConfigMap dans un template Helm, on écrirait par exemple :
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data:
myvalue: "Hello World"
Cependant, nous allons réutiliser le code commun déjà créé dans mylibchart.
Le ConfigMap peut être créé dans le fichier mychart/templates/configmap.yaml
comme suit :
{{- include "mylibchart.configmap" (list . "mychart.configmap") -}}
{{- define "mychart.configmap" -}}
data:
myvalue: "Hello World"
{{- end -}}
Vous voyez que le travail est simplifié, puisque le template hérite de la
définition commune du ConfigMap, qui ajoute les propriétés standard. Dans notre template,
nous ajoutons la configuration, ici la clé myvalue et sa
valeur. La configuration remplace la ressource vide du ConfigMap commun. C'est
possible grâce à la fonction utilitaire mylibchart.util.merge mentionnée
dans la section précédente.
Pour pouvoir utiliser le code commun, nous devons ajouter mylibchart comme
dépendance. Ajoutez ce qui suit à la fin du fichier mychart/Chart.yaml :
# My common code in my library chart
dependencies:
- name: mylibchart
version: 0.1.0
repository: file://../mylibchart
Le chart de type library est ainsi inclus comme dépendance dynamique depuis le
système de fichiers, situé dans le même répertoire parent que notre chart d'application. Comme nous
incluons le chart de type library en tant que dépendance dynamique, nous devons
exécuter helm dependency update. Cette commande copiera le chart de type
library dans votre répertoire 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
Nous sommes maintenant prêts à déployer notre chart. Avant l'installation, il est utile de vérifier le template rendu.
$ 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
C'est bien le ConfigMap que nous voulions, avec
myvalue: Hello World, qui remplace le data vide du ConfigMap commun. Installons-le :
$ helm install mydemo mychart/
NAME: mydemo
LAST DEPLOYED: Tue Mar 3 17:52:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Nous pouvons récupérer la release et constater que c'est bien notre template qui a été chargé.
$ 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
Avantages des charts de type library
Parce qu'ils ne peuvent pas fonctionner comme des charts autonomes, les charts de type library peuvent tirer parti des fonctionnalités suivantes :
- L'objet
.Filesréférence les chemins de fichiers du chart parent, plutôt que le chemin local du chart de type library - L'objet
.Valuesest le même que celui du chart parent, contrairement aux sous-charts d'application qui reçoivent uniquement la partie des valeurs placée sous leur nom dans le chart parent.
Le 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.
Ce chart était le modèle original pour les charts communs. Il fournit des utilitaires qui reflètent les bonnes pratiques de développement de charts Kubernetes. Mieux encore, vous pouvez l'utiliser d'emblée dans vos charts et profiter ainsi de code partagé bien pratique.
Voici une façon rapide de l'utiliser. Pour plus de détails, consultez le README.
Créez de nouveau un squelette de chart :
$ helm create demo
Creating demo
Utilisons le code commun du chart utilitaire. Commencez par modifier le fichier
demo/templates/deployment.yaml comme suit :
{{- 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 -}}
Puis le fichier du service, demo/templates/service.yaml, comme suit :
{{- 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 -}}
Ces templates montrent qu'en héritant du code commun du chart utilitaire, vous n'avez plus qu'à écrire la configuration ou la personnalisation des ressources.
Pour pouvoir utiliser le code commun, nous devons ajouter common comme
dépendance. Ajoutez ce qui suit à la fin du fichier demo/Chart.yaml :
dependencies:
- name: common
version: "^0.0.5"
repository: "https://charts.helm.sh/incubator/"
Remarque : vous devrez ajouter le dépôt incubator à la liste des dépôts Helm
(helm repo add).
Comme nous incluons le chart en tant que dépendance dynamique, nous devons
exécuter helm dependency update. Cette commande copiera le chart utilitaire
dans votre répertoire charts/.
Comme le chart utilitaire utilise certaines constructions de Helm 2, vous devrez
ajouter ce qui suit à demo/values.yaml pour que l'image
nginx puisse être chargée, le squelette de chart de Helm 3 ayant changé sur ce point :
image:
tag: 1.16.0
Avant de déployer, vous pouvez vérifier que les templates du chart sont corrects
avec les commandes helm lint et helm template.
Si tout est en ordre, déployez avec helm install !