Une récente série d'articles a mis en évidence les 10 raisons courantes de déploiements de Kubernetes défaillants. Celles-ci vont des entrées manquantes et incorrectes jusqu'au dépassement des limites de ressources. Dans la plupart des cas, la commande kubectl describe
peut aider à identifier la raison sous-jacente.
Les entrées non valides pour un déploiement sur Kubernetes incluent la spécification d'une image de conteneur inexistante ou qui est inaccessible par défaut de droits. Le dépôt par défaut est Dockerhub, donc l'URL du dépôt devrait être spécifiée si un autre dépôt comme Amazon ECR ou Quay.io est utilisé. Les dépôts privés nécessitent des autorisations pour accéder aux images. Une récupération ratée de l'image peut également se produire lorsque le nom du tag est incorrecte. Cela peut se produire lorsque le dernier tag n'existe pas, alors que l'image oui ('latest' est le tag par défaut si rien n'est spécifié). Les problèmes réseau peuvent également poser souci. Les messages d'erreur dans ces cas sont similaires, donc une analyse plus approfondie est nécessaire pour identifier la vrai cause.
Les échecs de déploiement avec Kubernetes conduisent généralement à l'absence de récupération du pod désiré. La commande kubectl describe pod <le nom du pod>
affiche le journal d'événements décrivant les raisons de l'échec. La commande kubectl
prend en paramètre les arguments pod
, replicaset
, et deployment
. Ces commandes combinées avec les kubectl logs <podname>
sont essentielles pour le débogage des échecs de déploiement.
Si la politique par défaut dans Kubernetes est définie pour ne pas faire toujours des pull à partir du dépôt, il se peut que les mises à jour ne soient pas visibles même après que les modifications aient été validées et que l'image ait été poussée. L'approche recommandée pour la production consiste à utiliser des tags uniques pour chaque image et à les utiliser lors de la récupération. La spécification de volumes persistants non existants dans la configuration de déploiement peut également entraîner un échec de déploiement.
Deux autres cas d'entrées non valides sont l'absence de 'ConfigMap' ou les 'Secrets' et des objets Spec non valides à l'exécution de l’application. Un 'ConfigMap' est une map de paires clé-valeur de données de configuration nécessaires à l'application. Les 'ConfigMaps' peuvent être spécifiés comme des arguments CLI, des variables d'environnement ou des fichiers dans un volume monté. S'ils sont absents, la création de pod s'arrête avec l'état défini sur "RunContainerError". Les secrets sont un mécanisme pour stocker des données sensibles comme des informations d'identification. Un secret manquant entraînera des erreurs similaires. Les 'ConfigMap' et les 'Secrets' peuvent aussi être montés en volumes. En cas d'échec, la création du conteneur s'arrête avec le statut bloqué à "ContainerCreating" dans le journal d'événements.
Les objets Kubernetes Spec non valides en raison d'erreurs d'indentation ou les fautes de frappe dans le YAML sont une autre cause d'échecs. On peut s'en prémunir facilement en utilisant une validation du YAML basée sur CLI et en utilisant le flag -dry-run de cette manière :
kubectl create -f test-application.deploy.yaml --dry-run --validate=true
Cela nécessite un cluster Kubernetes opérationnel pour s’exécuter. Il y a un travail en cours pour éliminer ce type de dépendance et avoir une validation côté client. La validation du YAML peut être ajoutée en tant que partie des hooks dans la phase pré-commit dans le système de contrôle des sources.
Une autre classe de déploiements ratés sur Kubernetes comprend le dépassement des limites des ressources. Les Pods et les conteneurs ont chacun des limites spécifiées pour le CPU et la mémoire. Le dépassement de ces limites entraînerait l'impossibilité de création de Pods. Le débuggage n’est pas aussi simple et nécessitera un peu d'investigation. La commande kubectl describe deployment <nom de déploiement>
nous donnerait le nom du ReplicaSet que Kubernetes a tenté de créer. En tapant kubectrl describe replicaset <nom du réplicaset>
, en passant le nom du replicaset obtenu à l'étape précédente, on obtient le journal d’événements comme avec les autres cas, avec le message d'erreur.
Les erreurs de déploiement peuvent également résulter du dépassement des quotas des ressources, comme un mécanisme permettant de limiter la consommation de ressources par le namespace lorsque les équipes partagent un cluster avec un nombre fixe de nœuds. Les ressources incluent des pods, des services et des déploiements ainsi que la globalité des ressources de calcul. Dans ce cas aussi, la commande kubectl describe
aide à creuser davantage sur le message d'erreur réel.
Le cluster autoscaler ajuste automatiquement la taille du cluster Kubernetes aussi bien lorsque les nœuds sont des ressources sous-utilisées que lorsqu'un pod n'est pas en mesure de fonctionner par défaut de ressources. Si cela n'est pas autorisé, les déploiements qui demanderaient plus que les ressources allouées échoueront avec l'état « Pending » du pod. Le journal des événements affichera la ressource réelle en défaut.
Des modifications inattendues du comportement de l'application peuvent entraîner des erreurs de différentes manières. Une erreur au lancement avec le message 'CrashLoopBackOff' est d'habitude causée par le crash d’une application. Dans ce cas, les logs de l'application aideront à identifier le problème. Il y a aussi les tests de disponibilité Liveness/Readiness que Kubernetes utilise pour détecter la santé/la disponibilité d'un service qui peuvent échouer en cas de mauvaise configuration ou d’un délai d'attente expiré. Par exemple, l'URL healthcheck (test de vie|santé) peut avoir changé dans l'application ou elle pourrait ne pas fonctionner comme prévu du fait d'un changement sur la base de données. Certaines URL mettront aussi beaucoup de temps à répondre au test d'accessibilité, ce qui causera un timeout et donc un échec de déploiement.
L'auteur de l'article a ouvert les sources de son script qui liste les commandes Kubernetes utiles et les informations liées au journal de build chaque fois qu'un build échoue.