Aller au contenu
Conteneurs & Orchestration medium

Helm v4 : changements, breaking changes et migration depuis Helm v3

14 min de lecture

logo helm

Helm v4 apporte des changements importants qui peuvent casser vos pipelines CI/CD si vous ne les anticipez pas. Ce guide liste tout ce qui change, avec les commandes exactes pour adapter vos scripts. Vous apprendrez à identifier les incompatibilités, tester votre migration en staging, et basculer sans incident en production.

  • Identifier les flags renommés et les corriger (--atomic--rollback-on-failure)
  • Migrer vos post-renderers vers le système de plugins
  • Comprendre le nouveau comportement de --dry-run et --wait
  • Activer Server-Side Apply (SSA) et gérer les conflits
  • Adapter l’authentification OCI et utiliser les digests
  • Planifier votre migration avec une checklist CI/CD

Avant de lire le détail, voici une checklist des breaking changes à vérifier dans vos scripts :

Ce qui changev3v4Impact
Rollback automatique--atomic--rollback-on-failureScripts CI/CD
Forcer remplacement--force--force-replaceScripts upgrade
Post-renderer--post-renderer ./script--post-renderer plugin-namePipelines avec kustomize
Dry-run--dry-run (booléen)--dry-run=client|serverTests avant déploiement
Wait--wait (booléen)--wait=watcher|legacyAttente pods ready
Server-Side ApplyOpt-inActivé par défautConflits ownership
OCI loginURL complète acceptéeDomaine uniquementAuth registries

Le flag --atomic existe toujours mais est déprécié. Utilisez --rollback-on-failure :

Fenêtre de terminal
helm upgrade --install myapp ./chart \
--atomic \
--wait \
--timeout 5m

Comportement : Si le déploiement échoue (pods non Ready dans le timeout), Helm effectue automatiquement un rollback vers la révision précédente.

Le flag pour forcer le remplacement des ressources a été renommé :

Fenêtre de terminal
helm upgrade myapp ./chart --force

Quand l’utiliser : Forcer le remplacement complet d’une ressource au lieu d’un patch. Utile quand un champ immutable a changé.

En v4, un nouveau flag gère les conflits Server-Side Apply :

Fenêtre de terminal
helm upgrade myapp ./chart --force-conflicts

Ce flag force l’application même si un autre controller (ArgoCD, Flux, kubectl) a modifié la ressource.


En Helm v3, vous pouviez passer un binaire externe :

Fenêtre de terminal
# v3 : binaire direct (NE FONCTIONNE PLUS en v4)
helm template myapp ./chart --post-renderer ./kustomize-overlay.sh

En Helm v4, les post-renderers passent obligatoirement par le système de plugins :

Fenêtre de terminal
# v4 : plugin installé
helm template myapp ./chart --post-renderer kustomize
  1. Convertir votre script en plugin Helm

    Créez la structure de plugin :

    Fenêtre de terminal
    mkdir -p ~/.local/share/helm/plugins/my-postrenderer

    Créez plugin.yaml :

    ~/.local/share/helm/plugins/my-postrenderer/plugin.yaml
    name: "my-postrenderer"
    version: "1.0.0"
    usage: "Post-render manifests with custom logic"
    command: "$HELM_PLUGIN_DIR/render.sh"
    postRenderer: true
  2. Déplacer votre script

    Copiez votre script existant :

    Fenêtre de terminal
    cp ./kustomize-overlay.sh ~/.local/share/helm/plugins/my-postrenderer/render.sh
    chmod +x ~/.local/share/helm/plugins/my-postrenderer/render.sh
  3. Vérifier l’installation

    Fenêtre de terminal
    helm plugin list

    Sortie attendue :

    NAME VERSION DESCRIPTION
    my-postrenderer 1.0.0 Post-render manifests with custom logic
  4. Utiliser le plugin

    Fenêtre de terminal
    helm template myapp ./chart --post-renderer my-postrenderer

Utilisez --post-renderer-args :

Fenêtre de terminal
helm upgrade --install myapp ./chart \
--post-renderer kustomize \
--post-renderer-args "--enable-helm" \
--post-renderer-args "--load-restrictor=LoadRestrictionsNone"

En v3, --dry-run était un booléen. En v4, c’est une option à valeurs :

ValeurComportementConnexion cluster
--dry-run=noneExécution normale (défaut si omis)Oui
--dry-run=clientSimulation côté client uniquementNon
--dry-run=serverSimulation côté serveurOui
--dry-run (sans valeur)Équivalent à --dry-run=clientNon

Recommandation : Utilisez toujours la forme explicite pour éviter les ambiguïtés.

Fenêtre de terminal
# Validation sans cluster (rapide, offline)
helm upgrade --install myapp ./chart --dry-run=client
# Validation avec le cluster (vérifie schémas, RBAC, quotas)
helm upgrade --install myapp ./chart --dry-run=server

Le flag --hide-secret masque les valeurs des Secrets dans la sortie :

Fenêtre de terminal
helm template myapp ./chart --dry-run=client --hide-secret

En v3 : Client-Side Apply (kubectl apply côté client) En v4 : Server-Side Apply activé par défaut (--server-side=true)

SSA délègue la logique de merge au serveur Kubernetes, ce qui apporte :

  • Meilleure gestion des conflits : détection si un autre controller a modifié la ressource
  • Ownership tracking : Kubernetes sait qui a créé chaque champ
  • Dry-run serveur : validation plus précise

Si un autre outil (ArgoCD, kubectl, opérateur) a modifié une ressource, vous verrez :

Error: UPGRADE FAILED: cannot patch "myapp" with kind Deployment:
Apply failed with 1 conflict: conflict with "argocd-application-controller"

Solutions :

  1. Forcer l’ownership (si Helm doit prendre le contrôle) :

    Fenêtre de terminal
    helm upgrade myapp ./chart --force-conflicts
  2. Désactiver SSA (temporairement, pour debug) :

    Fenêtre de terminal
    helm upgrade myapp ./chart --server-side=false
Fenêtre de terminal
helm upgrade myapp ./chart --dry-run=server 2>&1 | grep -i "server-side"

En v3, --wait attendait que les ressources soient “Ready” selon une logique interne. En v4, vous choisissez la stratégie :

ValeurComportement
--wait=hookOnlyAttend seulement les hooks (défaut)
--wait=watcherUtilise kstatus pour surveiller l’état réel
--wait=legacyComportement v3 (rétrocompatibilité)

Le mode watcher utilise kstatus qui comprend mieux l’état des ressources Kubernetes :

  • Détecte les CRDs avec des conditions personnalisées
  • Comprend les états intermédiaires (Progressing, Degraded)
  • Gère les ressources non-standard (Argo Rollouts, Knative, etc.)
Fenêtre de terminal
helm upgrade --install myapp ./chart \
--wait=watcher \
--timeout 5m

Le flag --wait-for-jobs reste disponible :

Fenêtre de terminal
helm upgrade --install myapp ./chart \
--wait=watcher \
--wait-for-jobs \
--timeout 10m

En v4, helm registry login attend uniquement le domaine, pas une URL complète :

Fenêtre de terminal
# Fonctionnait en v3
helm registry login oci://ghcr.io/myorg/charts

Pattern CI/CD recommandé :

Fenêtre de terminal
echo "$REGISTRY_TOKEN" | helm registry login ghcr.io -u "$REGISTRY_USER" --password-stdin

Helm v4 supporte l’installation par digest SHA256 pour des déploiements reproductibles :

Fenêtre de terminal
# Par tag (peut changer si le tag est réécrit)
helm install myapp oci://ghcr.io/myorg/charts/myapp --version 1.2.3
# Par digest (immuable, recommandé pour prod)
helm install myapp oci://ghcr.io/myorg/charts/myapp@sha256:abc123...

Obtenir le digest d’un chart :

Fenêtre de terminal
helm pull oci://ghcr.io/myorg/charts/myapp --version 1.2.3 2>&1 | grep Digest

  1. Auditer vos scripts

    Cherchez les patterns à mettre à jour :

    Fenêtre de terminal
    # Dans vos repos CI/CD
    grep -rn --include="*.yml" --include="*.yaml" --include="*.sh" \
    -E "(--atomic|--force[^-]|--post-renderer [^-]|--dry-run[^=])" .
  2. Installer Helm v4 en parallèle

    Testez sans remplacer v3 :

    Fenêtre de terminal
    # Installer v4 dans un chemin dédié
    curl -fsSL https://get.helm.sh/helm-v4.1.0-linux-amd64.tar.gz | \
    tar -xz && mv linux-amd64/helm /usr/local/bin/helm4
    # Tester
    helm4 version
  3. Tester en environnement de dev

    Fenêtre de terminal
    # Comparer les manifests générés
    helm3 template myapp ./chart -f values.yaml > v3-manifests.yaml
    helm4 template myapp ./chart -f values.yaml > v4-manifests.yaml
    diff v3-manifests.yaml v4-manifests.yaml
  4. Migrer les post-renderers

    Si vous utilisez --post-renderer, convertissez en plugin (voir section dédiée).

  5. Adapter les flags dans CI/CD

    Mettez à jour vos pipelines :

    .gitlab-ci.yml
    deploy:
    script:
    # Avant (v3)
    # - helm upgrade --install myapp ./chart --atomic --wait
    # Après (v4)
    - helm upgrade --install myapp ./chart --rollback-on-failure --wait=watcher
  6. Déployer en staging

    Testez le cycle complet :

    • Install → Upgrade → Rollback → Uninstall
  7. Basculer en production

    Une fois validé en staging, mettez à jour Helm et les scripts en production.


SymptômeCauseSolution
unknown flag: --atomicHelm v4 avec ancien flagRemplacer par --rollback-on-failure
unknown flag: --forceHelm v4 avec ancien flagRemplacer par --force-replace
Apply failed with conflictSSA détecte une modification externeUtiliser --force-conflicts ou coordonner l’ownership
post-renderer plugin not foundPost-renderer non migréConvertir en plugin Helm
Error: login requires exactly one argumentURL au lieu du domaineUtiliser seulement le domaine (ghcr.io)
--dry-run flag needs an argumentSyntaxe v3Utiliser --dry-run=client ou --dry-run=server
Pods non détectés comme ReadyMode wait legacyUtiliser --wait=watcher
Fenêtre de terminal
helm version

Sortie attendue (v4) :

version.BuildInfo{Version:"v4.1.0", GitCommit:"...", GoVersion:"go1.25.6", KubeClientVersion:"v1.35"}

Si vous devez rester compatible temporairement :

Fenêtre de terminal
helm upgrade --install myapp ./chart \
--server-side=false \
--wait=legacy

ChangementAction requise
--atomic--rollback-on-failureRechercher/remplacer dans tous les scripts
--force--force-replaceRechercher/remplacer
Post-renderer binaire → pluginCréer un plugin Helm
--dry-run--dry-run=client|serverSpécifier explicitement la valeur
SSA activé par défautGérer les conflits ownership
--wait--wait=watcherUtiliser pour meilleure détection Ready
OCI login : domaine seulAdapter les scripts de login

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.