E-NO
Kubernetes 7 min de lecture

Erreurs courantes avec les Secrets Kubernetes et leurs correctifs, avec exemples pratiques

calendar_today Publié : 2026-08-26
update Dernière mise à jour : 2026-08-26
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Erreurs courantes avec les Secrets Kubernetes et leurs correctifs, avec exemples pratiques ».

Introduction

Les Secrets Kubernetes stockent des données sensibles telles que des mots de passe, des jetons et des clés. Lorsqu'un Secret est mal configuré, les charges de travail échouent d'une manière qui peut ressembler à des bogues d'application. Un Pod peut rester dans l'état ContainerCreating, planter avec CreateContainerConfigError, ou s'exécuter avec des variables d'environnement manquantes. Souvent, la cause profonde est une discordance de nom, un format de données incorrect, un Secret manquant ou un refus RBAC.

Cet article offre aux opérateurs, développeurs, consultants DevOps et équipes techniques de startups un flux de travail de dépannage pratique pour les erreurs courantes des Secrets Kubernetes. Chaque section associe une défaillance observée à un correctif concret et à une commande de vérification. L'accent est mis sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.

Chaque étape est définie pour un cluster Kubernetes typique exécutant la version 1.27 ou plus récente, utilise kubectl 1.27, et repose uniquement sur les objets d'API de base. Aucune fonctionnalité spécifique au cloud n'est requise.

Inventaire des versions et de l'environnement

Avant de toucher à un Secret, enregistrez la version du cluster, la version du client, l'espace de noms et le contexte de la charge de travail. Une discordance entre le client et le serveur produit souvent des erreurs trompeuses.

Exécutez ces observations en lecture seule :

kubectl version --short
kubectl cluster-info
kubectl get nodes -o wide
kubectl config current-context
kubectl config view --minify

La sortie attendue inclut une version client et serveur, telles que Client Version: v1.27.3 et Server Version: v1.27.4. Si la version du serveur est antérieure à 1.19, certaines fonctionnalités de Secret comme immutable peuvent ne pas être disponibles.

Identifiez la charge de travail et l'espace de noms exacts :

kubectl get pods -n payments -o wide
kubectl get deployments -n payments
kubectl get secrets -n payments

Enregistrez l'état du Pod. Un Pod bloqué dans ContainerCreating pendant plus d'une minute indique souvent une erreur de tirage d'image ou un problème de montage de Secret. Un Pod dans CrashLoopBackOff suggère que l'application a démarré puis a échoué, peut-être parce qu'une variable d'environnement attendue était vide.

Capturez les événements du Pod :

kubectl describe pod <pod-name> -n payments

Recherchez des événements comme FailedMount, Failed to pull image, ou CreateContainerConfigError. Ce sont les premiers signaux qu'un Secret est impliqué.

Vérifiez la politique de tirage d'image et la référence de Secret utilisée par le déploiement :

kubectl get deployment <deployment-name> -n payments -o yaml

Notez le champ imagePullSecrets et toute référence envFrom ou volume aux Secrets.

Avant de modifier quoi que ce soit, enregistrez un instantané des définitions de Secret actuelles (si possible sans les valeurs) :

kubectl get secrets -n payments -o yaml | sed '/data:/,/stringData:/d' > secrets-metadata-$(date +%Y%m%d-%H%M%S).yaml

Cette commande supprime les données base64 et ne conserve que les métadonnées et le type. Elle peut être stockée en toute sécurité dans un wiki d'équipe ou un rapport d'incident.

Gardez le test local petit. Appliquez un seul manifeste, inspectez les ressources générées et vérifiez le trafic avec kubectl port-forward avant de passer à un équilibreur de charge cloud ou à un contrôleur d'entrée.

Question rapide 1 sur 2

Que se passe-t-il si un Pod référence un Secret non optionnel qui n'existe pas ?

Selon la référence [3], par défaut, les Secrets sont obligatoires, et aucun des conteneurs d'un Pod ne démarrera tant que tous les Secrets non optionnels ne sont pas disponibles.

Chemin de configuration sécurisé

Les Secrets sont référencés par nom. Une erreur courante est une discordance entre le nom du Secret dans la spécification du Pod et l'objet Secret réel. Kubernetes ne crée pas de Secret par défaut s'il est manquant ; il fait simplement échouer le montage ou l'injection d'environnement.

Exemple : Référence de Secret manquante

Un déploiement recherche un Secret nommé db-credentials, mais le Secret créé est database-credentials.

Observez l'échec :

kubectl describe pod <pod-name> -n payments

Les événements affichent :

Warning  FailedMount  2m (x8 over 5m)  kubelet  MountVolume.SetUp failed for volume "db-secret" : secret "db-credentials" not found

Le correctif le plus simple est de renommer le Secret ou de mettre à jour la référence. Pour renommer le Secret, créez-en un nouveau avec le nom attendu et copiez les données :

kubectl get secret database-credentials -n payments -o json | \
  jq '.metadata.name = "db-credentials"' | \
  kubectl apply -f -

Vérifiez que le Secret existe maintenant :

kubectl get secret db-credentials -n payments

Puis observez le redémarrage du Pod et le montage correct :

kubectl rollout restart deployment <deployment-name> -n payments
kubectl rollout status deployment/<deployment-name> -n payments

État attendu : deployment "<deployment-name>" successfully rolled out.

Exemple : Mauvaise clé de données

Un Pod consomme DATABASE_PASSWORD depuis un Secret, mais le Secret a la clé db-password.

Inspectez les clés du Secret sans révéler les valeurs :

kubectl get secret app-secrets -n payments -o jsonpath='{.data}' | jq 'keys'

La sortie attendue pourrait être :

["db-password", "db-user"]

Si l'application attend DATABASE_PASSWORD, corrigez le Secret en ajoutant ou en renommant la clé. Au lieu de modifier le Secret existant, créez une version corrigée avec les mêmes données mais une nouvelle clé :

kubectl get secret app-secrets -n payments -o json | \
  jq '.data.DATABASE_PASSWORD = .data["db-password"] | del(.data["db-password"])' | \
  kubectl apply -f -

Ensuite, redémarrez le Pod et vérifiez que la variable d'environnement est correctement définie dans le conteneur en cours d'exécution :

kubectl get pod <pod-name> -n payments -o jsonpath='{.spec.containers[0].env}' | jq

Recherchez {"name":"DATABASE_PASSWORD","valueFrom":{"secretKeyRef":{"name":"app-secrets","key":"DATABASE_PASSWORD"}}}.

Exemple : Échec de mise à jour d'un Secret immuable

Si un Secret est marqué immutable: true, Kubernetes empêche toute modification de ses données. C'est bon pour la sécurité, mais cela perturbe les équipes qui tentent de faire une rotation des informations d'identification.

Observez l'erreur lors de la mise à jour :

kubectl apply -f updated-secret.yaml

Sortie :

Error from server (Forbidden): error when applying patch: secrets "app-secrets" is immutable, updates are not allowed

La récupération consiste à créer un nouveau Secret avec un nom versionné, puis à mettre à jour la charge de travail pour référencer le nouveau Secret. Cela évite de muter l'ancien Secret et conserve un chemin de retour en arrière.

Exemple de nom de Secret versionné : app-secrets-v2.

Créez-le :

kubectl create secret generic app-secrets-v2 \
  --from-literal=DATABASE_PASSWORD='new-value' \
  --from-literal=DATABASE_USER='admin' \
  -n payments

Mettez à jour le déploiement pour référencer app-secrets-v2 et déclenchez un déploiement progressif :

kubectl set env deployment/<deployment-name> \
  --from=secret/app-secrets-v2 \
  -n payments
kubectl rollout restart deployment/<deployment-name> -n payments

Vérifiez le déploiement, puis supprimez éventuellement l'ancien Secret après avoir confirmé que le nouveau fonctionne.

Gardez tout test local aussi petit que possible : appliquez un seul manifeste, inspectez les ressources générées et vérifiez le trafic avec kubectl port-forward avant de passer à un équilibreur de charge cloud ou à un contrôleur d'entrée.

Vérification et diagnostics

Après un correctif, vérifiez que le Secret est correctement monté et que l'application voit les valeurs attendues. Ne supposez pas que parce que le Pod est Running, les données sont correctes.

Vérifier le montage du Secret dans un volume

Si un Secret est monté en tant que volume, listez les fichiers montés :

kubectl exec <pod-name> -n payments -- ls -l /etc/secrets

La sortie attendue montre des fichiers nommés d'après les clés du Secret, par exemple :

-rw-r--r-- 1 root root 13 Apr 12 09:15 DATABASE_PASSWORD
-rw-r--r-- 1 root root  5 Apr 12 09:15 DATABASE_USER

Inspectez ensuite le contenu d'un fichier pour vérifier qu'il correspond à la valeur prévue (faites attention à ne pas le journaliser dans un terminal partagé) :

kubectl exec <pod-name> -n payments -- cat /etc/secrets/DATABASE_PASSWORD

Si le contenu est vide ou encodé en base64, les données du Secret peuvent être mal formées.

Vérifier l'injection de variables d'environnement

Pour les Secrets basés sur l'environnement, imprimez les variables d'environnement du conteneur en cours d'exécution :

kubectl exec <pod-name> -n payments -- printenv | grep DATABASE

Sortie attendue :

DATABASE_PASSWORD=secret123
DATABASE_USER=admin

Si la variable est manquante, vérifiez à nouveau la spécification du Pod et la clé du Secret.

Déboguer les échecs de tirage d'image liés aux Secrets

Un Pod peut échouer avec ImagePullBackOff si l'image est dans un registre privé et que le imagePullSecret est manquant ou incorrect.

Tout d'abord, vérifiez que le Secret existe et a le type kubernetes.io/dockerconfigjson :

kubectl get secret regcred -n payments -o jsonpath='{.type}'

Attendu : kubernetes.io/dockerconfigjson.

Si le type est Opaque, le Secret n'est pas utilisable comme secret de tirage d'image. Recréez-le correctement :

kubectl create secret docker-registry regcred \
  --docker-server=myregistry.example.com \
  --docker-username=deploy \
  --docker-password=$(cat /path/to/password) \
  [email protected] \
  -n payments

Mettez ensuite à jour le déploiement pour inclure le secret de tirage d'image :

kubectl patch deployment <deployment-name> -n payments -p '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"regcred"}]}}}}'

Surveillez le déploiement :

kubectl rollout status deployment/<deployment-name> -n payments

Si les informations d'identification du registre sont toujours erronées, les événements affichent :

Failed to pull image "myregistry.example.com/app:1.0": rpc error: code = Unknown desc = Error response from daemon: pull access denied

Corrigez le Secret et relancez le déploiement.

Utiliser un Pod de débogage temporaire pour tester l'accès au Secret

Au lieu de déboguer une charge de travail défaillante, exécutez un Pod jetable avec la même référence de Secret :

kubectl run secret-test -n payments --rm -i --tty \
  --image=alpine --restart=Never -- \
  sh -c 'apk add --no-cache coreutils >/dev/null; \
         echo "User: $DATABASE_USER"; \
         echo "Password: $DATABASE_PASSWORD"'

Si aucune sortie n'apparaît, l'injection d'environnement a échoué. Vérifiez les événements du Pod :

kubectl describe pod secret-test -n payments

Supprimez le Pod de test après le diagnostic.

Question rapide 2 sur 2

Quelle méthode d'injection de secrets dans les pods est préférée à l'octroi aux comptes de service d'un accès RBAC aux secrets ?

Selon la référence [2], les pods ayant besoin de secrets devraient les voir automatiquement montés via des volumes, de préférence stockés en mémoire comme avec l'option emptyDir.medium, et cela devrait être fait de préférence à l'octroi au compte de service du pod d'un accès RBAC aux secrets.

Modes de défaillance et récupération

Cette section répertorie des modes de défaillance spécifiques liés aux Secrets, leurs symptômes et les étapes de récupération.

Défaillance 1 : Secret introuvable

Symptôme : Pod bloqué dans ContainerCreating, les événements affichent MountVolume.SetUp failed ... secret not found.

Cause : Le Secret référencé dans volumeMounts ou envFrom n'existe pas.

Récupération :

  1. Listez les Secrets existants : kubectl get secrets -n payments.
  2. Comparez les noms, y compris l'espace de noms. Les Secrets sont limités à l'espace de noms ; un Secret dans l'espace de noms par défaut ne peut pas être utilisé par un Pod dans un autre espace de noms.
  3. Soit créez le Secret manquant avec le nom attendu, soit corrigez la référence.
  4. Redémarrez le Pod : kubectl delete pod <pod-name> -n payments (pour un déploiement, utilisez kubectl rollout restart).

Défaillance 2 : Les données du Secret sont encodées en base64 de manière incorrecte

Symptôme : L'application voit des valeurs tronquées ou vides, ou kubectl describe secret montre une taille inattendue.

Cause : Lors de la création d'un Secret à partir d'un fichier YAML, les données doivent être encodées en base64. Si vous mettez du texte en clair dans le champ data, Kubernetes tentera de le décoder et pourra échouer ou produire des octets incorrects.

Mauvais exemple :

apiVersion: v1
kind: Secret
metadata:
  name: bad-secret
type: Opaque
data:
  password: mypassword

Ceci est invalide car mypassword n'est pas une base64 valide ; l'application échouera avec invalid base64.

Exemple correct utilisant stringData pour le texte en clair :

apiVersion: v1
kind: Secret
metadata:
  name: good-secret
type: Opaque
stringData:
  password: mypassword

stringData est fusionné dans data automatiquement, avec un encodage base64 correct.

Récupération :

  1. Inspectez le Secret : kubectl get secret bad-secret -n payments -o yaml et regardez le champ data.
  2. Recréez le Secret en utilisant stringData ou un encodage base64 approprié.
  3. Mettez à jour la référence de la charge de travail si nécessaire.
  4. Vérifiez avec kubectl exec ou un Pod de débogage temporaire.

Défaillance 3 : Secret consommé en volume mais permissions incorrectes

Symptôme : Pod en cours d'exécution, mais l'application ne peut pas lire les fichiers du Secret montés (Permission denied).

Cause : Le mode de fichier par défaut pour les volumes de Secret est 0644, mais certains conteneurs s'exécutent en tant qu'utilisateur non root (par exemple, securityContext.runAsUser: 1000) et ont besoin que le fichier soit lisible par cet utilisateur. Alternativement, le volume est monté en lecture seule mais l'application tente d'y écrire (les Secrets sont toujours en lecture seule).

Récupération :

Définissez le defaultMode sur le volume de Secret à une valeur plus permissive, par exemple, 0444 (lisible par tous) ou 0400 (lisible par le propriétaire uniquement). Exemple :

volumes:
- name: secret-volume
  secret:
    secretName: app-secrets
    defaultMode: 0400

Redémarrez ensuite le Pod et testez l'accès en lecture en tant qu'utilisateur du conteneur :

kubectl exec <pod-name> -n payments -- cat /etc/secrets/DATABASE_PASSWORD

Si l'application a besoin d'un accès en écriture, passez à une ConfigMap ou à un emptyDir.

Défaillance 4 : RBAC empêche l'accès au Secret

Symptôme : Un compte de service ne peut pas lire les Secrets, et un contrôleur d'application ou un sidecar échoue avec secrets "..." is forbidden: User "system:serviceaccount:payments:default" cannot get resource "secrets" in API group "" in the namespace "payments".

Cause : Le compte de service par défaut dans un espace de noms n'a généralement pas de permissions get/list/watch sur les Secrets à moins qu'elles ne soient explicitement accordées.

Récupération :

Créez un rôle qui permet de lire des Secrets spécifiques :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: payments
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]

Liez-le au compte de service :

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: payments
  name: read-secrets-to-default
subjects:
- kind: ServiceAccount
  name: default
  namespace: payments
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Appliquez et vérifiez :

kubectl apply -f role.yaml -f rolebinding.yaml
kubectl auth can-i get secrets --as=system:serviceaccount:payments:default -n payments

Attendu : yes.

Défaillance 5 : Cache de Secret obsolète dans un Pod en cours d'exécution

Symptôme : Vous avez mis à jour un Secret, mais l'application voit toujours les anciennes valeurs.

Cause : Les Secrets montés en volumes sont mis à jour dans le Pod après un délai (jusqu'à quelques minutes) mais seulement si le volume est un volume projeté ou si le kubelet se synchronise. Les variables d'environnement sont statiques et ne sont jamais mises à jour après le démarrage du Pod.

Récupération :

  • Pour les Secrets montés en volume, attendez jusqu'à 2 minutes et vérifiez à nouveau le contenu du fichier. S'il ne se met pas à jour, redémarrez le Pod : kubectl delete pod <pod-name> -n payments.
  • Pour les Secrets basés sur l'environnement, vous devez redémarrer le Pod pour récupérer les nouvelles valeurs. Utilisez un redémarrage progressif pour les déploiements : kubectl rollout restart deployment/<deployment-name> -n payments.

Liste de contrôle des opérations

Utilisez cette liste de contrôle avant et après tout changement lié aux Secrets.

Avant le changement

  • [ ] Enregistrer la version du cluster et du client : kubectl version
  • [ ] Identifier l'espace de noms et la charge de travail : kubectl get pods -n payments
  • [ ] Capturer l'état actuel du Pod et les événements : kubectl describe pod <pod-name> -n payments
  • [ ] Lister les Secrets existants et leurs types : kubectl get secrets -n payments
  • [ ] Inspecter les clés du Secret sans les valeurs : kubectl get secret <name> -n payments -o jsonpath='{.data}' | jq 'keys'
  • [ ] Vérifier si le Secret est immuable : kubectl get secret <name> -n payments -o jsonpath='{.immutable}'
  • [ ] Confirmer le nom de référence dans la spécification du déploiement/Pod : kubectl get deployment <name> -n payments -o yaml | grep -A2 -B2 secretName
  • [ ] Déterminer le chemin de retour en arrière : conserver une copie de tout Secret que vous êtes sur le point de modifier, mais ne jamais stocker de valeurs en texte clair dans git sans chiffrement.

Après le changement

  • [ ] Redémarrer la charge de travail : kubectl rollout restart deployment/<deployment-name> -n payments
  • [ ] Surveiller l'état du déploiement : kubectl rollout status deployment/<deployment-name> -n payments
  • [ ] Vérifier que le Pod est en cours d'exécution et prêt : kubectl get pods -n payments
  • [ ] Pour les montages en volume, lister les fichiers : kubectl exec <pod-name> -- ls -l /etc/secrets
  • [ ] Pour les variables d'environnement, les imprimer (en masquant la sortie) : kubectl exec <pod-name> -- printenv | grep DATABASE
  • [ ] Vérifier les événements pour tout nouvel avertissement : kubectl describe pod <pod-name> -n payments | tail -20
  • [ ] Tester le comportement de l'application avec un Pod de débogage si nécessaire
  • [ ] Supprimer les ressources de test temporaires : kubectl delete pod secret-test -n payments

Conclusion

Les erreurs de Secrets Kubernetes sont généralement opérationnelles et non architecturales. Les erreurs les plus courantes sont les discordances de noms, les espaces de noms manquants, l'encodage de données incorrect et les références obsolètes. En suivant un flux de travail discipliné — observer, reproduire dans un Pod minimal, corriger la plus petite chose, vérifier et revenir en arrière en toute sécurité — vous pouvez résoudre ces problèmes rapidement sans exposer d'informations d'identification.

Séparez toujours l'observation de l'intervention. Protégez les valeurs sensibles en utilisant stringData lors de la création et n'imprimez jamais le contenu complet d'un Secret dans les journaux ou les terminaux. Limitez les changements à un élément ciblé à la fois et définissez la vérification de récupération avant qu'un incident ne force la décision.

Comme étape suivante, choisissez une vérification à faible risque de cet article, comme vérifier qu'un Pod de test peut lire un Secret en tant que volume. Enregistrez l'état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et passez en revue les dépendances telles que les ConfigMaps, les ServiceAccounts et les rôles qui peuvent affecter l'accès au Secret.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO