Como soluciono problemas de status do pod no Amazon EKS?

10 minuto de leitura
0

Meus pods do Amazon Elastic Kubernetes Service (Amazon EKS) que estão sendo executados em instâncias do Amazon Elastic Compute Cloud (Amazon EC2) ou em um grupo de nós gerenciados estão bloqueados. Quero colocar meus pods no estado “Running” ou “Terminated”.

Resolução

Importante: as etapas a seguir se aplicam somente aos pods lançados em instâncias do Amazon EC2 ou em um grupo de nós gerenciados. Essas etapas não se aplicam aos pods lançados no AWS Fargate.

Encontrar o status do seu pod

Para solucionar o problema do status do pod no Amazon EKS, conclua as seguintes etapas:

  1. Para obter o status do seu pod, execute o seguinte comando:

    $ kubectl get pod
  2. Para obter informações do histórico de Eventos do seu pod, execute o seguinte comando:

    $ kubectl describe pod YOUR_POD_NAME
  3. Com base no status do seu pod, conclua as etapas na seção a seguir.

Seu pod está no estado Pendente

Observação: os comandos de exemplo nas etapas a seguir estão no namespace padrão. Para outros namespaces, acrescente o comando com -n YOURNAMESPACE.

Os pods podem ficar presos em um estado Pending devido à insuficiência de recursos ou porque você definiu um hostPort. Para obter mais informações, consulte Pod phase no site do Kubernetes.

Se não tiver recursos suficientes nos nós de processamento, exclua os pods desnecessários. Você também pode adicionar mais recursos aos nós de processamento. Quando você não tem recursos suficientes em seu cluster, use o Kubernetes Cluster Autoscaler para escalar automaticamente seu grupo de nós de processamento.

Exemplo 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.

Exemplo de memória 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.

Se você definiu um hostPort para seu pod, siga estas práticas recomendadas:

  • Porque a combinação de hostIP, hostPort e protocolo deve ser única, especificar um hostPort somente quando necessário.
  • Se você especificar um hostPort, agende o mesmo número de pods que existem nós de processamento.

Observação: ao vincular um pod a um hostPort, há um número limitado de lugares onde você pode programar um pod.

O exemplo a seguir mostra a saída do comando describe para um pod que está no estado Pending, frontend-port-77f67cff67-2bv7w. O pod não está programado porque a porta do host solicitada não está disponível para os nós de processamento no cluster:

$ 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.

Se você não puder programar os pods porque os nós têm taints que o pod não permite, o exemplo de saída é semelhante ao seguinte:

$ 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 verificar os taints dos seus nós, execute o seguinte comando:

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

Para reter os taints do seu nó, especifique uma tolerância para um pod no PodSpec. Para obter mais informações, consulte Conceitos no site do Kubernetes. Ou acrescente**-** ao final do valor da contaminação para remover o taint do nó:

$ kubectl taint nodes NODE_Name key1=value1:NoSchedule-

Se seus pods ainda estiverem no estado Pending, conclua as etapas na seção Solução de problemas adicionais.

Seu contêiner está no estado Aguardando

Seu contêiner pode estar no estado Waiting devido a uma imagem incorreta do Docker ou a um nome de repositório incorreto. Ou seu pod pode estar no estado Waiting porque a imagem não existe ou você não tem permissões.

Para confirmar se a imagem e o nome do repositório estão corretos, faça login no Docker Hub, no Amazon Elastic Container Registry (Amazon ECR) ou em outro repositório de imagens de contêiner. Compare o repositório ou a imagem do repositório com o nome do repositório ou da imagem especificado na especificação do pod. Se a imagem não existir ou você não tiver permissões, conclua as seguintes etapas:

  1. Verifique se a imagem especificada está disponível no repositório e se as permissões corretas estão configuradas para permitir que você extraia a imagem.

  2. Para confirmar que é possível extrair a imagem e se não há problemas gerais de permissão de rede e repositório, extraia a imagem manualmente. Você deve usar o Docker para extrair a imagem dos nós de processamento do Amazon EKS:

    $ docker pull yourImageURI:yourImageTag
  3. Para verificar se a imagem existe, verifique se a imagem e a tag estão no Docker Hub ou no Amazon ECR.

Observação: se você usa o Amazon ECR, verifique se a política do repositório permite a extração de imagens para o NodeInstanceRole. Ou verifique se a função AmazonEC2ContainerRegistryReadOnly está anexada à política.
O exemplo a seguir mostra um pod no estado Pending com o contêiner no estado Waiting devido a um erro de extração de imagem:

$ 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

Se seus contêineres ainda estiverem no estado Waiting, conclua as etapas na seção Solução de problemas adicionais.

Seu pod está no estado CrashLoopBackOff

Se você receber a mensagem de saída “Recuar a reinicialização do contêiner com falha”, seu contêiner pode ter saído logo após o Kubernetes iniciá-lo.

Para procurar erros nos registros do pod atual, execute o seguinte comando:

$ kubectl logs YOUR_POD_NAME

Para procurar erros nos registros do pod anterior que falhou, execute o seguinte comando:

$ kubectl logs --previous YOUR-POD_NAME

Para um pod com vários contêineres, acrescente o nome do contêiner no final. Por exemplo:

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

Se a sonda de vivacidade não retornar o status Successful, verifique se a sonda de vivacidade está configurada corretamente para a aplicação. Para obter mais informações, consulte Configurar sondas no site do Kubernetes.

O exemplo a seguir mostra um pod no estado CrashLoopBackOff porque o aplicativo sai depois de ser iniciado:

$ 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

Veja a seguir um exemplo de sonda de vivacidade que falha no 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"

Se seus pods ainda estiverem no estado CrashLoopBackOff, conclua as etapas na seção Solução de problemas adicionais.

Seu pod está no estado Encerramento

Se seus pods estiverem presos em um estado Terminating, verifique a integridade do nó em que o pod está sendo executado e dos finalizadores. Um finalizador é uma função que executa o processamento de encerramento antes da transição do pod para Terminated. Para obter mais informações, consulte Finalizadores no site do Kubernetes. Para verificar o finalizador do pod de encerramento, execute o seguinte comando:

$ kubectl get po nginx -o yaml  

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

No exemplo anterior, o pod faz a transição para Terminated somente depois que o finalizador sample/do-something é removido. Geralmente, um controlador personalizado processa o finalizador e depois o remove. Em seguida, o pod passa para o estado Terminated.

Para resolver esse problema, verifique se o pod do controlador personalizado está funcionando corretamente. Resolva qualquer problema com o pod do controlador e deixe o controlador personalizado concluir o processo de finalização. Em seguida, o pod passa automaticamente para o estado Terminated. Ou execute o seguinte comando para excluir diretamente o finalizador:

$ kubectl edit po nginx

Solução de problemas adicionais

Se o pod ainda estiver preso, conclua as seguintes etapas:

  1. Para confirmar se os nós de processamento estão no cluster e no status Ready, execute o seguinte comando:

    $ kubectl get nodes

    Se o status dos nós for NotReady, consulte Como posso alterar o status dos meus nós de NotReady ou Unknown para Ready? Se os nós não conseguirem se juntar ao cluster, consulte Como posso fazer com que meus nós de processamento se juntem ao meu cluster Amazon EKS?

  2. Para verificar a versão do cluster Kubernetes, execute o seguinte comando:

    $ kubectl version --short
  3. Para verificar a versão do nó de processamento do Kubernetes, execute o seguinte comando:

    $ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
  4. Confirme se a versão do servidor Kubernetes para o cluster corresponde à versão dos nós de processamento dentro de uma distorção de versão aceitável. Para obter mais informações, consulte a Política de distorção de versão no site do Kubernetes.
    Importante: as versões do patch podem ser diferentes entre o cluster e o nó de processamento, como v1.21.x para o cluster e v1.21.y para o nó de processamento. Se as versões do cluster e do nó de processamento forem incompatíveis, use eksctl ou AWS CloudFormation para criar um novo grupo de nós. Ou use uma versão do Kubernetes compatível para criar um novo grupo de nós gerenciados, como Kubernetes: v1.21, plataforma: eks.1 e superior. Em seguida, exclua o grupo de nós que contém a versão incompatível do Kubernetes.

  5. Confirme se o plano de controle do Kubernetes pode se comunicar com os nós de processamento. Compare as regras de firewall com as regras exigidas nos requisitos e considerações do grupo de segurança do Amazon EKS. Em seguida, verifique se os nós estão no status Ready.

AWS OFICIAL
AWS OFICIALAtualizada há 3 meses