Comment puis-je résoudre les problèmes d'état des pods dans Amazon EKS ?

Date de la dernière mise à jour : 13/02/2020

Mes pods Amazon Elastic Kubernetes Service (Amazon EKS) exécutés sur des instances Amazon Elastic Compute Cloud (Amazon EC2) ou sur un groupe de nœuds gérés sont bloqués. Que puis-je faire pour que mes pods retrouvent l'état « Running » (En cours d'exécution) ?

Résolution

Important : les étapes suivantes s'appliquent uniquement aux pods lancés sur des instances Amazon EC2 ou sur un groupe de nœuds gérés. Elles ne concernent pas les pods lancés sur AWS Fargate.

Découvrir l'état de votre pod

1.    Exécutez la commande suivante pour obtenir des informations à partir de l'historique des Événements de votre pod :

$ kubectl describe pod YOUR_POD_NAME

Remarque : les exemples de commandes couverts dans les étapes suivantes se trouvent dans l'espace de noms par défaut. Pour les autres espaces de noms, ajoutez la commande avec -n YOURNAMESPACE.

2.    En fonction de l'état de votre pod, suivez les étapes décrites dans l'une des sections suivantes : Votre pod est à l'état « Pending » (En attente), Votre pod est à l'état « En suspens » (Waiting), ou Votre pod est à l'état CrashLoopBackOff.

Votre pod est à l'état « Pending » (En attente)

Les pods ayant l'état « Pending » (En attente) ne peuvent pas être programmés sur un nœud.

Votre pod peut avoir l'état « Pending » (En attente), car vous n’avez pas assez de ressources sur les nœuds de travail disponibles ou vous avez défini un hostPort occupé sur le pod.

Si vos ressources sur les nœuds de travail disponibles sont insuffisantes, supprimez les pods inutiles ou ajoutez d'autres nœudsde travail. Par exemple, vos nœuds de travail peuvent manquer de processeur et d'espace mémoire. S'il s'agit d'un problème récurrent, vous pouvez utiliser Kubernetes Cluster Autoscaler pour mettre à l'échelle automatiquement votre groupe de nœuds de travail lorsque les ressources de votre cluster sont rares.

Si vous définissez un hostPort pour votre pod, prenez en compte les éléments suivants :

(A) Il existe un nombre limité d'emplacements où un pod peut être programmé lorsque vous liez un pod à un hostPort.
(B) Ne spécifiez pas un hostPort sauf si nécessaire. En effet, la combinaison hostIP, hostPort et protocole doit être unique.
(C) Si vous devez spécifier hostPort, programmez le même nombre de pods qu'il y a des nœuds de travail.

L'exemple suivant montre le résultat de la commande « describe » (décrire) pour my-nginx-12345abc6d-7e8fg, qui est à l'état « Pending » (En attente). Le pod n'est pas programmé en raison d'un problème de ressource.

$ kubectl describe pod my-nginx-86459cfc9f-2j5bq

Name:               my-nginx-12345abc6d-7e8fg
Namespace:          default
Priority:           0
PriorityClassName:  
Node:               
Labels:             pod-template-hash=86459cfc9f
                    run=my-nginx
Annotations:        kubernetes.io/psp: eks.privileged
Status:             Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  7s (x6 over 5m58s)  default-scheduler  0/2 nodes are available: 1 Insufficient pods, 1 node(s) had taints that the pod didn't tolerate.

Si vos pods sont toujours à l'état « Pending » (En attente) après les étapes précédentes, suivez les étapes de la section « Additional troubleshooting » (Résolution de problèmes supplémentaires).

Votre pod est à l'état « Waiting » (En suspens)

Un pod à l'état « Waiting » (En suspens) est programmé sur un nœud de travail (par exemple, une instance Amazon EC2), mais ne peut pas s'exécuter sur ce nœud.

Votre pod peut avoir l'état « Waiting » (En suspens), car vous n'avez pas la bonne image Docker ou le bon nom de référentiel, en raison d'un manque d'autorisations ou parce que l'image n'existe pas.

Si vous n'avez pas la bonne image Docker ou le bon nom de référentiel, effectuez les opérations suivantes :

1.    Vérifiez que l'image et le nom du référentiel sont corrects en vous connectant à Docker Hub, Amazon Elastic Container Registry (Amazon ECR) ou à un autre référentiel d'images de conteneur.

2.    Comparez le référentiel ou l'image du référentiel au nom du référentiel ou de l'image spécifié dans la description du pod.

Si l'image n'existe pas ou si vous n'avez pas les autorisations requises, effectuez les opérations suivantes :

1.    Vérifiez que l'image spécifiée est disponible dans le référentiel et que les autorisations appropriées sont configurées pour permettre l'extraction de l'image.

2.    Pour confirmer que l'extraction d'image est possible et pour exclure les problèmes généraux d'autorisation de mise en réseau et de référentiel, extrayez manuellement l'image des nœuds de travail Amazon EKS avec Docker :

$ docker pull yourImageURI:yourImageTag

3.    Pour vérifier que l'image existe, vérifiez que l'image et la balise sont toutes deux présentes dans Docker Hub ou Amazon ECR.

Remarque : si vous utilisez Amazon ECR, vérifiez que la stratégie de référentiel autorise l'extraction d'image pour NodeInstanceRole. Vous pouvez également vérifier que le rôle AmazonEC2ContainerRegistryReadOnly est attaché à la stratégie.

L'exemple suivant montre un pod à l'état « Pending » (En attente), le conteneur étant à l'état « Waiting » (En suspens) en raison d'une erreur d'extraction d'image :

$ kubectl describe po web-test

Name:               web-test
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               ip-192-168-6-51.us-east-2.compute.internal/192.168.6.51
Start Time:         Wed, 22 Jan 2020 08:18:16 +0200
Labels:             app=web-test
Annotations:        kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"web-test"},"name":"web-test","namespace":"default"},"spec":{...
                    kubernetes.io/psp: eks.privileged
Status:             Pending
IP:                 192.168.1.143
Containers:
  web-test:
    Container ID:   
    Image:          somerandomnonexistentimage
    Image ID:       
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       ErrImagePull
...
Events:
  Type     Reason            Age                 From                                                 Message
  ----     ------            ----                ----                                                 -------
  Normal   Scheduled         66s                 default-scheduler                                    Successfully assigned default/web-test to ip-192-168-6-51.us-east-2.compute.internal
  Normal   Pulling           14s (x3 over 65s)   kubelet, ip-192-168-6-51.us-east-2.compute.internal  Pulling image "somerandomnonexistentimage"
  Warning  Failed            14s (x3 over 55s)   kubelet, ip-192-168-6-51.us-east-2.compute.internal  Failed to pull image "somerandomnonexistentimage": rpc error: code = Unknown desc = Error response from daemon: pull access denied for somerandomnonexistentimage, repository does not exist or may require 'docker login'
  Warning  Failed            14s (x3 over 55s)   kubelet, ip-192-168-6-51.us-east-2.compute.internal  Error: ErrImagePull

Si vos pods sont toujours à l'état « Waiting » (En suspens) après les étapes précédentes, suivez les étapes de la section « Additional troubleshooting » (Résolution de problèmes supplémentaires).

Votre pod est à l'état CrashLoopBackOff

Les pods bloqués dans CrashLoopBackOff démarrent, se bloquent, redémarrent, puis se bloquent à nouveau de manière répétée.

Si vous recevez le message « Back-Off restarting failed container », c'est que votre conteneur s'est probablement fermé peu de temps après que Kubernetes l'ait démarré.

Pour rechercher des erreurs dans les journaux du pod actuel, exécutez la commande suivante :

$ kubectl logs YOUR_POD_NAME

Pour rechercher des erreurs dans les journaux du pod précédent qui s'est bloqué, exécutez la commande suivante :

$ kubectl logs --previous YOUR-POD_NAME

Remarque : pour un pod à plusieurs conteneurs, vous pouvez ajouter le nom du conteneur à la fin. Par exemple :

$ kubectl logs POD_NAME CONTAINER_NAME

si la sonde vive ne renvoie pas un statut de réussite, vérifiez qu'elle est configurée correctement pour l'application. Pour plus d'informations, consultez Configuration des sondes.

L'exemple suivant montre un pod dans un état CrashLoopBackOff, car l'application se ferme après le démarrage :

$ kubectl describe po crash-app-6847947bf8-28rq6

Name:               crash-app-6847947bf8-28rq6
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               ip-192-168-6-51.us-east-2.compute.internal/192.168.6.51
Start Time:         Wed, 22 Jan 2020 08:42:20 +0200
Labels:             pod-template-hash=6847947bf8
                    run=crash-app
Annotations:        kubernetes.io/psp: eks.privileged
Status:             Running
IP:                 192.168.29.73
Controlled By:      ReplicaSet/crash-app-6847947bf8
Containers:
  main:
    Container ID:  docker://6aecdce22adf08de2dbcd48f5d3d8d4f00f8e86bddca03384e482e71b3c20442
    Image:         alpine
    Image ID:      docker-pullable://alpine@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
    Port:          80/TCP
    Host Port:     0/TCP
    Command:
      /bin/sleep
      1
    State:          Waiting
      Reason:       CrashLoopBackOff
...
Events:
  Type     Reason     Age                From                                                 Message
  ----     ------     ----               ----                                                 -------
  Normal   Scheduled  47s                default-scheduler                                    Successfully assigned default/crash-app-6847947bf8-28rq6 to ip-192-168-6-51.us-east-2.compute.internal
  Normal   Pulling    28s (x3 over 46s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Pulling image "alpine"
  Normal   Pulled     28s (x3 over 46s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Successfully pulled image "alpine"
  Normal   Created    28s (x3 over 45s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Created container main
  Normal   Started    28s (x3 over 45s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Started container main
  Warning  BackOff    12s (x4 over 42s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Back-off restarting failed container

Si vos pods sont toujours à l'état CrashLoopBackOff après les étapes précédentes, suivez les étapes de la section « Additional troubleshooting » (Résolution de problèmes supplémentaires).

Résolution de problèmes supplémentaires

Si votre pod est encore bloqué après les étapes des sections précédentes, essayez les étapes suivantes :

1.    Pour confirmer que les nœuds de travail existent dans le cluster et sont à l'état « Prêt »(Prêt) – ce qui permet la planification des pods sur celui-ci – , exécutez la commande suivante :

$ kubectl get nodes

Le résultat doit ressembler à ce qui suit :

NAME                                          STATUS   ROLES    AGE   VERSION
ip-192-168-6-51.us-east-2.compute.internal    Ready    <none>   25d   v1.14.6-eks-5047ed
ip-192-168-86-33.us-east-2.compute.internal   Ready    <none>   25d   v1.14.6-eks-5047ed

Si les nœuds ne sont pas dans le cluster, ajoutez des nœuds de travail.

Si les nœuds sont NotReady ou ne peuvent pas joindre le cluster, consultez Comment puis-je modifier l'état de mes nœuds « NotReady » (Indisponible) ou « Unknown » (Inconnu) en « Ready » (Prêt) ?

2.    Pour vérifier la version du cluster Kubernetes, exécutez la commande suivante :

$ kubectl version --short

Le résultat doit ressembler à ce qui suit :

Client Version: v1.14.6-eks-5047ed
Server Version: v1.14.9-eks-c0eccc

3.    Pour vérifier la version du nœud de travail Kubernetes, exécutez la commande suivante :

$ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion

Le résultat doit ressembler à ce qui suit :

NAME                                          VERSION
ip-192-168-6-51.us-east-2.compute.internal    v1.14.6-eks-5047ed
ip-192-168-86-33.us-east-2.compute.internal   v1.14.6-eks-5047ed

4.    En fonction du résultat des étapes 2 et 3, vérifiez que la version du serveur Kubernetes pour le cluster correspond à la version des nœuds de travail au sein d'une différence de version acceptable.

Important : Les versions de correctifs peuvent être différentes (par exemple, v1.14.x pour le cluster et v1.14.y pour le nœud de travail).

Si les versions de cluster et de nœud de travail ne sont pas compatibles, créez un nouveau groupe de nœuds avec (voir l'onglet eksctl )ou AWS CloudFormation (voir l'onglet Nœuds autogérés).

--ou--

Créez un nouveau groupe de nœuds gérés (Kubernetes : v1.14, plateforme : eks.3 et versions ultérieures) à l'aide d'une version Kubernetescompatible. Supprimez ensuite le groupe de nœuds ayant la version Kubernetes incompatible.

5.    Pour confirmer que le plan de contrôle Kubernetes peut communiquer avec les nœuds de travail, vérifiez les règles de pare-feu par rapport aux règles recommandées dans Considérations relatives aux groupes de sécurité Amazon EKS, puis vérifiez que les nœuds sont à l'état « Ready » (Prêt).


Cet article vous a-t-il été utile ?

Cette page peut-elle être améliorée ?


Vous avez besoin d’aide ?