Échafaudage de graphique Helm
Guide complet pour créer, organiser et gérer des graphiques Helm permettant de packager et déployer des applications Kubernetes.
Objectif
Cette skill fournit des instructions étape par étape pour construire des graphiques Helm prêts pour la production, incluant la structure des graphiques, les modèles de templating, la gestion des valeurs et les stratégies de validation.
Quand utiliser cette skill
Utilisez cette skill quand vous devez :
- Créer de nouveaux graphiques Helm à partir de zéro
- Packager des applications Kubernetes pour la distribution
- Gérer des déploiements multi-environnements avec Helm
- Implémenter le templating pour des manifestes Kubernetes réutilisables
- Configurer des dépôts de graphiques Helm
- Suivre les bonnes pratiques et conventions Helm
Présentation de Helm
Helm est le gestionnaire de paquets pour Kubernetes qui :
- Template les manifestes Kubernetes pour la réutilisabilité
- Gère les releases et rollbacks des applications
- Gère les dépendances entre graphiques
- Fournit le contrôle de version pour les déploiements
- Simplifie la gestion de configuration à travers les environnements
Flux de travail étape par étape
1. Initialiser la structure du graphique
Créer un nouveau graphique :
helm create my-app
Structure standard du graphique :
my-app/
├── Chart.yaml # Métadonnées du graphique
├── values.yaml # Valeurs de configuration par défaut
├── charts/ # Dépendances de graphiques
├── templates/ # Templates de manifestes Kubernetes
│ ├── NOTES.txt # Notes post-installation
│ ├── _helpers.tpl # Helpers de template
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── serviceaccount.yaml
│ ├── hpa.yaml
│ └── tests/
│ └── test-connection.yaml
└── .helmignore # Fichiers à ignorer
2. Configurer Chart.yaml
Les métadonnées du graphique définissent le paquet :
apiVersion: v2
name: my-app
description: A Helm chart for My Application
type: application
version: 1.0.0 # Version du graphique
appVersion: "2.1.0" # Version de l'application
# Mots-clés pour la découverte de graphiques
keywords:
- web
- api
- backend
# Informations de maintenance
maintainers:
- name: DevOps Team
email: devops@example.com
url: https://github.com/example/my-app
# Dépôt du code source
sources:
- https://github.com/example/my-app
# Page d'accueil
home: https://example.com
# Icône du graphique
icon: https://example.com/icon.png
# Dépendances
dependencies:
- name: postgresql
version: "12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "17.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
Référence : Voir assets/Chart.yaml.template pour un exemple complet
3. Concevoir la structure de values.yaml
Organisez les valeurs hiérarchiquement :
# Configuration de l'image
image:
repository: myapp
tag: "1.0.0"
pullPolicy: IfNotPresent
# Nombre de réplicas
replicaCount: 3
# Configuration du service
service:
type: ClusterIP
port: 80
targetPort: 8080
# Configuration Ingress
ingress:
enabled: false
className: nginx
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
# Ressources
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
# Autoscaling
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# Variables d'environnement
env:
- name: LOG_LEVEL
value: "info"
# Données ConfigMap
configMap:
data:
APP_MODE: production
# Dépendances
postgresql:
enabled: true
auth:
database: myapp
username: myapp
redis:
enabled: false
Référence : Voir assets/values.yaml.template pour la structure complète
4. Créer des fichiers de template
Utiliser le templating Go avec les fonctions Helm :
templates/deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
{{- toYaml .Values.env | nindent 12 }}
5. Créer des helpers de template
templates/_helpers.tpl :
{{/*
Expand the name of the chart.
*/}}
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
6. Gérer les dépendances
Ajouter les dépendances dans Chart.yaml :
dependencies:
- name: postgresql
version: "12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Mettre à jour les dépendances :
helm dependency update
helm dependency build
Surcharger les valeurs des dépendances :
# values.yaml
postgresql:
enabled: true
auth:
database: myapp
username: myapp
password: changeme
primary:
persistence:
enabled: true
size: 10Gi
7. Tester et valider
Commandes de validation :
# Linter le graphique
helm lint my-app/
# Installation en dry-run
helm install my-app ./my-app --dry-run --debug
# Rendu des templates
helm template my-app ./my-app
# Rendu des templates avec valeurs
helm template my-app ./my-app -f values-prod.yaml
# Afficher les valeurs calculées
helm show values ./my-app
Script de validation :
#!/bin/bash
set -e
echo "Linting chart..."
helm lint .
echo "Testing template rendering..."
helm template test-release . --dry-run
echo "Checking for required values..."
helm template test-release . --validate
echo "All validations passed!"
Référence : Voir scripts/validate-chart.sh
8. Packager et distribuer
Packager le graphique :
helm package my-app/
# Crée : my-app-1.0.0.tgz
Créer un dépôt de graphiques :
# Créer l'index
helm repo index .
# Uploader vers le dépôt
# Exemple AWS S3
aws s3 sync . s3://my-helm-charts/ --exclude "*" --include "*.tgz" --include "index.yaml"
Utiliser le graphique :
helm repo add my-repo https://charts.example.com
helm repo update
helm install my-app my-repo/my-app
9. Configuration multi-environnements
Fichiers de valeurs spécifiques à l'environnement :
my-app/
├── values.yaml # Défauts
├── values-dev.yaml # Développement
├── values-staging.yaml # Staging
└── values-prod.yaml # Production
values-prod.yaml :
replicaCount: 5
image:
tag: "2.1.0"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
ingress:
enabled: true
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
postgresql:
enabled: true
primary:
persistence:
size: 100Gi
Installer avec environnement :
helm install my-app ./my-app -f values-prod.yaml --namespace production
10. Implémenter des hooks et des tests
Hook de pré-installation :
# templates/pre-install-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-app.fullname" . }}-db-setup
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
containers:
- name: db-setup
image: postgres:15
command: ["psql", "-c", "CREATE DATABASE myapp"]
restartPolicy: Never
Test de connexion :
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "my-app.fullname" . }}-test-connection"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
Exécuter les tests :
helm test my-app
Motifs courants
Motif 1 : Ressources conditionnelles
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-app.fullname" . }}
spec:
# ...
{{- end }}
Motif 2 : Itération sur les listes
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
Motif 3 : Inclusion de fichiers
data:
config.yaml: |
{{- .Files.Get "config/application.yaml" | nindent 4 }}
Motif 4 : Valeurs globales
global:
imageRegistry: docker.io
imagePullSecrets:
- name: regcred
# Utilisation dans les templates :
image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
Bonnes pratiques
- Utilisez le versioning sémantique pour les versions du graphique et de l'application
- Documentez toutes les valeurs dans values.yaml avec des commentaires
- Utilisez des helpers de template pour la logique répétée
- Validez les graphiques avant de les packager
- Épinglez les versions des dépendances explicitement
- Utilisez des conditions pour les ressources optionnelles
- Suivez les conventions de nommage (minuscules, tirets)
- Incluez NOTES.txt avec les instructions d'utilisation
- Ajoutez des labels de manière cohérente en utilisant les helpers
- Testez les installations dans tous les environnements
Dépannage
Erreurs de rendu de template :
helm template my-app ./my-app --debug
Problèmes de dépendance :
helm dependency update
helm dependency list
Échecs d'installation :
helm install my-app ./my-app --dry-run --debug
kubectl get events --sort-by='.lastTimestamp'
Skills connexes
k8s-manifest-generator- Pour créer des manifestes Kubernetes de basegitops-workflow- Pour les déploiements automatisés de graphiques Helm