¿Cómo puedo solucionar los problemas relacionados con el estado de los pods en Amazon EKS?
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:
-
Para averiguar el estado del pod, ejecute el siguiente comando:
$ kubectl get pod
-
Para obtener información del historial Eventos de su pod, ejecute el siguiente comando:
$ kubectl describe pod YOUR_POD_NAME
-
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:
-
Compruebe que la imagen especificada esté disponible en el repositorio y que se hayan configurado los permisos correctos para poder extraer la imagen.
-
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
-
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:
-
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?
-
Para comprobar la versión del clúster de Kubernetes, ejecute el siguiente comando:
$ kubectl version --short
-
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
-
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. -
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.
Vídeos relacionados
Contenido relevante
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 2 años
- OFICIAL DE AWSActualizada hace 2 años