Aller au contenu
English
English
Conteneurs & Orchestration medium

Lifecycle Helm : upgrade, history, rollback et uninstall

65 min de lecture

logo helm

Ce guide vous apprend à gérer le cycle de vie complet d'une release Helm. Vous allez maîtriser upgrade, rollback, history et uninstall pour mettre à jour vos applications sans risque, revenir en arrière en cas de problème, et nettoyer proprement. En 20 minutes, vous saurez piloter vos releases comme en production.

Une release n'est pas un simple « déployé ou pas ». Helm lui attribue un statut qui dit ce qu'il a fait en dernier, et un numéro de révision qui s'incrémente à chaque opération. Ces deux informations sont ce que toute commande de diagnostic vous rendra en premier, et savoir les lire évite de relancer un upgrade sur une release déjà bloquée.

Une release Helm peut se trouver dans différents états selon son cycle de vie :

ÉtatSignificationQuand ?
deployedRelease active et fonctionnelleAprès un install ou upgrade réussi
supersededAncienne révision remplacéeAprès un nouvel upgrade ou rollback
pending-installInstallation en coursPendant l'exécution de helm install
pending-upgradeMise à jour en coursPendant l'exécution de helm upgrade
failedÉchec de l'opérationSi les hooks échouent ou timeout atteint
uninstalledRelease supprimée (avec historique)Après helm uninstall --keep-history

À tout moment, une seule révision d'une release porte le statut deployed. Toutes les autres sont en superseded, l'historique, ou en uninstalled si la release a été supprimée avec conservation de l'historique. C'est ce qui permet à helm history de se lire d'un coup d'œil : la ligne deployed est l'état courant, tout le reste est du passé.

Chaque opération sur une release crée une nouvelle révision :

Révision 1 (install) → deployed → superseded
Révision 2 (upgrade) → deployed → superseded
Révision 3 (upgrade) → deployed → superseded
Révision 4 (rollback 2) → deployed ← ACTUELLE

Le rollback ne "revient pas dans le temps" : il crée une nouvelle révision avec la configuration d'une révision précédente.

Le choix entre les deux commandes n'est pas une question de style : chacune refuse la situation de l'autre. C'est la première erreur que rencontre toute personne qui rejoue un script de déploiement, et la comprendre une fois dispense de la subir dix fois.

install et upgrade ne sont pas interchangeables : chacune échoue dans la situation opposée. helm install refuse une release déjà présente, helm upgrade refuse une release absente. Retenez surtout les deux cas d'échec : ce sont eux qui expliquent l'erreur rencontrée tôt ou tard en rejouant un script, et que upgrade --install résout d'un coup.

CommandeRelease existe ?Comportement
helm installNon✅ Crée la release
helm installOui❌ Erreur : cannot reuse a name
helm upgradeNon❌ Erreur : has no deployed releases
helm upgradeOui✅ Met à jour la release

Démonstration : l'erreur d'install sur une release existante

Section intitulée « Démonstration : l'erreur d'install sur une release existante »

Installez une release :

Fenêtre de terminal
helm install mon-api stefanprodan/podinfo -n demo --create-namespace --version 6.7.1

Résultat :

NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:24:49 2026
NAMESPACE: demo
STATUS: deployed
REVISION: 1

Tentez de réinstaller la même release :

Fenêtre de terminal
helm install mon-api stefanprodan/podinfo -n demo --version 6.7.1

Résultat (erreur) :

Error: INSTALLATION FAILED: release name check failed: cannot reuse a name that is still in use

Cette erreur est le symptôme d'un script rejoué, pas d'un problème de chart : la commande a réussi une première fois, et c'est précisément pour cela qu'elle échoue la seconde. La section suivante montre la forme idempotente qui règle le cas une fois pour toutes.

Démonstration : l'erreur d'upgrade sur une release inexistante

Section intitulée « Démonstration : l'erreur d'upgrade sur une release inexistante »

Le cas symétrique du précédent se produit dès qu'une chaîne d'intégration déploie pour la première fois dans un environnement neuf. Le message est explicite, mais il arrive au pire moment, sur une mise en production dont personne n'avait prévu qu'elle serait un premier déploiement.

Fenêtre de terminal
helm upgrade app-inexistante stefanprodan/podinfo -n demo

Résultat (erreur) :

Error: UPGRADE FAILED: "app-inexistante" has no deployed releases

Une commande idempotente rend le même résultat qu'on la joue une fois ou dix. C'est la propriété qui permet à un déploiement automatisé de ne pas avoir à savoir si l'application existe déjà, et donc de ne pas porter de logique conditionnelle fragile.

En CI/CD, vous ne savez pas toujours si la release existe déjà :

  • Premier déploiement : la release n'existe pas → install fonctionne
  • Déploiements suivants : la release existe → install échoue

L'option --install rend helm upgrade idempotent : la commande crée la release si elle n'existe pas, ou la met à jour si elle existe.

Fenêtre de terminal
helm upgrade --install mon-api stefanprodan/podinfo -n demo --version 6.7.1

Si la release n'existe pas :

Release "mon-api" does not exist. Installing it now.
NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:25:42 2026
NAMESPACE: demo
STATUS: deployed
REVISION: 1

Si la release existe déjà :

Release "mon-api" has been upgraded. Happy Helming!
NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:25:49 2026
NAMESPACE: demo
STATUS: deployed
REVISION: 2

Dans une chaîne de déploiement, écrivez toujours helm upgrade --install. La commande est idempotente : elle installe si la release est absente, met à jour si elle existe, et se rejoue autant de fois que nécessaire sans jamais échouer sur l'état antérieur. C'est ce qui permet à la même chaîne de servir un environnement neuf et une mise à jour de production, sans condition ni variable d'aiguillage.

Ces quatre options se retrouvent dans la quasi-totalité des chaînes de déploiement, et chacune répond à un échec observé en production. Retenez surtout que --wait ne sert à rien sans --timeout : sans borne, une chaîne bloquée attend indéfiniment un pod qui ne démarrera jamais.

OptionEffet
--create-namespaceCrée le namespace s'il n'existe pas
--waitAttend que les pods soient Ready avant de terminer
--timeout 5mTimeout pour --wait (défaut: 5m)
--rollback-on-failureRollback automatique si l'upgrade échoue
--description "v1.2.3"Description personnalisée dans l'historique

Commande CI/CD complète :

Fenêtre de terminal
helm upgrade --install mon-api stefanprodan/podinfo \
--namespace demo \
--create-namespace \
--version 6.7.1 \
--wait \
--timeout 3m \
--description "Déploiement v6.7.1 depuis CI"

Un upgrade peut changer deux choses indépendantes : les values, c'est-à-dire votre configuration, et la version du chart, c'est-à-dire le gabarit lui-même. Les distinguer est essentiel au diagnostic, puisque le premier cas relève de vos fichiers et le second de ce que l'auteur du chart a publié.

C'est le cas le plus fréquent : le chart ne bouge pas, seule votre configuration change. Attention au piège de la surcharge partielle : un --set ne reprend pas les values de la révision précédente, il repart des défauts du chart. Tout ce que vous ne redonnez pas revient donc à sa valeur d'origine.

Pour modifier la configuration d'une release existante :

Fenêtre de terminal
helm upgrade mon-api stefanprodan/podinfo -n demo --set replicaCount=2

Résultat :

Release "mon-api" has been upgraded. Happy Helming!
NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:25:12 2026
NAMESPACE: demo
STATUS: deployed
REVISION: 2

Pour passer à une nouvelle version du chart :

Fenêtre de terminal
helm upgrade mon-api stefanprodan/podinfo -n demo --version 6.8.0

Un point de vigilance avant d'aller plus loin : par défaut, helm upgrade repart des values du nouveau chart et oublie vos surcharges. Un upgrade qui ne passe qu'un --set perd donc tout ce que l'installation précédente avait configuré, sans aucun message. Le drapeau --reuse-values rétablit le comportement attendu, et la leçon Personnaliser avec les values mesure précisément ce que cet oubli coûte.

helm upgrade ne met jamais à jour un CRD livré dans le dossier crds/ d'un chart. Il les installe à la première release, puis les ignore pour toujours, quelle que soit leur évolution dans les versions suivantes du chart.

La conséquence se diagnostique mal, parce que rien n'échoue. Montez une version d'un chart d'opérateur qui ajoute un champ à son CRD : l'upgrade rend deployed, les templates sont bien appliqués, et pourtant vos manifestes utilisant le champ neuf sont silencieusement amputés par l'API server, qui valide contre l'ancien schéma. Vous cherchez l'erreur dans votre YAML alors qu'elle est dans un objet que Helm a décidé de ne pas toucher.

Le contrôle tient en une commande, à lancer après toute montée de version d'un chart qui embarque des CRD :

Fenêtre de terminal
kubectl get crd widgets.example.com -o jsonpath='{.spec.versions[*].name}'

La mise à jour, elle, se fait hors de Helm, et c'est assumé par le projet : appliquer un CRD peut casser des ressources existantes, et Helm refuse d'en prendre la responsabilité à votre place.

Fenêtre de terminal
# Extraire le CRD de la nouvelle version du chart, puis l'appliquer soi-même
helm pull stefanprodan/podinfo --version 6.8.0 --untar --untardir /tmp/chart
kubectl apply --server-side -f /tmp/chart/podinfo/crds/

Relisez le CRD avant de l'appliquer : un champ retiré du schéma rend invalides les ressources qui s'en servaient encore.

Le dossier crds/ existe parce que les CRD ne sont pas des ressources comme les autres. Elles doivent être présentes avant les objets qui s'en réclament, or Helm applique tout son rendu en une passe, triée par type. Le dossier crds/ résout cet ordre : Helm l'installe en premier, avant même les templates, et sans le passer par le moteur de rendu. Un CRD n'y est donc jamais un template : pas de {{ }}, pas de values.

Ce traitement à part explique les trois comportements qui surprennent, et qu'il vaut mieux connaître avant de choisir :

MomentCe que Helm fait des CRD de crds/
installles applique en premier, sans rendu de template
upgradene les touche pas, quelle que soit leur évolution
uninstallles conserve, avec toutes leurs instances

L'option --skip-crds permet de ne pas les installer du tout. Vérification faite, le CRD est alors purement et simplement absent du cluster :

Fenêtre de terminal
helm install mon-operateur ./chart --skip-crds
kubectl get crd widgets.example.com
Error from server (NotFound): customresourcedefinitions.apiextensions.k8s.io
"widgets.example.com" not found

Ce n'est pas une option de confort : c'est une décision d'organisation. Elle répond à la question de savoir qui possède les CRD dans votre cluster.

Deux modèles cohabitent, et le pire est de ne pas choisir. Dans le premier, le chart les porte : simple pour un cluster d'une seule équipe, mais chaque release qui installe l'opérateur croit légitimement les posséder. Dans le second, la plateforme les applique hors de Helm, par kubectl apply dans un dépôt dédié, et tous les charts s'installent avec --skip-crds. Ce modèle est le seul tenable dès que plusieurs équipes déploient des opérateurs sur le même cluster, précisément parce qu'un CRD est partagé par tout le cluster alors qu'une release ne l'est pas.

Le cas qui fait perdre une journée : deux charts embarquent le même CRD dans des versions différentes. Le second installé n'écrase rien : Helm ignore les CRD à l'upgrade et refuse de recréer un objet qui existe déjà. Vous obtenez alors un cluster dont le CRD correspond au premier chart installé, et un second opérateur qui échoue sur des champs absents de ce CRD.

Ce qui rend le cas coûteux, c'est que rien ne le signale du côté de Helm : les deux releases sont en deployed, aucune commande n'avertit. Le diagnostic se fait dans le cluster, avec kubectl get crd <nom> -o yaml, en comparant les versions servies à celles qu'attend l'opérateur qui tombe.

Un chart peut lancer du code avant d'appliquer ses ressources, par une annotation helm.sh/hook sur un Job : migration de schéma, préchauffage de cache, contrôle de prérequis. Si ce Job échoue, l'upgrade s'arrête, et le message nomme précisément le coupable :

Error: UPGRADE FAILED: pre-upgrade hooks failed: resource Job/demo/migration
not ready. status: Failed, message: Job Failed. failed: 1/1

Trois questions se posent alors, et les réponses sont plus rassurantes qu'on ne le croit.

Mon application a-t-elle été modifiée ? Non, si le hook était un pre-upgrade. Il s'exécute avant que Helm applique quoi que ce soit : les ressources en place n'ont pas bougé. C'est tout l'intérêt de cette famille de hooks, et la raison de préférer pre-upgrade à post-upgrade pour un contrôle bloquant.

Dans quel état se trouve la release ? L'historique porte la trace de l'échec, et la révision précédente reste la référence :

REVISION STATUS DESCRIPTION
1 deployed Install complete
2 failed Upgrade "mon-api" failed: pre-upgrade hooks failed: ...

Faut-il réparer à la main ? Non plus, dans ce cas. Une fois la cause corrigée, un helm upgrade ordinaire suffit : il crée une révision 3 qui repart de l'état sain. Inutile de supprimer la release, inutile de forcer quoi que ce soit.

Un détail matériel mérite d'être connu, parce qu'il s'accumule en silence : le Job du hook reste dans le cluster après son exécution, réussie ou non. Il est d'ailleurs commode de l'y trouver, ses journaux étant la seule façon de savoir pourquoi la migration a échoué :

Fenêtre de terminal
kubectl logs -n demo job/migration

Mais au bout de trente déploiements, trente Jobs traînent. L'annotation helm.sh/hook-delete-policy décide de leur sort, et le choix se fait entre confort de diagnostic et propreté :

ValeurEffet
before-hook-creationsupprime le Job de l'exécution précédente avant d'en créer un nouveau, c'est le compromis courant
hook-succeededsupprime le Job s'il a réussi, et conserve donc ceux qui ont échoué
hook-failedl'inverse, rarement ce que l'on veut

Quand une API du manifeste n'existe plus dans le cluster

Section intitulée « Quand une API du manifeste n'existe plus dans le cluster »

C'est le blocage le plus déroutant de Helm, parce que rien n'en avertit avant qu'il soit trop tard. Helm conserve dans la release le manifeste tel qu'il l'a appliqué. Si une apiVersion qui s'y trouve disparaît du cluster, parce qu'une montée de version l'a retirée ou parce qu'un CRD a été supprimé, Helm ne sait plus reconstruire l'état courant.

Le symptôme trompe d'abord, car la release paraît en parfaite santé :

Fenêtre de terminal
helm list -n demo
NAME NAMESPACE REVISION STATUS CHART
r1 demo 1 deployed ad-0.1.0

Puis tout échoue. Pas seulement la mise à jour :

Error: UPGRADE FAILED: resource mapping not found for name: "mon-gadget" namespace: ""
from "": no matches for kind "Gadget" in version "audit.example.invalid/v1"
ensure CRDs are installed first

Le retour arrière ne sauve pas, contrairement à ce que l'instinct suggère :

Error: unable to build kubernetes objects from current release manifest:
resource mapping not found for name: "mon-gadget" ...

Et la désinstallation non plus :

Error: failed to delete release: r1

La release est prisonnière : ni mise à jour, ni retour arrière, ni suppression. Trois commandes sur trois refusent, parce que toutes commencent par relire le manifeste stocké.

Le diagnostic tient en une commande, et c'est la seule qui fonctionne encore :

Fenêtre de terminal
helm get manifest r1 -n demo | grep -E '^apiVersion|^kind'

Elle affiche exactement ce que Helm tente de reconstruire, apiVersion fautive comprise. Comparez-la à ce que le cluster connaît :

Fenêtre de terminal
kubectl api-resources | grep -i gadget

La sortie de crise consiste à rendre l'API disponible à nouveau, le temps de débloquer la release. Réappliquer le CRD suffit, vérification faite : l'upgrade repasse immédiatement, la révision avance, et uninstall redevient possible.

Fenêtre de terminal
kubectl apply -f crds/gadget.yaml
helm upgrade r1 ./chart -n demo

La prévention est ici bien plus confortable que la guérison. Avant toute montée de version de cluster, passez en revue ce que vos releases ont réellement appliqué :

Fenêtre de terminal
for r in $(helm list -n demo -q); do
echo "== $r"
helm get manifest "$r" -n demo | grep '^apiVersion' | sort -u
done

C'est la seule façon de voir les apiVersion héritées d'un déploiement ancien, que le chart courant n'utilise peut-être plus mais que la release garde en mémoire.

En Helm v4, le drapeau s'appelle --force-replace : il supprime et recrée les ressources au lieu de les patcher. L'ancien nom --force reste accepté, avec un avertissement de dépréciation à chaque exécution.

Fenêtre de terminal
helm upgrade mon-api stefanprodan/podinfo -n demo --set replicaCount=1 --force-replace

Trois situations le justifient, et elles ont en commun qu'un patch ne peut pas aboutir : la modification d'un champ immutable, comme le selector d'un Deployment, une ressource corrompue qu'une mise à jour partielle ne répare pas, et le débogage d'un problème de synchronisation entre l'état stocké et le cluster.

Ne le confondez pas avec --force-conflicts, qui porte un nom voisin et fait tout autre chose : celui-ci reprend la propriété de champs gérés par un autre acteur en Server-Side Apply, sans rien recréer.

Trois commandes, trois questions différentes, et les confondre fait perdre du temps en incident. helm status répond « où en est cette release maintenant », helm history répond « par quoi est-elle passée », et helm get répond « qu'est-ce qui a été réellement envoyé au cluster ».

C'est la commande à taper en premier, parce qu'elle tient en six lignes ce qu'il faut savoir : quand, où, quelle révision et dans quel état. La suite de la sortie reprend les NOTES du chart, souvent oubliées alors qu'elles contiennent les commandes d'accès à l'application.

Fenêtre de terminal
helm status mon-api -n demo

Résultat :

NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:25:12 2026
NAMESPACE: demo
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl -n demo port-forward deploy/mon-api-podinfo 8080:9898

Décryptage :

ChampSignification
LAST DEPLOYEDDate/heure du dernier déploiement
STATUSÉtat actuel (deployed, failed, etc.)
REVISIONNuméro de la révision actuelle
NOTESInstructions post-installation du chart

Vous pouvez consulter l'état d'une révision passée :

Fenêtre de terminal
helm status mon-api -n demo --revision 1

Résultat :

NAME: mon-api
LAST DEPLOYED: Sun Feb 1 18:24:49 2026
NAMESPACE: demo
STATUS: superseded
REVISION: 1

Le statut superseded indique que cette révision a été remplacée par une plus récente.

L'historique est ce qui rend le rollback possible, et il se lit de bas en haut : la dernière ligne est l'état courant. La colonne DESCRIPTION est la plus utile en incident, puisqu'elle porte le message d'échec de la révision fautive, souvent tronqué mais suffisant pour orienter.

Fenêtre de terminal
helm history mon-api -n demo

Résultat :

REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Sun Feb 1 18:24:49 2026 superseded podinfo-6.7.1 6.7.1 Install complete
2 Sun Feb 1 18:25:12 2026 superseded podinfo-6.7.1 6.7.1 Upgrade complete
3 Sun Feb 1 18:26:56 2026 deployed podinfo-6.7.1 6.7.1 Upgrade complete

Décryptage de chaque colonne :

ColonneContenu
REVISIONNuméro incrémental de la révision
UPDATEDDate/heure de cette révision
STATUSdeployed (actuelle), superseded (ancienne), failed
CHARTNom et version du chart utilisé
APP VERSIONVersion de l'application (définie dans Chart.yaml)
DESCRIPTIONOrigine : Install complete, Upgrade complete, Rollback to X

Helm propose plusieurs commandes get pour inspecter les détails d'une release :

CommandeContenu
helm get valuesValues personnalisées (surcharges)
helm get values --allToutes les values (défauts + surcharges)
helm get manifestManifests Kubernetes générés
helm get notesNotes post-installation
helm get hooksHooks de la release
helm get allTout ce qui précède

Exemple : voir les values d'une révision précédente

Fenêtre de terminal
helm get values mon-api -n demo --revision 1

Résultat :

USER-SUPPLIED VALUES:
null

La révision 1 n'avait aucune surcharge.

Fenêtre de terminal
helm get values mon-api -n demo --revision 2

Résultat :

USER-SUPPLIED VALUES:
replicaCount: 2

La révision 2 a ajouté replicaCount: 2.

Par défaut, Helm conserve les 10 dernières révisions. En CI/CD avec des déploiements fréquents, l'historique peut devenir volumineux.

Fenêtre de terminal
helm upgrade mon-api stefanprodan/podinfo -n demo --history-max 3

Cette option purge automatiquement les révisions les plus anciennes pour n'en garder que 3 :

Fenêtre de terminal
helm history mon-api -n demo

Résultat après plusieurs upgrades avec --history-max 3 :

REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
9 Sun Feb 1 18:28:56 2026 superseded podinfo-6.10.0 6.10.0 Upgrade complete
10 Sun Feb 1 18:29:06 2026 superseded podinfo-6.7.1 6.7.1 Rollback to 7
11 Sun Feb 1 18:29:17 2026 deployed podinfo-6.10.0 6.10.0 Upgrade complete

Le réglage est un compromis, pas une optimisation. Chaque révision conservée est un Secret de plus dans le namespace, donc de l'espace etcd ; chaque révision supprimée est un retour arrière en moins disponible. En production, cinq à dix révisions couvrent la quasi-totalité des besoins : au-delà, un rollback vers une révision très ancienne est de toute façon rarement souhaitable, l'écart de configuration étant devenu trop grand.

Le rollback est la raison d'être de l'historique des révisions. Helm ne rejoue pas votre chart : il réapplique le manifeste stocké de la révision visée, ce qui le rend rapide et indépendant de l'état de vos fichiers. Le prix de cette rapidité est qu'il ne corrige rien en dehors de ce que la release gère.

Le rollback est votre filet de sécurité quand un upgrade dégrade l'application. L'objectif est de restaurer un état stable connu en quelques secondes, sans rejouer un déploiement complet. Les situations ci-dessous partagent le même signal : l'état actuel est cassé et une révision précédente fonctionnait.

  • L'application ne fonctionne plus après un upgrade
  • Les pods sont en CrashLoopBackOff
  • Les métriques montrent des erreurs en hausse
  • Vous devez revenir rapidement à un état stable
Fenêtre de terminal
helm rollback mon-api 2 -n demo

Résultat :

Rollback was a success! Happy Helming!

Vérifiez l'historique après le rollback :

Fenêtre de terminal
helm history mon-api -n demo

Résultat :

REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Sun Feb 1 18:24:49 2026 superseded podinfo-6.7.1 6.7.1 Install complete
2 Sun Feb 1 18:25:12 2026 superseded podinfo-6.7.1 6.7.1 Upgrade complete
3 Sun Feb 1 18:26:56 2026 superseded podinfo-6.7.1 6.7.1 Upgrade complete
4 Sun Feb 1 18:27:10 2026 deployed podinfo-6.7.1 6.7.1 Rollback to 2

Remarquez que le rollback a créé la révision 4, décrite « Rollback to 2 », plutôt que de revenir à la révision 2 elle-même. Helm ne modifie jamais l'historique : il y ajoute toujours. La conséquence est double, et bonne dans les deux sens : la trace du retour arrière reste auditable, et il est possible de revenir en avant en faisant un rollback vers la révision qu'on venait de quitter.

Rollback vers la révision précédente (sans numéro)

Section intitulée « Rollback vers la révision précédente (sans numéro) »

Sans numéro de révision, Helm revient à la révision immédiatement précédente :

Fenêtre de terminal
helm rollback mon-api -n demo

Résultat :

Rollback was a success! Happy Helming!
Fenêtre de terminal
helm history mon-api -n demo

Résultat :

REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
...
4 Sun Feb 1 18:27:10 2026 superseded podinfo-6.7.1 6.7.1 Rollback to 2
5 Sun Feb 1 18:27:41 2026 deployed podinfo-6.7.1 6.7.1 Rollback to 3

Lors d'un rollback, Helm restaure :

ÉlémentRestauré ?
Values (configuration)✅ Oui
Version du chart✅ Oui
Templates générés✅ Oui
Ressources Kubernetes✅ Oui (recréées/patchées)
Données des PVC❌ Non (persistantes)
Données des bases de données❌ Non (externes)
Fenêtre de terminal
helm rollback mon-api 99 -n demo

Résultat :

Error: release has no 99 version

Consultez helm history pour voir les révisions disponibles.

Le rollback accepte les mêmes options qu'un upgrade. La plus utile en production est --wait : sans elle, la commande rend la main dès que Helm a soumis les manifestes, avant même que les pods soient repartis, ce qui donne un faux sentiment de succès. Réservez --force-replace aux cas où un patch ne suffit pas, car il provoque une coupure.

OptionEffet
--waitAttend que les pods soient Ready
--timeout 5mTimeout pour --wait
--forceForce la recréation des ressources
--recreate-podsSupprime et recrée tous les pods

Supprimer une release est moins total qu'il n'y paraît, et c'est la source de la plupart des surprises : certains objets survivent volontairement à la commande, au premier rang desquels les CRD. Cette section montre d'abord la suppression ordinaire, puis ce qu'elle laisse derrière elle.

Sans option, helm uninstall supprime les ressources et l'historique des révisions, ce qui libère le nom de la release. C'est le comportement voulu en environnement de test ; en production, la variante qui conserve l'historique mérite d'être considérée.

Fenêtre de terminal
helm uninstall mon-api -n demo

Résultat :

release "mon-api" uninstalled

Cette commande supprime :

  • La release de la base Helm
  • Les ressources Kubernetes que Helm a rendues depuis templates/
  • L'historique des révisions

Tout ce que Helm a créé n'est pas repris par uninstall, et la commande ne prévient pas. Elle affiche release "mon-api" uninstalled et rend la main, laissant derrière elle des objets que plus aucune release ne revendique.

Le cas le plus important concerne les définitions de ressources personnalisées. Un CRD livré dans le dossier crds/ d'un chart n'est jamais supprimé par helm uninstall : il reste dans le cluster, avec les objets qu'il décrit. C'est délibéré de la part de Helm, parce que supprimer un CRD détruit d'un coup toutes les ressources de ce type, y compris celles créées par d'autres équipes.

ObjetSort après helm uninstall
Ressources rendues depuis templates/supprimées
CRD du dossier crds/conservé, et il faut le supprimer à la main
Objets créés par un opérateur, hors chartconservés
Namespace créé par --create-namespaceconservé

La vérification utile ne se limite donc pas au namespace :

Fenêtre de terminal
helm list -n demo
kubectl get all -n demo
kubectl get crd | grep mon-operateur

Supprimer un CRD est une opération destructrice et non réversible : elle emporte toutes ses instances dans le cluster, y compris celles créées par d'autres équipes. Ne la lancez qu'après avoir compté ce qui en dépend encore.

Fenêtre de terminal
# ❌ À ne jamais lancer sans avoir compté les instances d'abord
kubectl delete crd widgets.example.com

Pour garder une trace de la release supprimée :

Fenêtre de terminal
helm uninstall mon-api -n demo --keep-history

Résultat :

release "mon-api" uninstalled

La release apparaît avec le statut uninstalled, à condition de le demander : par défaut helm list ne montre que les releases déployées.

Fenêtre de terminal
helm list -n demo --uninstalled

Résultat :

NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
mon-api demo 1 Sun Feb 1 18:29:52 2026 uninstalled podinfo-6.7.1 6.7.1

L'historique reste consultable :

Fenêtre de terminal
helm history mon-api -n demo

Résultat :

REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Sun Feb 1 18:29:52 2026 uninstalled podinfo-6.7.1 6.7.1 Uninstallation complete

C'est l'option à retenir pour l'audit : elle conserve la trace de ce qui a été déployé et quand, même après la suppression de l'application. En contrepartie, le nom de la release reste réservé dans le namespace, et une réinstallation sous le même nom échouera tant que l'historique n'aura pas été purgé.

Par défaut, helm list ne montre que les releases déployées, ce qui masque les échecs et les releases supprimées avec --keep-history. Ces filtres deviennent indispensables au diagnostic : --failed révèle un déploiement bloqué qui n'apparaît pas dans la liste normale, et --uninstalled retrouve la trace d'une release effacée dont on veut consulter l'historique.

Fenêtre de terminal
# Releases déployées uniquement (défaut)
helm list -n demo
# Releases avec échec
helm list -n demo --failed
# Releases supprimées (avec --keep-history)
helm list -n demo --uninstalled
# Les révisions remplacées par une plus récente
helm list -n demo --superseded

helm uninstall ne supprime pas :

RessourcePourquoi
PersistentVolumeClaims d'un StatefulSetCréés par volumeClaimTemplates, ils sont gérés par Kubernetes et non par Helm. Un PVC ordinaire, lui, est supprimé par défaut : annotez-le helm.sh/resource-policy: keep pour le conserver
NamespacePeut contenir d'autres ressources
CRDsPeuvent être utilisées par d'autres releases
Ressources créées manuellementNon gérées par Helm

Pour supprimer le namespace et tout son contenu :

Fenêtre de terminal
kubectl delete namespace demo

Ces options n'ont pas d'intérêt en exploration manuelle, mais changent tout dans une chaîne automatisée, où personne ne regarde la sortie. Elles ont un point commun : rendre le comportement de Helm prévisible face à un échec, au lieu de laisser une release à moitié appliquée.

--rollback-on-failure : rollback automatique si échec

Section intitulée « --rollback-on-failure : rollback automatique si échec »

En Helm v4, le drapeau s'appelle --rollback-on-failure. Il combine l'attente des ressources et un retour arrière automatique si le déploiement échoue. Son ancien nom, --atomic, reste accepté mais affiche un avertissement de dépréciation.

Fenêtre de terminal
helm upgrade --install mon-api stefanprodan/podinfo \
-n demo \
--set image.tag=inexistant \
--rollback-on-failure \
--timeout 30s

Si les ressources ne deviennent pas prêtes dans le délai imparti, Helm repart de la révision précédente. Mesuré sur une image inexistante, avec une release saine en révision 1 :

Error: UPGRADE FAILED: release app failed, and has been rolled back due to
rollback-on-failure being set: resource Deployment/atom/app-web not ready.
2 failed Upgrade "app" failed: resource Deployment/atom/app-web not ready...
3 deployed Rollback to 1

L'échec crée donc deux révisions, la tentative ratée puis le retour arrière, et l'image effectivement déployée redevient celle d'origine. Notez que le message parle de rollback-on-failure même quand on a écrit --atomic : Helm a renommé le drapeau, pas le mécanisme.

Fenêtre de terminal
helm upgrade mon-api stefanprodan/podinfo -n demo --set replicaCount=5 --dry-run

Cette commande affiche les manifests qui seraient générés sans les appliquer. Le STATUS affiché est pending-upgrade et le REVISION porte le numéro suivant, ce qui inquiète à tort : il s'agit de la release simulée, pas de la vôtre. Mesuré juste après un --dry-run sur une release en révision 5, la simulation annonce la révision 6 en pending-upgrade alors que helm status rend toujours révision 5, deployed. Aucun Secret n'a été écrit.

Fenêtre de terminal
# Liste des releases en JSON
helm list -n demo -o json
# Historique en YAML
helm history mon-api -n demo -o yaml

Utile pour parser les résultats dans des scripts.

La description est le seul champ libre de l'historique d'une release. Y écrire la version applicative, le ticket ou l'identifiant de la chaîne d'intégration transforme helm history en journal d'exploitation encore lisible des mois plus tard.

Ajoutez une description pour tracer les déploiements :

Fenêtre de terminal
helm upgrade --install mon-api stefanprodan/podinfo \
-n demo \
--description "Ticket JIRA-1234 - Ajout du health check"
Fenêtre de terminal
helm history mon-api -n demo

Résultat :

REVISION UPDATED STATUS CHART DESCRIPTION
1 Sun Feb 1 18:31:30 2026 deployed podinfo-6.7.1 Ticket JIRA-1234 - Ajout du health check

Ce tableau condense tout le cycle de vie en une antisèche à garder sous la main. Si vous ne deviez retenir qu'une ligne, ce serait helm upgrade --install : c'est la seule commande rejouable telle quelle, qui fonctionne au premier déploiement comme aux suivants, et donc la seule à mettre dans un pipeline. Rejouable ne veut pas dire sans effet : chaque passage crée une révision de plus.

CommandeEffet
helm install <name> <chart>Crée une nouvelle release (erreur si existe)
helm upgrade <name> <chart>Met à jour une release existante (erreur si n'existe pas)
helm upgrade --install <name> <chart>Crée ou met à jour (idempotent)
helm status <name>Affiche l'état actuel de la release
helm history <name>Liste toutes les révisions
helm get values <name>Affiche les values personnalisées
helm get manifest <name>Affiche les manifests Kubernetes
helm rollback <name> [revision]Revient à une révision précédente
helm uninstall <name>Supprime la release et ses ressources

Ces quatre symptômes couvrent la majorité des demandes d'aide sur le cycle de vie d'une release. Le point commun des deux premiers est qu'ils se règlent par la même commande, upgrade --install, ce qui explique sa popularité dans les chaînes de déploiement.

SymptômeCause probableSolution
cannot reuse a nameRelease existe déjàUtiliser upgrade --install
has no deployed releasesRelease n'existe pasUtiliser upgrade --install
release has no X versionRévision inexistanteVérifier avec helm history
Pods en Pending après rollbackRessources insuffisantesVérifier les quotas/nodes
PVC encore présent après uninstallComportement normalSupprimer manuellement si souhaité

Ce lab enchaîne les trois moments qui comptent : une release saine, un upgrade fautif, puis le retour en arrière. Jouez-le sur un cluster de test, en observant helm history après chaque étape : c'est l'historique, plus que les pods, qui raconte ce que Helm a fait.

  1. Installer une release stable

    Fenêtre de terminal
    kubectl create namespace helm-lab
    helm install mon-api stefanprodan/podinfo -n helm-lab --version 6.7.1
  2. Vérifier l'état initial

    Fenêtre de terminal
    helm history mon-api -n helm-lab
    kubectl get pods -n helm-lab
  3. Faire un premier upgrade (changement visible)

    Fenêtre de terminal
    helm upgrade mon-api stefanprodan/podinfo -n helm-lab --set replicaCount=3 --set ui.message="Version 2"
  4. Observer la nouvelle révision

    Fenêtre de terminal
    helm history mon-api -n helm-lab
    helm get values mon-api -n helm-lab
  5. Simuler un problème (image inexistante)

    Fenêtre de terminal
    helm upgrade mon-api stefanprodan/podinfo -n helm-lab --set image.tag=fausse-version
  6. Observer l'état cassé

    Fenêtre de terminal
    kubectl get pods -n helm-lab
    # Un ou plusieurs pods en ImagePullBackOff
  7. Rollback vers la révision stable

    Fenêtre de terminal
    helm rollback mon-api 2 -n helm-lab
  8. Vérifier le retour à la normale

    Fenêtre de terminal
    helm history mon-api -n helm-lab
    kubectl get pods -n helm-lab
    # Tous les pods Running
  9. Nettoyer

    Fenêtre de terminal
    helm uninstall mon-api -n helm-lab
    kubectl delete namespace helm-lab

Critères de réussite :

  • helm history montre au moins 4 révisions
  • Vous identifiez la révision problématique
  • Le rollback ramène les pods en Running
  • Vous comprenez la relation révision ↔ configuration

  • helm upgrade --install est la commande idempotente pour CI/CD
  • Chaque opération crée une nouvelle révision dans l'historique
  • helm history permet de consulter toutes les révisions
  • helm rollback crée une nouvelle révision avec l'ancienne config
  • helm uninstall supprime les ressources mais pas les données persistantes
  • Utilisez --rollback-on-failure en production pour rollback automatique en cas d'échec
  • Limitez l'historique avec --history-max pour éviter l'accumulation

Huit questions sur ce que Helm fait et ne fait pas : les CRD qu'un upgrade ignore et qu'un uninstall conserve, l'effet de --skip-crds, l'état d'une release après l'échec d'un hook, et le blocage total quand une apiVersion disparaît.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

9 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

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

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. 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