¿Cómo puedo solucionar los problemas relacionados con el estado de los pods en Amazon EKS?

11 minutos de lectura
0

Mis pods de Amazon Elastic Kubernetes Service (Amazon EKS) que se ejecutan en instancias de Amazon Elastic Compute Cloud (Amazon EC2) o en un grupo de nodos administrado están bloqueados. Quiero que mis pods estén en estado «En ejecución» o «Terminado».

Solución

Importante: Los siguientes pasos solo son aplicables a los pods lanzados en instancias de Amazon EC2 o en un ](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)grupo de nodos administrado[. Estos pasos no son aplicables a los pods lanzados en AWS Fargate.

Búsqueda del estado de un pod

Para solucionar problemas relacionados con el estado de un pod en Amazon EKS, siga estos pasos:

  1. Para averiguar el estado del pod, ejecute el siguiente comando:

    $ kubectl get pod
  2. Para obtener información del historial Eventos de su pod, ejecute el siguiente comando:

    $ kubectl describe pod YOUR_POD_NAME
  3. Según el estado del pod, siga los pasos del apartado siguiente.

El estado del pod es Pendiente

Nota: Los comandos de ejemplo de los pasos siguientes se encuentran en el espacio de nombres predeterminado. En el caso de los demás espacios de nombres, añada -n SUESPACIODENOMBRE al comando.

Los pods pueden quedarse bloqueados en estado Pendiente debido a la falta de recursos o porque ha definido un hostPort. Para obtener más información, consulte Pod phase en el sitio web de Kubernetes.

Si no tiene recursos suficientes en los nodos de trabajo, elimine los pods innecesarios. También puede agregar más recursos en los nodos de trabajo. Si no tiene suficientes recursos en el clúster, use el escalador automático de clústeres de Kubernetes para escalar automáticamente el grupo de nodos de trabajo.

Ejemplo de CPU insuficiente:

$ kubectl describe pod frontend-cpu
Name:         frontend-cpu
...
Status:       Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  22s (x14 over 13m)  default-scheduler  0/3 nodes are available: 3 Insufficient cpu.

Ejemplo de memoria insuficiente:

$ kubectl describe pod frontend-memory
Name:         frontend-memory
...
Status:       Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  80s (x14 over 15m)  default-scheduler  0/3 nodes are available: 3 Insufficient memory.

Si ha definido un hostPort para su pod, siga estas prácticas recomendadas:

  • Dado que la combinación de hostIP, hostPort y protocol debe ser unívoca, especifique un hostPort solo cuando sea necesario.
  • Si especifica un hostPort, programe tantos pods como nodos de trabajo.

Nota: Cuando vincula un pod a un hostPort, hay un número limitado de lugares en los que puede programar un pod.

En el siguiente ejemplo se muestra el resultado del comando describe en el caso de un pod en estado Pendiente, frontend-port-77f67cff67-2bv7w. El pod no se ha programado porque el puerto de host solicitado no está disponible para los nodos de trabajo del clúster:

$ kubectl describe pod frontend-port-77f67cff67-2bv7w
Name:           frontend-port-77f67cff67-2bv7w
...
Status:         Pending
IP:
IPs:            <none>
Controlled By:  ReplicaSet/frontend-port-77f67cff67
Containers:
  app:
    Image:      nginx
    Port:       80/TCP
    Host Port:  80/TCP
...
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  11s (x7 over 6m22s)  default-scheduler  0/3 nodes are available: 3 node(s) didn't have free ports for the requested pod ports.

Si no puede programar los pods porque los nodos tienen taints que el pod no permite, el resultado del ejemplo es similar al siguiente:

$ kubectl describe pod nginx
Name:         nginx
...
Status:       Pending
...
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  8s (x10 over 9m22s)  default-scheduler  0/3 nodes are available: 3 node(s) had taint {key1: value1}, that the pod didn't tolerate.

Para comprobar los taints de los nodos, ejecute el siguiente comando:

$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

Para conservar los taints de los nodos, especifique una tolerancia para un pod en PodSpec. Para obtener más información, consulte Conceptos en el sitio web de Kubernetes. Como alternativa, puede añadir - al final del valor del taint para eliminarlo del nodo:

$ kubectl taint nodes NODE_Name key1=value1:NoSchedule-

Si los pods siguen estando en estado Pendiente, siga los pasos del apartado Otras soluciones.

El contenedor está en estado Esperando

Es posible que el contenedor esté en estado Esperando debido a una imagen de Docker o a un nombre de repositorio incorrectos. También es posible que el pod esté en estado Esperando porque la imagen no existe o porque le faltan permisos.

Para confirmar si la imagen y el nombre del repositorio son correctos, inicie sesión en Docker Hub, Amazon Elastic Container Registry (Amazon ECR) u otro repositorio de imágenes de contenedor. Compare el repositorio o la imagen del repositorio con el nombre del repositorio o la imagen que se indican en la especificación del pod. Si la imagen no existe o le faltan permisos, siga estos pasos:

  1. Compruebe que la imagen especificada esté disponible en el repositorio y que se hayan configurado los permisos correctos para poder extraer la imagen.

  2. Para confirmar que pueda extraer la imagen y que no haya problemas generales con los permisos de red y de repositorio, extraiga la imagen manualmente. Debe usar Docker para extraer la imagen de los nodos de trabajo de Amazon EKS:

    $ docker pull yourImageURI:yourImageTag
  3. Para verificar si la imagen existe, compruebe que tanto la imagen como la etiqueta estén en Docker Hub o Amazon ECR.

Nota: Si usa Amazon ECR, compruebe si la política del repositorio permite la extracción de imágenes para el NodeInstanceRole. Compruebe también si el rol AmazonEC2ContainerRegistryReadOnly está asociado a la política.
En el siguiente ejemplo se muestra un pod en estado Pendiente con el contenedor en estado Esperando debido a un error al extraer la imagen:

$ kubectl describe po web-test

Name:               web-test
...
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 los contenedores siguen en estado Esperando, siga los pasos del apartado Otras soluciones.

El pod está en estado Bucle de fallo en retroceso

Si se muestra el mensaje «Back-Off restarting failed container», es posible que el contenedor haya salido poco después de que Kubernetes lo iniciara.

Para buscar errores en los registros del pod actual, ejecute el siguiente comando:

$ kubectl logs YOUR_POD_NAME

Para buscar errores en los registros del pod anterior, en el que se produjo el fallo, ejecute el siguiente comando:

$ kubectl logs --previous YOUR-POD_NAME

En el caso de un pod con varios contenedores, añada el nombre del contenedor al final. Por ejemplo:

$ kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]

Si la sonda de vida no devuelve el estado Correcto, compruebe si se ha configurado correctamente para la aplicación. Para obtener más información, consulte Configure probes en el sitio web de Kubernetes.

En el siguiente ejemplo se muestra un pod en estado Bucle de fallo en retroceso debido a que la aplicación sale tras el inicio:

$ kubectl describe pod crash-app-b9cf4587-66ftw
Name:         crash-app-b9cf4587-66ftw
...
Containers:
  alpine:
    Container ID:   containerd://a36709d9520db92d7f6d9ee02ab80125a384fee178f003ee0b0fcfec303c2e58
    Image:          alpine
    Image ID:       docker.io/library/alpine@sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Tue, 12 Oct 2021 12:26:21 +1100
      Finished:     Tue, 12 Oct 2021 12:26:21 +1100
    Ready:          False
    Restart Count:  4
    ...
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Started    97s (x4 over 2m25s)  kubelet            Started container alpine
  Normal   Pulled     97s                  kubelet            Successfully pulled image "alpine" in 1.872870869s
  Warning  BackOff    69s (x7 over 2m21s)  kubelet            Back-off restarting failed container
  Normal   Pulling    55s (x5 over 2m30s)  kubelet            Pulling image "alpine"
  Normal   Pulled     53s                  kubelet            Successfully pulled image "alpine" in 1.858871422s

A continuación se muestra un ejemplo de una sonda de vida que falla en el pod:

$ kubectl describe pod nginx
Name:         nginx
...
Containers:
  nginx:
    Container ID:   containerd://950740197c425fa281c205a527a11867301b8ec7a0f2a12f5f49d8687a0ee911
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506
    Port:           80/TCP
    Host Port:      0/TCP
    State:
          Waiting      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Tue, 12 Oct 2021 13:10:06 +1100
      Finished:     Tue, 12 Oct 2021 13:10:13 +1100
    Ready:          False
    Restart Count:  5
    Liveness:       http-get http://:8080/ delay=3s timeout=1s period=2s #success=1 #failure=3
    ...
Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Pulled     2m25s                  kubelet            Successfully pulled image "nginx" in 1.876232575s
  Warning  Unhealthy  2m17s (x9 over 2m41s)  kubelet            Liveness probe failed: Get "http://192.168.79.220:8080/": dial tcp 192.168.79.220:8080: connect: connection refused
  Normal   Killing    2m17s (x3 over 2m37s)  kubelet            Container nginx failed liveness probe, will be restarted
  Normal   Pulling    2m17s (x4 over 2m46s)  kubelet            Pulling image "nginx"

Si los pods siguen en estado Bucle de fallo de retroceso, siga los pasos del apartado Otras soluciones.

El pod está en estado Terminando

Si los pods están bloqueados en estado Terminando, compruebe el estado del nodo en el que se ejecutan, así como los finalizadores. Un finalizador es una función que procesa la terminación antes de que el pod pase a Terminado. Para obtener más información, consulte Finalizadores en el sitio web de Kubernetes. Para comprobar el finalizador del pod que se está terminando, ejecute el siguiente comando:

$ kubectl get po nginx -o yaml  

apiVersion: v1  
kind: Pod  
metadata:  
...  
  finalizers:  
  - sample/do-something  
...

En el ejemplo anterior, el pod pasa a Terminado solo después de eliminar el finalizador sample/do-something. Por lo general, un controlador personalizado procesa el finalizador y, a continuación, lo elimina. A continuación, el pod pasa al estado Terminado.

Para solucionar este problema, compruebe si el pod del controlador personalizado se ejecuta correctamente. Solucione cualquier problema con el módulo del controlador y deje que el controlador personalizado complete el proceso del finalizador. A continuación, el pod pasará automáticamente al estado Terminado. Como alternativa, ejecute el siguiente comando para eliminar directamente el finalizador:

$ kubectl edit po nginx

Otras soluciones

Si el pod sigue atascado, siga estos pasos:

  1. Para confirmar si los nodos de trabajo están en el clúster y su estado es Preparado, ejecute el siguiente comando:

    $ kubectl get nodes

    Si el estado de los nodos es No preparado, consulte ¿Cómo puedo cambiar el estado de mis nodos de NotReady o Unknown a Ready? Si los nodos no pueden unirse al clúster, consulte ¿Cómo puedo hacer que mis nodos de trabajo se unan a mi clúster de Amazon EKS?

  2. Para comprobar la versión del clúster de Kubernetes, ejecute el siguiente comando:

    $ kubectl version --short
  3. Para comprobar la versión del nodo de trabajo de Kubernetes, ejecute el siguiente comando:

    $ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
  4. Confirme si la versión del servidor de Kubernetes del clúster coincide con la versión de los nodos de trabajo, con un sesgo de versión aceptable. Para obtener más información, consulte Version skew policy en el sitio web de Kubernetes.
    Importante: Las versiones de parches del clúster pueden ser distintas a las del nodo de trabajo, por ejemplo, el clúster puede tener la versión v1.21.x, y el nodo de trabajo la versión v1.21.y. Si las versiones del clúster y del nodo de trabajo son incompatibles, utilice eksctl o AWS CloudFormation para crear un nuevo grupo de nodos. Como alternativa, use una versión de Kubernetes compatible para crear un nuevo grupo de nodos administrado, como Kubernetes: v1.21, platform: eks.1 y versiones posteriores. A continuación, elimine el grupo de nodos con la versión incompatible de Kubernetes.

  5. Confirme que el plano de control de Kubernetes pueda comunicarse con los nodos de trabajo. Compare las reglas del firewall con las reglas requeridas en Requisitos y consideraciones sobre grupos de seguridad de Amazon EKS. A continuación, compruebe que los nodos estén en estado Preparado.

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace 3 meses