## Introduction Les pods mal configurés sont l'une des causes les plus fréquentes d'incidents de production dans Kubernetes. Les symptômes sont familiers : pods bloqués en état Pending , bouclant en CrashLoopBackOff , échouant aux sondes de disponibilité ou consommant plus de ressources que prévu. Pourtant, de nombreuses équipes dépannent encore en supprimant et recréant des ressources, en espérant que le prochain déploiement se comportera différemment. Ce guide remplace les suppositions par une approche systématique de la configuration des pods Kubernetes. Il est destiné aux développeurs, consultants DevOps et équipes techniques de startups qui exploitent des clusters au quotidien. Il se concentre sur quatre domaines pratiques : les erreurs de configuration des pods, la validation des pods, le retour en arrière des pods et le dépannage des pods. Pour chacun, vous trouverez des commandes kubectl concrètes, les sorties attendues, les signaux de défaillance et les décisions de récupération adaptées au scénario. Le principe directeur tout au long de ce guide est la sécurité : observer avant de modifier, limiter le rayon d'impact, utiliser des valeurs factices au lieu de secrets, vérifier les résultats et documenter les chemins de récupération avant qu'un incident ne force une décision précipitée. ## Inventaire des versions et de l'environnement Avant de toucher à un pod, vous devez savoir avec quoi vous travaillez. L'inventaire des versions et de l'environnement signifie identifier le composant concerné (pod, Deployment, ReplicaSet), la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat. Commencez par capturer l'état actuel sans rien modifier. Enregistrez la version du serveur Kubernetes, l'espace de noms dans lequel le pod s'exécute et les balises d'image exactes utilisées. Cela établit une base de référence et évite toute confusion lors de la comparaison des états avant et après. kubectl version --short kubectl get pods -n payments -o wide kubectl get deployment -n payments -o yaml | grep -A 2 image: Exemple de sortie d'une base de référence saine : Client Version: v1.28.2 Server Version: v1.28.4 NAME READY STATUS RESTARTS AGE IP NODE checkout-7d9f8c5b6d-abcde 1/1 Running 0 2m 10.244.1.5 node-1 checkout-7d9f8c5b6d-fghij 1/1 Running 0 2m 10.244.2.7 node-2 Pour voir les événements, les détails de planification et les avertissements récents, décrivez le pod : kubectl describe pod checkout-7d9f8c5b6d-abcde -n payments Portez attention à la section Events en bas. Un pod bloqué en état Pending parce qu'aucun nœud n'a suffisamment de ressources affichera des événements comme FailedScheduling avec des messages tels que 0/3 nodes are available: 3 Insufficient memory . Séparez l'observation de l'intervention. Ne supprimez pas et ne modifiez pas encore le pod. Capturez l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis planifiez un changement ciblé à la fois. Les ressources associées telles que Deployment, ReplicaSet et Node ne doivent être incluses que lorsqu'elles affectent les prérequis, la compatibilité, la sécurité, l'observabilité ou la récupération. Par exemple, si un pod est toujours planifié sur le même nœud, vérifiez les teintes et les étiquettes du nœud, car cela peut révéler une tolérance manquante dans la spécification du pod. Gardez le test local petit. Appliquez un manifeste, inspectez les ressources générées et vérifiez le trafic avec kubectl port-forward ou un Service local de type NodePort avant de passer à un équilibreur de charge cloud ou à un contrôleur d'entrée.
Question rapide 1 sur 2 Quelle est la première étape pour enquêter sur un problème CrashLoopBackOff selon la référence ? - Vérifier les logs - Inspecter les événements - Revoir la configuration - Vérifier les limites de ressources
La référence indique que pour rechercher la cause d'un problème CrashLoopBackOff, l'utilisateur peut consulter les logs à l'aide de kubectl logs, ce qui est souvent le moyen le plus direct de diagnostiquer la cause des plantages.
## Erreurs courantes de configuration des pods Les erreurs de configuration les plus fréquentes se répartissent en quelques catégories récurrentes. Chaque erreur ci-dessous inclut une commande réelle pour la reproduire, une description de la défaillance et une correction qui a été vérifiée en pratique. ### Déclaration de port de conteneur manquante ou incorrecte Un conteneur peut écouter sur le port 8080 à l'intérieur, mais si la spécification du pod ne déclare pas containerPort , les Services ne peuvent pas acheminer le trafic correctement. Pire, si le mauvais port est déclaré, le trafic ne va nulle part. apiVersion: v1 kind: Pod metadata: name: webapp spec: containers: - name: webapp image: myapp:1.2.3 ports: - containerPort: 8080 # l'application écoute réellement sur 8080, donc c'est correct Pour vérifier à l'intérieur du conteneur, exécutez : kubectl exec -it webapp -- sh -c 'netstat -tulpn | grep LISTEN' Sortie attendue si l'application écoute sur 8080 : tcp 0 0 :::8080 :::* LISTEN - Si la sortie montre un autre port ou aucun écouteur, corrigez la déclaration containerPort dans le manifeste. ### Limites de ressources manquantes ou trop strictes Sans demandes et limites de ressources, un pod peut être évincé lorsqu'un nœud manque de mémoire, ou il peut affamer d'autres charges de travail. À l'inverse, des limites trop basses provoquent des OOMKilled ou un étranglement du processeur. Définissez des valeurs réalistes basées sur l'utilisation observée : resources: requests: memory: "128Mi" cpu: "250m" limits: memory: "256Mi" cpu: "500m" Pour vérifier l'utilisation actuelle, utilisez kubectl top : kubectl top pod -n payments Exemple de sortie : NAME CPU(cores) MEMORY(bytes) checkout-7d9f8c5b6d-abcde 120m 150Mi checkout-7d9f8c5b6d-fghij 98m 142Mi Si l'utilisation de la mémoire est constamment proche de 256Mi, augmentez la limite à 512Mi et mettez à jour la demande en conséquence. Si un pod a été tué par OOM, vérifiez la raison de l'arrêt : kubectl describe pod checkout-7d9f8c5b6d-abcde -n payments | grep -A 5 'Last State' Recherchez Reason: OOMKilled . La correction consiste à augmenter la limite de mémoire ou à réduire l'empreinte de la charge de travail. ### Sondes mal configurées Les sondes de vivacité et de disponibilité sont essentielles, mais de mauvaises configurations provoquent des redémarrages ou des pertes de trafic. Une erreur courante consiste à utiliser une sonde TCP sur un point de terminaison HTTP, ou à définir initialDelaySeconds trop bas pour les applications à démarrage lent. Exemple de sonde HTTP problématique : livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 # trop court pour une app qui met 15 secondes à démarrer periodSeconds: 10 Avec cette sonde, le conteneur peut ne jamais devenir prêt avant que la sonde de vivacité ne commence à échouer, provoquant un CrashLoopBackOff . Augmentez initialDelaySeconds à 30 et periodSeconds à 20. Pour observer les échecs de sonde, décrivez le pod et recherchez les événements Unhealthy : kubectl describe pod webapp -n payments | grep -A 10 Events Si vous voyez Liveness probe failed: HTTP probe failed with statuscode: 500 , l'application elle-même échoue ; s'il s'agit de connection refused , la sonde atteint le mauvais port. ### Variables d'environnement codées en dur ou secrets en texte clair Mettre des mots de passe de base de données ou des clés API directement dans la spécification du pod est une erreur grave. Utilisez les Secrets Kubernetes et référencez-les via valueFrom . Mauvaise approche : env: - name: DB_PASSWORD value: "Sup3rSecret!" # ne faites jamais cela Bonne approche : env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: db-password Créez d'abord le Secret avec une valeur factice, puis injectez la valeur réelle via un gestionnaire de secrets externe ou un secret scellé. kubectl create secret generic app-secrets --from-literal=db-password='CHANGE_ME' Vérifiez que le pod peut lire le Secret sans l'imprimer : kubectl exec webapp -- printenv DB_PASSWORD Ne faites pas écho à la valeur dans les journaux ou les commandes qui se retrouvent dans l'historique du shell. Utilisez une valeur masquée si vous devez confirmer l'existence. ### Politique de tirage d'image incorrecte ou authentification de registre manquante Si votre image est privée, un pod peut échouer avec ImagePullBackOff parce que le cluster ne peut pas s'authentifier. La politique de tirage d'image compte également : Always tire à chaque fois, ce qui est sûr pour les balises mutables mais lent ; IfNotPresent est plus rapide pour les balises immuables. imagePullPolicy: IfNotPresent # à utiliser avec des balises immuables imagePullSecrets: - name: regcred Créez le secret de tirage : kubectl create secret docker-registry regcred \ --docker-server=registry.example.com \ --docker-username=deploy \ --docker-password=xxxx \ --docker-email=deploy@example.com Si un pod est en ImagePullBackOff , vérifiez les événements : kubectl describe pod webapp | grep -A 5 Events Recherchez des messages comme failed to authorize: failed to fetch anonymous token ou pull access denied . Corrigez le secret ou la balise d'image, puis supprimez le pod pour forcer un nouveau tirage. ## Chemin de configuration sûr Le chemin de configuration sûr est une séquence qui réduit le risque à chaque étape. Il se compose de cinq phases : observer, planifier, modifier, vérifier et documenter. Pour la configuration des pods Kubernetes, cela signifie nommer le composant concerné, la version prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande de vérification. ### Phase 1 : Observer Ne changez encore rien. Collectez l'état actuel : kubectl get pods -n payments -o wide kubectl describe pod -n payments kubectl logs --previous -n payments # si le conteneur a redémarré kubectl rollout status deployment/checkout -n payments Exemple de sortie lorsqu'un déploiement est bloqué : Waiting for deployment "checkout" rollout to finish: 1 old replicas are pending termination... ### Phase 2 : Planifier Identifiez le champ exact à modifier. Si un pod est en CrashLoopBackOff , inspectez d'abord les journaux précédents : kubectl logs checkout-7d9f8c5b6d-abcde --previous -n payments Supposons que le journal affiche : panic: runtime error: invalid memory address or nil pointer dereference Cela indique un bogue d'application, pas un problème de configuration. Mais si le journal affiche Error: could not connect to database at postgres:5432 , la configuration est probablement erronée : le nom d'hôte de la base de données ou les informations d'identification peuvent être incorrects. Choisissez le plus petit changement qui répond à la défaillance observée. S'il s'agit d'une erreur de configuration, modifiez le Deployment (pas directement le pod, car les pods sont éphémères) : kubectl edit deployment checkout -n payments ### Phase 3 : Modifier Appliquez la modification via un patch de fusion pour éviter d'écraser des champs non liés : kubectl patch deployment checkout -n payments -p '{"spec":{"template":{"spec":{"containers":[{"name":"checkout","env":[{"name":"DB_HOST","value":"postgres.internal"}]}]}}}}' Puis surveillez le déploiement : kubectl rollout status deployment/checkout -n payments Sortie attendue en cas de succès : deployment "checkout" successfully rolled out ### Phase 4 : Vérifier Confirmez que le nouveau pod est en cours d'exécution et prêt, et que le trafic circule. Utilisez le transfert de port pour tester localement : kubectl port-forward deployment/checkout 8080:8080 -n payments curl http://localhost:8080/healthz Attendu : {"status":"ok"} ### Phase 5 : Documenter Enregistrez ce qui a changé, pourquoi et comment revenir en arrière. Par exemple, notez dans votre runbook : "Augmentation de initialDelaySeconds de la sonde de vivacité de 5 à 30 pour le déploiement checkout en raison d'un démarrage lent. Commande de retour en arrière : kubectl rollout undo deployment/checkout -n payments " ## Vérification et diagnostics La vérification n'est pas un simple kubectl get après un déploiement. C'est une séquence de contrôles qui confirment que le pod est sain de l'intérieur vers l'extérieur : processus, utilisation des ressources, accessibilité réseau et réponse au niveau de l'application. ### Vérifier le statut et la disponibilité du pod Commencez par les bases : kubectl get pods -n payments -o wide Tous les pods doivent être Running et READY 1/1 . Si un pod est Running mais 0/1 , la disponibilité échoue. Décrivez pour voir pourquoi : kubectl describe pod checkout-7d9f8c5b6d-xyz -n payments Recherchez des événements comme Readiness probe failed: Get "http://10.244.1.6:8080/ready": dial tcp 10.244.1.6:8080: connect: connection refused . ### Inspecter les journaux pour les erreurs kubectl logs checkout-7d9f8c5b6d-xyz -n payments --tail=50 Si le conteneur a redémarré, incluez l'instance précédente : kubectl logs checkout-7d9f8c5b6d-xyz -n payments --previous Filtrez les erreurs avec grep : kubectl logs checkout-7d9f8c5b6d-xyz -n payments --previous | grep -i error ### Tester la connectivité réseau depuis l'intérieur du pod kubectl exec -it checkout-7d9f8c5b6d-xyz -n payments -- sh # à l'intérieur du pod ping -c 3 postgres.internal # si ping est installé nc -zv postgres.internal 5432 Si le pod peut résoudre le nom DNS mais ne peut pas se connecter au port, il peut y avoir une NetworkPolicy bloquant le trafic. ### Valider l'utilisation des ressources par rapport aux limites kubectl top pod checkout-7d9f8c5b6d-xyz -n payments --containers Exemple de sortie : POD NAME CPU(cores) MEMORY(bytes) checkout-7d9f8c5b6d-xyz checkout 75m 198Mi Si la mémoire est proche de la limite (par exemple, limite de 256Mi, utilisation de 198Mi), envisagez d'augmenter la limite avant le prochain pic de trafic. ### Vérifier l'historique des déploiements kubectl rollout history deployment/checkout -n payments Exemple : deployment.apps/checkout REVISION CHANGE-CAUSE 1 2 kubectl set image deployment/checkout checkout=myapp:1.2.4 Cet historique est essentiel pour les décisions de retour en arrière.
Question rapide 2 sur 2 Quelle commande est utilisée pour inspecter les événements d'un Pod bloqué à l'état Pending ? - kubectl logs pod-name - kubectl describe pod pod-name - kubectl get pod pod-name -o yaml - kubectl exec pod-name
La référence montre l'utilisation de kubectl describe pod frontend pour consulter les événements, notamment le message FailedScheduling pour un Pod en attente (Pending).
## Modes de défaillance et récupération Chaque configuration de pod peut échouer de manière prévisible. Connaître les modes de défaillance typiques et leurs commandes de récupération réduit le temps d'incident. ### CrashLoopBackOff Symptôme : le pod redémarre à plusieurs reprises, STATUS affiche CrashLoopBackOff et le nombre de RESTARTS augmente. Diagnostic : kubectl describe pod webapp -n payments | grep -A 10 'Last State' kubectl logs webapp --previous -n payments Causes courantes : plantage de l'application au démarrage, fichier de configuration manquant, commande ou arguments incorrects, OOMKilled . Récupération : corrigez la cause racine (par exemple, ajoutez la ConfigMap manquante, augmentez la limite de mémoire), puis supprimez le pod pour redémarrer proprement : kubectl delete pod webapp -n payments Si le pod est géré par un Deployment, il sera recréé automatiquement. ### ImagePullBackOff Symptôme : le pod ne peut pas extraire l'image, statut ImagePullBackOff ou ErrImagePull . Diagnostic : kubectl describe pod webapp -n payments | grep -A 10 Events Recherchez des messages comme failed to pull image "myapp:latest": pull access denied ou repository does not exist . Récupération : corrigez le nom ou la balise de l'image, assurez-vous que le secret de tirage existe et est référencé par la spécification du pod. Ensuite, supprimez le pod. ### En attente en raison de ressources insuffisantes Symptôme : le pod reste en Pending , READY est 0/1 , et les événements affichent FailedScheduling . Diagnostic : kubectl describe pod bigdata -n analytics | grep -A 5 Events Exemple de message : 0/3 nodes are available: 3 Insufficient cpu . Récupération : réduisez les demandes de ressources, réduisez d'autres charges de travail ou ajoutez des nœuds au cluster. Si la demande est justifiée, augmentez la capacité du cluster. ### Échec de la sonde de disponibilité Symptôme : le pod est Running mais pas Ready ; le Service ne route pas le trafic vers lui. Diagnostic : kubectl get pods -n payments kubectl describe pod webapp -n payments | grep -A 10 Events Recherchez Readiness probe failed: HTTP probe failed with statuscode: 503 . Récupération : corrigez le chemin, le port ou le délai de la sonde. Pour une application qui met 30 secondes à devenir prête, définissez initialDelaySeconds: 30 et periodSeconds: 10 . ### OOMKilled Symptôme : le pod se termine avec la raison OOMKilled , code de sortie 137. Diagnostic : kubectl describe pod webapp -n payments | grep -A 5 'Last State' La sortie affiche Reason: OOMKilled . Récupération : augmentez la limite de mémoire ou réduisez l'utilisation de la mémoire. Utilisez un outil de mise à l'échelle verticale ou ajustez les paramètres de mémoire de l'application. Ensuite, déployez une nouvelle révision. ### Récupération par retour en arrière Si un changement récent a provoqué la défaillance, revenez à une révision précédente : kubectl rollout undo deployment/checkout -n payments kubectl rollout status deployment/checkout -n payments Pour revenir à une révision spécifique : kubectl rollout undo deployment/checkout --to-revision=1 -n payments Vérifiez toujours après le retour en arrière : kubectl get pods -n payments -o wide kubectl logs deployment/checkout --tail=20 -n payments ## Liste de contrôle opérationnelle Utilisez cette liste de contrôle pour standardiser le dépannage et les modifications de configuration des pods. Chaque élément inclut un exemple concret et le résultat attendu. - Enregistrez le contexte du cluster et de l'espace de noms. - Commande : kubectl config current-context && kubectl get ns payments - Attendu : le nom du contexte est affiché et l'espace de noms existe. - Capturez la base de référence du pod. - Commande : kubectl get pods -n payments -o wide --show-labels - Attendu : tous les pods sont répertoriés avec les étiquettes et les adresses IP. - Décrivez le pod défaillant et enregistrez les événements dans un fichier. - Commande : kubectl describe pod webapp-abc123 -n payments > /tmp/webapp-events.txt - Attendu : le fichier contient des événements récents comme des échecs de sonde ou des erreurs de planification. - Vérifiez les journaux du conteneur précédent s'il a redémarré. - Commande : kubectl logs webapp-abc123 --previous -n payments | tail -50 - Attendu : les erreurs de démarrage ou les traces de pile de plantage sont visibles. - Validez la spécification du pod par rapport à la configuration souhaitée. - Comparez la spécification en cours d'exécution avec votre manifeste source : kubectl get pod webapp-abc123 -n payments -o yaml | diff - desired-pod.yaml - Attendu : uniquement des différences attendues (par exemple, des champs par défaut). - Appliquez le plus petit changement via un patch, pas un remplacement complet. - Exemple : kubectl patch deployment webapp -n payments -p '{"spec":{"template":{"spec":{"containers":[{"name":"webapp","resources":{"limits":{"memory":"512Mi"}}}]}}}}' - Attendu : le patch réussit avec deployment.apps/webapp patched . - Surveillez le statut du déploiement. - Commande : kubectl rollout status deployment/webapp -n payments - Attendu : deployment "webapp" successfully rolled out dans le délai imparti. - Vérifiez la disponibilité du pod et la santé de l'application. - Commandes : kubectl get pods -n payments , puis kubectl port-forward deployment/webapp 8080:8080 -n payments et curl localhost:8080/healthz . - Attendu : pods 1/1 Running , le point de terminaison de santé renvoie 200 OK. - Confirmez que l'utilisation des ressources est dans les limites. - Commande : kubectl top pod -n payments - Attendu : mémoire et CPU inférieurs aux limites, avec une marge. - Documentez le changement et la commande de retour en arrière. - Exemple de note : "Augmentation de la limite de mémoire de webapp de 256Mi à 512Mi pour éviter OOMKilled. Retour en arrière : kubectl rollout undo deployment/webapp -n payments ." - Attendu : entrée dans le runbook de l'équipe ou le journal des incidents. ## Conclusion Les erreurs de configuration des pods Kubernetes sont inévitables, mais elles ne doivent pas provoquer de longues interruptions. Les exemples pratiques de ce guide ont montré comment observer l'état du pod avant de changer quoi que ce soit, diagnostiquer les modes de défaillance courants avec des commandes kubectl spécifiques, appliquer le plus petit changement sûr et vérifier le résultat avant de déclarer victoire. Chaque recommandation ici est limitée à une version, observable et réversible lorsque Kubernetes le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure opérationnelle ; c'est un pari. Comme prochaine étape, choisissez une vérification à faible risque de la liste de contrôle opérationnelle, enregistrez l'état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et examinez les dépendances telles que Deployment, ReplicaSet et Node dans votre propre cluster. Ensuite, identifiez l'erreur de configuration de pod la plus fréquente dans votre environnement et créez une entrée de runbook pour celle-ci en utilisant les phases du chemin de configuration sûr. Un flux de travail technique fiable rend la défaillance visible, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. Votre futur moi d'astreinte vous remerciera.