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.

développeur logiciel dans la nature 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 ressources
  • post-install : Après l’installation de toutes les ressources
  • pre-upgrade : Avant la mise à jour
  • post-upgrade : Après la mise à jour
  • pre-delete : Avant la suppression
  • post-delete : Après la suppression
  • pre-rollback : Avant le retour en arrière
  • post-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