Helm rend le packaging des applications Kubernetes reproductible, mais de nombreux incidents en production trouvent encore leur origine dans de petites erreurs de configuration. La bonne nouvelle : la plupart de ces erreurs sont prévisibles et évitables avec un mode opératoire cohérent. Ce guide montre comment prévenir les erreurs de configuration Helm les plus courantes, vérifier les changements en toute sécurité et revenir rapidement en arrière quand quelque chose ne se comporte pas comme prévu.
Vous obtiendrez :
- Un processus d'inventaire court pour ancrer vos versions, espaces de noms et contexte de release.
- Un chemin de configuration sûr avec linting, rendu local et dry runs.
- Des exemples de configuration pratiques qui démontrent l'erreur, le symptôme et la correction.
- Des étapes de vérification et de dépannage que vous pouvez exécuter immédiatement.
- Des modes de défaillance et habitudes de rollback qui réduisent le temps d'indisponibilité.
- Une liste de contrôle opérationnelle concise pour rendre tout cela reproductible.
Cet article suppose que vous utilisez déjà Helm pour déployer un ou plusieurs charts vers Kubernetes.
Inventaire des versions et de l'environnement
Avant de modifier toute configuration, capturez les faits de votre environnement. Cela réduit les conjectures, simplifie la vérification et rend le rollback précis.
Prérequis :
- Un contexte kubeconfig fonctionnel pour le cluster cible.
- Helm 3.x installé sur votre poste de travail.
- kubectl installé avec accès aux espaces de noms cibles.
- Accès réseau et permissions RBAC pour lire et écrire les objets Kubernetes pertinents.
Commandes d'inventaire :
# Enregistrer les versions client Helm et Kubernetes
helm version
kubectl version --short
# Confirmer le contexte cible et les espaces de noms
kubectl config current-context
kubectl get ns
# Identifier le chart et la release que vous allez modifier
helm ls -n <namespace>
helm status <release> -n <namespace>
# Optionnel : capturer les valeurs et manifestes actuels
helm get values <release> -n <namespace> --all > current-values.yaml
helm get manifest <release> -n <namespace> > current-manifest.yaml
Définir un pilote étroit :
- Choisissez une release et un petit changement mesurable (par exemple, changer un port de Service, activer une seule règle Ingress, ou figer un tag d'image).
- Prévoyez de rendre et d'inspecter le changement localement avant toute écriture dans le cluster.
- Décidez de la cible de rollback (révision Helm précédente) avant de commencer.
Chemin de configuration sûr
Un chemin sûr est petit, observable et réversible. Suivez ces étapes pour chaque changement.
1. Commencez par un fichier de valeurs, pas seulement des drapeaux --set
- Conservez un
values.yamlde base et des fichiers d'overlay (par exemple,values.dev.yaml,values.prod.yaml). - Évitez les longues chaînes de drapeaux
--setqui peuvent introduire des bugs subtils de type ou d'échappement.
2. Lintez le chart
helm lint <répertoire_chart_ou_ref_chart>
Corrigez les avertissements, surtout ceux concernant les API dépréciées ou les erreurs de template.
3. Rendez les templates localement avec vos valeurs
helm template <release> <chart> \
-n <namespace> \
-f values.yaml \
--values values.<env>.yaml > rendered.yaml
Inspectez rendered.yaml pour les objets Kubernetes exacts que Helm soumettra. Confirmez que les espaces de noms, labels et noms de ressources correspondent aux attentes.
4. Faites un dry-run de l'upgrade avec sortie de débogage complète
helm upgrade --install <release> <chart> \
-n <namespace> \
-f values.yaml \
-f values.<env>.yaml \
--create-namespace \
--dry-run --debug
Cherchez les avertissements ou messages de validation côté serveur dans la sortie.
5. (Optionnel) Différenciez le changement
Si vous avez le plugin diff installé, comparez l'état live à vos nouvelles valeurs avant d'appliquer :
helm diff upgrade <release> <chart> -n <namespace> -f values.yaml -f values.<env>.yaml
6. Appliquez avec garde-fous
helm upgrade --install <release> <chart> \
-n <namespace> \
-f values.yaml \
-f values.<env>.yaml \
--wait --timeout 5m --atomic
--wait attend la disponibilité, --atomic fait un rollback automatique en cas d'échec.
Erreurs de configuration pratiques et corrections
Les exemples ci-dessous sont construits pour illustrer des problèmes courants et ne font référence à aucune organisation spécifique.
1) Types booléens et numériques modifiés silencieusement avec --set
Erreur :
# Intention : définir la chaîne "080" et la chaîne booléenne "false"
helm upgrade --install web mychart \
--set app.code=080 \
--set feature.enabled=false
Symptôme :
app.codedevient le nombre80, perdant le zéro initial.feature.enableddevient le booléenfalsemême si le chart attend une chaîne.
Correction :
# Forcer les types chaîne quand nécessaire
helm upgrade --install web mychart \
--set-string app.code=080 \
--set-string feature.enabled=false
Mieux : placez ces valeurs dans des fichiers où le guillemet est explicite.
2) Les points dans les clés sont interprétés comme séparateurs de chemin
Erreur :
helm upgrade --install api mychart --set config.db.host=my.db.local
Si le schéma de valeurs attend une clé littérale config.db (peu probable mais vu), le point divise le chemin à tort.
Correction :
# Échapper les points dans les clés
helm upgrade --install api mychart --set "config\.db".host=my.db.local
Préférez le YAML explicite pour les clés complexes.
3) L'indentation YAML inverse maps et listes
Erreur dans values.yaml :
# Visé : une liste de noms d'hôtes
ingress:
hosts:
- app.example.com
- api.example.com
# Édition ultérieure introduit une mauvaise indentation
ingress:
hosts:
- app.example.com
api.example.com
Symptôme :
- Le YAML est analysé incorrectement ;
helm templatepeut réussir, mais la spécification Ingress est invalide au moment de l'application.
Correction :
- Utilisez une indentation cohérente (2 espaces typiques) et lancez un linter YAML.
- Validez avec
helm templateet un validateur YAML avant l'upgrade.
4) Requêtes et limites de ressources typées incorrectement
Erreur :
resources:
requests:
cpu: 100 # devrait être une chaîne avec unité, comme "100m"
memory: 256 # unité manquante, devrait être "256Mi"
Symptôme :
- Kubernetes rejette ou interprète mal les quantités.
Correction :
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "200m"
memory: "512Mi"
5) Ingress activé sans Service ou annotations correspondants
Erreur :
ingress:
enabled: true
className: nginx
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
Le nom/port du Service du chart ne correspond pas au backend Ingress.
Symptôme :
- L'objet Ingress existe mais renvoie 502/404.
Correction :
- Assurez-vous que le câble correctement les références de Service. Pour les charts attendant des valeurs comme
service.port, définissez-le explicitement :
service:
port: 8080
- Confirmez que le backend Ingress rendu référence le bon nom et port de Service dans
rendered.yaml.
6) Secrets : pré-encodage vs encodage par template
Erreur :
# values.yaml
secret:
username: admin
password: cGFzc3dvcmQ= # base64 pré-encodé
Si le template du chart encode aussi en base64 les valeurs, le mot de passe devient doublement encodé.
Correction :
- Suivez le contrat du chart. Si le template utilise
b64enc, fournissez du texte clair dans les valeurs :
secret:
username: admin
password: password123
- Vérifiez que les données du Secret rendu ne comportent qu'un seul encodage base64.
7) Valeurs globales vs spécifiques au chart en collision
Erreur :
global:
image:
tag: latest
# Mais le subchart attend app.image.tag spécifiquement
Symptôme :
- Les subcharts peuvent ignorer les paramètres globaux ; le tag d'image dérive.
Correction :
- Définissez les clés spécifiques au chart que le chart documente, ou utilisez des requirements qui mappent correctement les valeurs globales.
- Figer les tags d'image explicitement (évitez
latest) pour des déploiements déterministes :
app:
image:
repository: ghcr.io/example/app
tag: 1.4.2
8) Confusion entre espace de noms et nommage de release
Erreur :
# L'absence de --namespace déploie dans l'espace de noms par défaut du contexte courant
helm upgrade --install api mychart
Symptôme :
- Les ressources apparaissent dans le mauvais espace de noms ; les Services ou règles Ingress ne trouvent pas les backends.
Correction :
helm upgrade --install api mychart -n platform --create-namespace
Spécifiez toujours --namespace, et vérifiez les labels app.kubernetes.io/instance pour scopper les ressources.
9) Valeurs requises manquantes
Erreur : Laisser une valeur requise que le chart attend (par exemple, replicaCount ou une valeur de secret obligatoire).
Symptôme :
- Erreurs de template ou échecs à l'exécution.
Correction :
- De nombreux charts utilisent la fonction
requireddans les templates. Fournissez la valeur dans votre YAML, et validez avechelm templatepour attraper l'erreur localement d'abord.
10) CRDs et ordonnancement
Erreur :
- Appliquer un chart qui crée des objets CustomResource avant que leurs CRDs n'existent, ou modifier des CRDs en cours d'upgrade.
Symptôme :
- Le serveur API rejette les ressources ; l'upgrade échoue.
Correction :
- Installez ou mettez à jour les CRDs en premier si le chart exige une approche par étapes, ou utilisez des charts qui gèrent les CRDs dans un répertoire
crds/traité en pre-install. - Validez
Capabilities.APIVersionsdans les manifestes rendus pour vous assurer que les versions d'API existent dans votre cluster.
Tableau de référence rapide : Erreurs, symptômes et corrections
| Erreur | Symptôme | Vérification rapide | Correction plus sûre |
|---|---|---|---|
Coercition de type --set | Booléens/entiers incorrects | helm get values --all | Utiliser --set-string ou YAML |
| Points dans les clés | Mauvaise résolution de chemin | Inspecter rendered.yaml | Échapper les points ou utiliser YAML |
| Mauvaise indentation YAML | Erreurs d'application/analyse | Lint YAML + helm template | Corriger l'indentation, valider localement |
| Unités de ressources incorrectes | K8s rejette la quantité | kubectl describe events | Utiliser "100m", "256Mi" |
| Ingress mal aligné | 404/502 via Ingress | kubectl describe ingress | Aligner nom/port du Service |
| Secrets doublement encodés | Échec d'authentification | Inspecter le Secret rendu | Fournir du texte clair si templaté |
| Clés globales vs chart | Images dérivées | helm template diff | Définir clés spécifiques au chart |
--namespace manquant | Mauvais espace de noms | kubectl get all -n <ns> | Toujours passer --namespace |
| Valeur requise manquante | Erreur de template | helm template --debug | Définir valeurs requises |
| Ordonnancement CRD | API rejette les CRs | kubectl api-resources | Appliquer CRDs avant CRs |
Vérification et diagnostics
Après avoir appliqué un changement, vérifiez l'état Helm et l'état d'exécution Kubernetes.
Vérifications immédiates :
# Release existe, déployée, et saine
helm ls -n <namespace>
helm status <release> -n <namespace>
# Quelles valeurs sont actives ?
helm get values <release> -n <namespace> --all
# Qu'est-ce que Helm a appliqué ?
helm get manifest <release> -n <namespace> | head -n 80
Vérifications de santé des charges de travail :
# Les pods devraient être Running ou Completed
kubectl get pods -n <namespace> -l app.kubernetes.io/instance=<release>
# Examiner la disponibilité et les événements pour un pod en échec
kubectl describe pod <pod> -n <namespace>
# Les endpoints de Service devraient être peuplés
kubectl get svc -n <namespace>
kubectl get endpoints -n <namespace>
# Si utilisation d'Ingress
kubectl get ingress -n <namespace>
kubectl describe ingress <name> -n <namespace>
Accessibilité de l'application (exemple construit) :
# Port-forward pour tester un Service sans impliquer Ingress
kubectl port-forward deploy/<deployment> -n <namespace> 8080:8080 &
curl -I http://127.0.0.1:8080/healthz
Résultat attendu : HTTP 200 depuis l'endpoint de santé. Sinon, vérifiez les logs du conteneur et les probes de disponibilité.
Inspection des logs :
kubectl logs deploy/<deployment> -n <namespace> --tail=200
Valider les objets de configuration :
- Les ConfigMaps et Secrets portent souvent l'erreur. Dumpez et examinez les données rendues.
kubectl get configmap <name> -n <namespace> -o yaml
kubectl get secret <name> -n <namespace> -o yaml
Si un chart attend du texte clair dans les valeurs et encode en base64 dans le template, vous devriez voir une seule couche base64 dans Secret.data.
Modes de défaillance et récupération
Même avec des garde-fous, les erreurs arrivent. Reconnaissez ces motifs et récupérez vite.
1. L'upgrade échoue et Helm fait un auto-rollback (--atomic)
- Symptôme :
helm upgradesort avec code non-zéro ;helm statusmontre la dernière révision réussie. - Action : Inspectez les logs et le diff de la révision échouée.
helm history <release> -n <namespace>
# Voir les valeurs d'une révision précédente
helm get values <release> -n <namespace> --revision <rev> --all
Corrigez les valeurs ou le template, relancez avec --dry-run d'abord, puis appliquez.
2. Release bloquée en pending-upgrade ou pending-install
- Symptôme :
helm lsmontre STATUSpending-upgrade. - Action : Identifiez les hooks ou Jobs bloquants.
kubectl get jobs -n <namespace> -l app.kubernetes.io/instance=<release>
kubectl describe job <name> -n <namespace>
Si un Job hook est bloqué, adressez sa cause (image pull, permissions, arguments). Si nécessaire, supprimez le Job échoué et relancez l'upgrade.
3. Ressources partiellement appliquées causent des erreurs d'exécution
- Symptôme : Certains Deployments mis à jour, d'autres non ; Services pointent vers des backends non prêts.
- Action : Revenez à une révision connue-bonne et regroupez.
helm history <release> -n <namespace>
helm rollback <release> <revision> -n <namespace> --wait
4. Déploiement dans le mauvais espace de noms
- Symptôme : Ressources absentes de l'espace de noms attendu mais présentes ailleurs.
- Action : Désinstallez du mauvais espace de noms et installez dans le bon.
helm uninstall <release> -n <wrong-ns>
helm upgrade --install <release> <chart> -n <right-ns> --create-namespace -f values.yaml
5. Échecs liés aux CRDs
- Symptôme : Le serveur API rejette les CustomResources avec message comme "no matches for kind".
- Action : Assurez-vous que les CRDs existent aux versions cibles avant d'appliquer les objets. Si un chart mélange upgrades de CRDs et mises à jour d'objets CR, procédez en deux étapes : CRDs d'abord, puis la release.
6. CrashLoopBackOff dû à un mauvais ConfigMap ou Secret
- Symptôme : Les pods redémarrent en boucle ; les logs font référence à une mauvaise config.
- Action : Faites un rollback ou corrigez la config à chaud.
# Réparation la plus rapide : rollback vers la dernière bonne révision
helm rollback <release> <good-rev> -n <namespace> --wait
# Ou patchez les valeurs et refaites l'upgrade en sécurité
helm upgrade <release> <chart> -n <namespace> -f values.yaml --dry-run --debug
helm upgrade <release> <chart> -n <namespace> -f values.yaml --wait --atomic
Validation de la récupération :
- Après rollback, relancez les étapes de Vérification. Confirmez que les états des pods se stabilisent, les Services ont des endpoints, et l'Ingress répond.
Liste de contrôle opérationnelle
Utilisez cette liste concise pour chaque changement de configuration Helm.
| Étape | Commande ou extrait | Résultat attendu |
|---|---|---|
| Capturer l'état actuel | helm get values <rel> -n <ns> --all > current-values.yaml | Vous avez un point de départ réversible |
| Linter | helm lint <chart> | Aucune erreur ; avertissements revus |
| Rendre localement | helm template <rel> <chart> -n <ns> -f values.yaml > rendered.yaml | Manifestes correspondent à l'intention |
| Dry-run | helm upgrade --install <rel> <chart> -n <ns> -f values.yaml --dry-run --debug | Validation côté serveur passe |
| Diff optionnel | helm diff upgrade <rel> <chart> -n <ns> -f values.yaml | Ensemble de changements clair et minimal |
| Appliquer avec gardes | helm upgrade --install <rel> <chart> -n <ns> -f values.yaml --wait --timeout 5m --atomic | Release atteint statut deployed |
| Vérifier l'exécution | kubectl get/describe; logs; health checks | Pods prêts, Services et Ingress sains |
| Enregistrer la révision | helm history <rel> -n <ns> | Cible de rollback connue identifiée |
Conclusion
La plupart des incidents Helm proviennent d'un petit ensemble d'erreurs de configuration : coercition de type avec --set, problèmes d'indentation YAML, câblage mal aligné entre Service et Ingress, quantités de ressources mal typées, valeurs requises manquantes, et confusion d'espaces de noms. Vous pouvez en prévenir presque toutes en faisant des changements petits et mesurables que vous pouvez rendre et inspecter localement d'abord ; en utilisant des fichiers de valeurs avec guillemets et structure explicites au lieu de longues chaînes --set ; en lintant, templatant et dry-runnant avant de toucher au cluster ; en appliquant avec --wait, --timeout et --atomic pour que les erreurs s'annulent d'elles-mêmes ; en vérifiant à la fois la vue de Helm et l'état d'exécution Kubernetes après chaque changement ; et en gardant une cible de rollback claire avec des étapes de récupération répétées. Adoptez la liste de contrôle, commencez par un pilote étroit, et faites-en le mode opératoire par défaut de votre équipe. Vous livrerez des changements Helm plus vite, avec moins de surprises, et quand quelque chose casse, vous saurez exactement comment le voir, le corriger, et continuer.