Helm#
Le problème que Helm résout#
Imaginez que vous devez installer WordPress sur Kubernetes. Cette application nécessite :
Un Deployment pour WordPress (avec la bonne image, les variables d’environnement, les volumes)
Un Deployment pour MySQL (avec mot de passe, volume persistant)
Deux Services (pour exposer les ports)
Un PersistentVolumeClaim (pour le stockage MySQL)
Un Secret (pour le mot de passe de la base de données)
Éventuellement un Ingress (pour le nom de domaine)
Ça représente 6 à 8 fichiers YAML, étroitement liés. Si vous voulez en installer une seconde instance (pour un autre client), vous devez dupliquer tous ces fichiers et modifier les noms. Si une mise à jour est disponible, vous devez modifier chaque fichier manuellement.
Helm résout ce problème. C’est le gestionnaire de paquets de Kubernetes.
Analogie apt / pip
Helm est à Kubernetes ce qu”apt est à Debian ou ce que pip est à Python.
pip install django→ installe Django et toutes ses dépendanceshelm install mon-wordpress bitnami/wordpress→ installe WordPress et toutes ses ressources Kubernetes
Un Chart Helm est l’équivalent d’un package pip. Une Release est une instance installée (comme un paquet installé). Le Repository est l’équivalent de PyPI.
Les quatre concepts fondamentaux#
Structure d’un Chart Helm#
/tmp/ipykernel_23214/531314076.py:38: UserWarning: Glyph 128193 (\N{FILE FOLDER}) missing from font(s) DejaVu Sans Mono.
plt.tight_layout()
/tmp/ipykernel_23214/531314076.py:38: UserWarning: Glyph 128196 (\N{PAGE FACING UP}) missing from font(s) DejaVu Sans Mono.
plt.tight_layout()
/tmp/ipykernel_23214/531314076.py:39: UserWarning: Glyph 128193 (\N{FILE FOLDER}) missing from font(s) DejaVu Sans Mono.
plt.savefig("helm_structure.png", dpi=110, bbox_inches='tight')
/tmp/ipykernel_23214/531314076.py:39: UserWarning: Glyph 128196 (\N{PAGE FACING UP}) missing from font(s) DejaVu Sans Mono.
plt.savefig("helm_structure.png", dpi=110, bbox_inches='tight')
/home/loc/legacy_workspace/notebooks/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 128193 (\N{FILE FOLDER}) missing from font(s) DejaVu Sans Mono.
fig.canvas.print_figure(bytes_io, **kw)
/home/loc/legacy_workspace/notebooks/.venv/lib/python3.13/site-packages/IPython/core/pylabtools.py:170: UserWarning: Glyph 128196 (\N{PAGE FACING UP}) missing from font(s) DejaVu Sans Mono.
fig.canvas.print_figure(bytes_io, **kw)
Chart.yaml#
# Chart.yaml — métadonnées du chart
apiVersion: v2
name: mon-app
description: Une application web simple avec PostgreSQL
type: application
version: 1.3.0 # Version du chart (semver)
appVersion: "2.4.1" # Version de l'application empaquetée
keywords:
- web
- api
maintainers:
- name: Lôc Cosnier
email: loc@exemple.fr
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
values.yaml#
# values.yaml — valeurs par défaut
replicaCount: 2
image:
repository: mon-registry/mon-app
tag: "2.4.1"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: nginx
host: mon-app.exemple.fr
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
postgresql:
enabled: true
auth:
database: monapp
username: monapp
password: "" # À surcharger !
Templates Go#
Les templates Helm utilisent le moteur de template Go, enrichi de fonctions Sprig :
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mon-app.fullname" . }}
labels:
{{- include "mon-app.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mon-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mon-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 8080
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
env:
- name: DATABASE_URL
value: {{ printf "postgresql://%s@%s-postgresql/%s"
.Values.postgresql.auth.username
(include "mon-app.fullname" .)
.Values.postgresql.auth.database | quote }}
# templates/_helpers.tpl
{{/*
Nom complet de l'application
*/}}
{{- define "mon-app.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Labels communs
*/}}
{{- define "mon-app.labels" -}}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Structures de contrôle en Go Template#
# Conditionnel
{{- if .Values.ingress.enabled }}
# ... manifeste Ingress ...
{{- end }}
# Boucle sur une liste
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
# Boucle sur un dictionnaire
{{- range $key, $val := .Values.config }}
{{ $key }}: {{ $val | quote }}
{{- end }}
# With (change le contexte)
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 2 }}
{{- end }}
# Default et quote
image: "{{ .Values.image.repository | default "nginx" }}:{{ .Values.image.tag | default "latest" | quote }}"
Commandes Helm essentielles#
Flux helm install : de values.yaml aux ressources K8s#
Historique des releases et rollback#
Créer son propre chart#
# Créer un chart avec la structure standard
helm create mon-app
# La commande crée :
# mon-app/
# Chart.yaml
# values.yaml
# templates/
# deployment.yaml
# service.yaml
# ingress.yaml
# _helpers.tpl
# NOTES.txt
# Vérifier la syntaxe des templates
helm lint mon-app/
# Prévisualiser les manifestes rendus (sans installer)
helm template ma-release mon-app/ -f custom-values.yaml
# Packager en archive .tgz
helm package mon-app/
# Produit : mon-app-0.1.0.tgz
# Pousser vers un registry OCI (Harbor, GHCR)
helm push mon-app-0.1.0.tgz oci://registry.exemple.fr/charts
Helmfile : orchestrer plusieurs releases#
Pour les environnements complexes, Helmfile permet de décrire toutes les releases Helm en un seul fichier déclaratif :
# helmfile.yaml
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
- name: ingress-nginx
url: https://kubernetes.github.io/ingress-nginx
environments:
staging:
values:
- environments/staging/values.yaml
production:
values:
- environments/production/values.yaml
releases:
- name: ingress-nginx
namespace: ingress-nginx
chart: ingress-nginx/ingress-nginx
version: 4.9.0
- name: cert-manager
namespace: cert-manager
chart: jetstack/cert-manager
version: v1.14.0
set:
- name: installCRDs
value: true
- name: mon-app
namespace: production
chart: ./charts/mon-app
version: 1.3.0
values:
- values/mon-app.yaml
- values/mon-app.{{ .Environment.Name }}.yaml
needs:
- ingress-nginx/ingress-nginx
# Appliquer toutes les releases pour l'environnement staging
helmfile -e staging sync
# Voir le diff avant d'appliquer
helmfile -e production diff
# Appliquer seulement une release
helmfile -e production apply --selector name=mon-app
Moteur de templates simplifié (simulation Python)#
Valeurs finales après fusion :
{
"replicaCount": 5,
"image": {
"repository": "mon-registry/mon-app",
"tag": "2.4.1",
"pullPolicy": "IfNotPresent"
},
"service": {
"type": "LoadBalancer",
"port": 80
},
"resources": {
"requests": {
"cpu": "100m",
"memory": "128Mi"
},
"limits": {
"cpu": "500m",
"memory": "512Mi"
}
}
}
replicas finaux : 5 (--set a la priorité maximale)
image tag final : 2.4.1 (override par custom.yaml)
service type final : LoadBalancer (override par custom.yaml)
Artifact Hub#
Artifact Hub est le catalogue public de charts Helm (et aussi d’autres artefacts CNCF). On y trouve des charts pour quasiment tous les logiciels open-source populaires : nginx, PostgreSQL, Redis, Kafka, Prometheus, Grafana, etc.
# Chercher un chart dans les repos configurés
helm search repo postgres
# NAME CHART VERSION APP VERSION
# bitnami/postgresql 12.12.10 16.1.0
# bitnami/postgresql-ha 11.9.7 16.1.0
# Chercher dans Artifact Hub (nécessite helm hub search ou l'UI web)
helm search hub postgresql
# Voir toutes les versions d'un chart
helm search repo bitnami/postgresql --versions
# Installer en spécifiant une version précise
helm install my-postgres bitnami/postgresql --version 12.12.10
Récapitulatif#
Ce qu’il faut retenir
Helm = gestionnaire de paquets K8s : il empaquette des ensembles de manifestes YAML en Charts réutilisables et paramétrables.
Chart / Release / Repository / Values : les quatre concepts fondamentaux. Un Chart installé devient une Release. Les Values permettent de personnaliser sans modifier les templates.
Templates Go :
{{ .Values.xxx }},{{ if }},{{ range }},{{ include }}. La fusion des values suit une hiérarchie : défauts <-f fichier<--set.Commandes clés :
helm install,helm upgrade,helm rollback,helm history,helm template(pour prévisualiser).Helmfile orchestre plusieurs releases Helm en une configuration déclarative, avec support des environnements.
Artifact Hub est le catalogue public de charts.
bitnamiest le dépôt le plus populaire.