Helm Charts : Gestion des packages Kubernetes
Déploiements Kubernetes avec la gestion des packages Helm
Helm a révolutionné le déploiement d’applications Kubernetes en introduisant des concepts de gestion de paquets familiers provenant des systèmes d’exploitation traditionnels.
À mesure que l’adoption de Kubernetes augmente, la gestion d’applications complexes avec des dizaines de fichiers YAML devient difficile. Les Helm Charts résolvent ce problème en regroupant toutes les ressources en paquets versionnés et configurables.
Cette belle image est générée par modèle AI Flux 1 dev.
Comprendre Helm : le gestionnaire de paquets Kubernetes
Helm est à Kubernetes ce que apt est à Debian, yum à RedHat, ou Homebrew à macOS. Il empaquète les applications Kubernetes en Charts – des collections de fichiers qui décrivent des ressources Kubernetes liées. Un seul Chart peut déployer une pile d’applications complète : serveurs web, bases de données, couches de mise en cache, règles d’ingress et composants de surveillance. Pour ceux qui découvrent Kubernetes, une feuille de calcul Kubernetes fournit des commandes et concepts essentiels pour commencer.
Pourquoi Helm compte dans le DevOps moderne
Réduction de la complexité : Au lieu de gérer plus de 20 fichiers YAML, vous gérez un seul Chart avec des valeurs personnalisables.
Reproductibilité : Déployez des configurations identiques sur les environnements de développement, de test et de production avec des surcharges de valeurs spécifiques à l’environnement. Cela est particulièrement précieux lors du déploiement d’architectures microservices complexes où la cohérence est cruciale.
Contrôle de version : Les Charts sont versionnés, permettant un retour en arrière facile et un suivi des mises à jour.
Écosystème communautaire : Des milliers de Charts prêts à l’emploi sont disponibles via Artifact Hub (anciennement Helm Hub) pour des applications populaires comme PostgreSQL, Redis, NGINX, Prometheus, etc.
Puissance de modélisation : Les modèles Go permettent la génération dynamique de ressources basée sur les valeurs d’entrée, réduisant les duplications.
Architecture Helm et concepts clés
Architecture Helm 3
Helm 3 a simplifié l’architecture en supprimant Tiller, le composant côté serveur problématique de Helm 2 :
- Client Helm : Outil CLI qui interagit directement avec l’API Kubernetes
- Chart : Format de paquet contenant des modèles et des métadonnées
- Release : Une instance d’un Chart en cours d’exécution dans un cluster Kubernetes
- Répertoire : Emplacement de stockage des Charts (serveur HTTP ou registre OCI)
Composants clés d’un Chart Helm
my-app-chart/
├── Chart.yaml # Métadonnées et version du Chart
├── values.yaml # Valeurs de configuration par défaut
├── charts/ # Charts dépendants
├── templates/ # Modèles de ressources Kubernetes
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Fonctions de modèle
│ └── NOTES.txt # Notes post-installation
├── .helmignore # Fichiers à ignorer lors du paquetage
├── README.md
└── LICENSE
Créer votre premier Chart Helm
Initialiser un nouveau Chart
helm create my-application
cd my-application
Cela génère un Chart de départ avec des modèles d’exemple pour un déploiement, un service et un ingress.
Chart.yaml : Définir les métadonnées
apiVersion: v2
name: my-application
description: Un chart d'application prêt pour la production
type: application
version: 1.0.0 # Version du chart
appVersion: "2.4.1" # Version de l'application
maintainers:
- name: Votre équipe
email: team@company.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
values.yaml : Gestion de la configuration
Le fichier values.yaml définit les configurations par défaut que les utilisateurs peuvent surcharger. Cette approche sépare la configuration des modèles, facilitant la gestion de différents environnements (développement, test, production) et la personnalisation des déploiements sans modifier les fichiers de modèles.
replicaCount: 3
image:
repository: myapp/backend
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
Modèles : Manifestes Kubernetes dynamiques
Les modèles utilisent la syntaxe de modélisation Go pour générer dynamiquement des ressources Kubernetes. Ces modèles peuvent générer tout type de ressource Kubernetes, des simples Déploiements à des StatefulSets complexes pour les applications nécessitant un stockage persistant. Pour les applications nécessitant des identités stables et des volumes persistants, vous souhaiterez utiliser des StatefulSets au lieu de Déploiements, comme détaillé dans notre guide sur StatefulSets et stockage persistant dans Kubernetes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-application.fullname" . }}
labels:
{{- include "my-application.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-application.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-application.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
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 10 }}
Aides de modèle (_helpers.tpl)
Créez des fonctions de modèle réutilisables pour éviter les répétitions :
{{/*
Étendre le nom du chart.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Créer un nom d'application complet par défaut.
*/}}
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Étiquettes communes
*/}}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
{{ include "my-application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Gestion des Charts Helm : installation et opérations
Installer un Chart
# Installer depuis un dépôt
helm install my-release bitnami/postgresql
# Installer depuis un répertoire local
helm install my-app ./my-application
# Installer avec des valeurs personnalisées
helm install my-app ./my-application -f values-production.yaml
# Installer avec des surcharges de valeurs en ligne
helm install my-app ./my-application \
--set replicaCount=5 \
--set image.tag=2.0.0
Mettre à jour les releases
# Mettre à jour avec de nouvelles valeurs
helm upgrade my-app ./my-application -f values-production.yaml
# Mettre à jour avec un retour en arrière automatique en cas d'échec
helm upgrade my-app ./my-application --atomic --timeout 5m
# Forcer les mises à jour des ressources
helm upgrade my-app ./my-application --force
Retour en arrière et historique
# Voir l'historique des releases
helm history my-app
# Retour en arrière vers la version précédente
helm rollback my-app
# Retour en arrière vers une version spécifique
helm rollback my-app 3
Test et débogage
# Exécution en mode sec pour voir les manifestes générés
helm install my-app ./my-application --dry-run --debug
# Rendu des modèles sans installation
helm template my-app ./my-application
# Vérifier le chart pour des problèmes
helm lint ./my-application
# Tester la release avec des hooks de test
helm test my-app
Fonctionnalités avancées de Helm
Dépendances de chart
Les Charts Helm peuvent dépendre d’autres Charts, vous permettant de composer des applications complexes à partir de composants réutilisables. Cela est particulièrement utile lors du déploiement de microservices nécessitant des bases de données, des files d’attente de messages ou d’autres services d’assistance. Définissez les dépendances dans Chart.yaml :
dependencies:
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Mettre à jour les dépendances :
helm dependency update ./my-application
Hooks Helm pour la gestion du cycle de vie
Les hooks s’exécutent à des points spécifiques dans le cycle de vie de la release :
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-application.fullname" . }}-db-migration
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
spec:
containers:
- name: db-migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["python", "manage.py", "migrate"]
restartPolicy: Never
Les types de hooks incluent :
pre-install: Avant l’installation des ressourcespost-install: Après l’installation de toutes les ressourcespre-upgrade: Avant la mise à jourpost-upgrade: Après la mise à jourpre-delete: Avant la suppressionpost-delete: Après la suppressionpre-rollback: Avant le retour en arrièrepost-rollback: Après le retour en arrière
Logique conditionnelle et contrôle du flux
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-application.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "my-application.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Support des registres OCI : distribution moderne des Charts
Depuis Helm 3.8, le support des registres OCI (Open Container Initiative) est stable, permettant de stocker les Charts à côté des images conteneurs.
Publication dans un registre OCI
# Connexion au registre
helm registry login registry.example.com
# Empaquetage du chart
helm package ./my-application
# Pousser vers le registre OCI
helm push my-application-1.0.0.tgz oci://registry.example.com/charts
# Installer depuis le registre OCI
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0
Avantages des registres OCI
- Stockage unifié : Charts et images au même endroit
- Outils standard : Utiliser l’infrastructure de registre existante
- Meilleure sécurité : Exploiter l’authentification et le balayage du registre
- Gestion plus simple : Aucun serveur de dépôt de Chart séparé nécessaire
Bonnes pratiques pour les Charts Helm en production
1. Structure et documentation des valeurs
Documentez toutes les valeurs avec des commentaires :
# -- Nombre de réplicas pour l'application
replicaCount: 3
# -- Configuration de l'image
image:
# -- Référentiel de l'image
repository: myapp/backend
# -- Stratégie de tirage de l'image
pullPolicy: IfNotPresent
# -- Étiquette de l'image (par défaut à la version de l'application du chart)
tag: ""
2. Gestion des ressources
Définissez toujours les demandes et limites de ressources :
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
3. Contextes de sécurité
Définissez les contextes de sécurité pour les conteneurs :
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
4. Vérifications de santé
Incluez des sondes de vivacité et de prêtes :
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5. Gestion des ConfigMap et Secrets
La gestion correcte des secrets est cruciale pour les déploiements en production. Utilisez des gestionnaires de secrets externes (Sealed Secrets, External Secrets Operator ou Vault) plutôt que de stocker les secrets dans les fichiers de valeurs. Cela garantit que les données sensibles comme les mots de passe de base de données, les clés API et les certificats sont gérées de manière sécurisée :
envFrom:
- secretRef:
name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
name: {{ include "my-application.fullname" . }}-config
6. Validation de schéma
Créez values.schema.json pour valider les entrées utilisateur :
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": ["repository"]
}
},
"required": ["image"]
}
7. NOTES.txt pour les instructions utilisateur
Fournissez des instructions post-installation :
1. Obtenir l'URL de l'application en exécutant :
{{- if .Values.ingress.enabled }}
https://{{ (index .Values.ingress.hosts 0).host }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-application.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- end }}
2. Surveiller le déploiement :
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"
Test des Charts Helm et intégration CI/CD
Test des Charts avec chart-testing (ct)
# Installer chart-testing
brew install chart-testing
# Vérifier les charts
ct lint --config ct.yaml
# Installer et tester les charts
ct install --config ct.yaml
Exemple GitHub Actions
name: Helm Chart CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configurer Helm
uses: azure/setup-helm@v3
with:
version: 3.12.0
- name: Configurer chart-testing
uses: helm/chart-testing-action@v2
- name: Vérifier les charts
run: ct lint --config ct.yaml
- name: Créer un cluster kind
uses: helm/kind-action@v1
- name: Installer les charts
run: ct install --config ct.yaml
GitOps avec Helm : ArgoCD et Flux
Les outils GitOps comme ArgoCD et Flux s’intègrent parfaitement avec les Charts Helm, permettant des déploiements déclaratifs et automatisés. Ces outils surveillent votre dépôt Git pour les changements et synchronisent automatiquement les releases Helm, rendant le déploiement continu simple. Pour les architectures microservices complexes, envisagez comment les modèles de transactions distribuées comme le modèle Saga peuvent aider à gérer la cohérence des services déployés via Helm.
Application ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-application
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app-chart
targetRevision: main
path: charts/my-application
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
HelmRelease Flux
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: my-application
namespace: flux-system
spec:
interval: 5m
chart:
spec:
chart: my-application
version: '1.x.x'
sourceRef:
kind: HelmRepository
name: my-charts
values:
replicaCount: 5
image:
tag: "2.0.0"
Dépannage des problèmes courants avec Helm
Problème : Mise à jour échouée bloquée en attente
# Vérifier l'état de la release
helm list --all-namespaces
# Obtenir les détails de la release
helm status my-app -n namespace
# Supprimer forcé si nécessaire (utiliser avec prudence)
kubectl delete secret -n namespace -l owner=helm,name=my-app
Problème : Erreurs de rendu des modèles
# Déboguer le rendu des modèles
helm template my-app ./my-application --debug
# Valider contre Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -
Problème : Valeurs non appliquées
# Vérifier les valeurs fusionnées
helm get values my-app
# Afficher toutes les valeurs calculées
helm get values my-app --all
Écosystème et outils Helm
L’écosystème Helm inclut de nombreux outils qui étendent ses capacités et s’intègrent à d’autres technologies Kubernetes. Lors du déploiement d’applications nécessitant des fonctionnalités réseau avancées comme la communication service à service, la gestion du trafic et les politiques de sécurité, envisagez d’intégrer un réseau de services avec Istio et Linkerd, qui peuvent être déployés et gérés via des Charts Helm.
Outils essentiels
- Helmfile : Spécification déclarative pour déployer des Charts Helm
- Helm Diff : Aperçu des changements avant la mise à jour
- Helm Secrets : Gestion des secrets avec SOPS
- Nova : Trouver les Charts Helm obsolètes
- Pluto : Détecter les API Kubernetes obsolètes
Exemple de Helmfile
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: postgresql
namespace: database
chart: bitnami/postgresql
version: 12.x.x
values:
- postgresql:
auth:
database: myapp
username: appuser
- name: my-app
namespace: production
chart: ./charts/my-application
values:
- values-production.yaml
needs:
- database/postgresql
L’avenir de Helm
L’écosystème Helm continue d’évoluer :
- OCI-Native : Transition complète vers les registres OCI comme norme
- Sécurité améliorée : Meilleure gestion des secrets et capacités de signature
- Performance : Rendu et installation plus rapides pour les grands Charts
- Support de WASM : WebAssembly pour les plugins et extensions des Charts
- Validation améliorée : Validation de schéma et application de politiques renforcée
Conclusion
Helm est devenu le standard de facto pour la gestion de paquets Kubernetes, et maîtriser Helm est essentiel pour les pratiques DevOps modernes. En comprenant la structure des Charts, le modélisation, la gestion des valeurs et les bonnes pratiques, vous pouvez créer des déploiements Kubernetes maintenables, sécurisés et évolutifs.
Commencez par des Charts simples, incorporez progressivement des fonctionnalités avancées comme les hooks et les dépendances, et intégrez des outils GitOps pour une infrastructure de production. La communauté Helm propose des milliers de Charts prêts à l’emploi, mais le vrai pouvoir vient de la création de Charts personnalisés adaptés aux besoins de votre organisation. Que vous déployiez des applications stateless ou des charges de travail stateful nécessitant un stockage persistant, Helm simplifie la complexité de la gestion des ressources Kubernetes. Pour les équipes installant de nouveaux clusters Kubernetes, envisagez d’installer Kubernetes avec Kubespray ou explorez les distributions Kubernetes comme k3s ou MicroK8s pour les environnements de développement. Si vous évaluez laquelle des distributions convient à vos besoins de laboratoire domestique ou de petit cluster, consultez notre comparaison approfondie des distributions Kubernetes pour une analyse détaillée.
Liens utiles
- Documentation officielle Helm
- Artifact Hub - Découvrir les Charts Helm
- Dépôt GitHub Helm
- Guide des bonnes pratiques Helm
- Outil de test de Chart
- Helmfile
- ArgoCD
- Flux CD
- Dépôt de Charts Bitnami
- Feuille de calcul Kubernetes
- Installer Kubernetes avec Kubespray
- Comparaison des distributions Kubernetes pour un laboratoire domestique de 3 nœuds
- Distributions Kubernetes - aperçu de kubeadm, k3s, MicroK8s, Minikube, Talos Linux et RKE2
- Réseau de services avec Istio et Linkerd
- StatefulSets et stockage persistant en Kubernetes
- Modèle Saga dans les transactions distribuées