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 tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn