Come faccio a risolvere i problemi relativi allo stato dei pod in Amazon EKS?

10 minuti di lettura
0

I miei pod Amazon Elastic Kubernetes Service (Amazon EKS) in esecuzione su istanze Amazon Elastic Compute Cloud (Amazon EC2) o su un gruppo di nodi gestiti sono bloccati. Voglio che ai miei pod venga assegnato lo stato "Running" o "Terminated".

Risoluzione

Importante: i seguenti passaggi si applicano solo ai pod avviati su istanze Amazon EC2 o in un gruppo di nodi gestiti. Non si applicano quindi ai pod avviati su AWS Fargate.

Scopri lo stato del tuo pod

Per risolvere i problemi relativi allo stato dei pod su Amazon EKS, completa i seguenti passaggi:

  1. Per verificare lo stato del tuo pod, esegui questo comando:

    $ kubectl get pod
  2. Per consultare la cronologia degli Eventi associata al tuo pod, esegui questo comando:

    $ kubectl describe pod YOUR_POD_NAME
  3. In base allo stato del tuo pod, completa i passaggi indicati nella sezione seguente.

Il tuo pod è nello stato Pending

Nota: i comandi di esempio mostrati nei passaggi seguenti includono uno spazio dei nomi predefinito. Per utilizzare altri spazi dei nomi dovrai aggiungere -n YOURNAMESPACE.

I pod potrebbero bloccati nello stato Pending a causa della mancanza di risorse o del fatto che avevi definito una hostPort. Per maggiori dettagli, consulta la sezione Pod phase sul sito web di Kubernetes.

Se non disponi di risorse sufficienti sui nodi worker, elimina i pod superflui. Puoi anche aggiungere altre risorse ai nodi worker. Se non hai abbastanza risorse nel cluster, usa la Scalabilità automatica di Kubernetes per dimensionare automaticamente il tuo gruppo di nodi worker.

Esempio di CPU insufficiente:

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

Esempio di memoria insufficiente:

$ 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 hai definito una hostPort per il tuo pod, segui queste best practice:

  • Poiché la combinazione hostIP, hostPort e protocol deve essere univoca, specifica una hostPort solo se necessario.
  • Se specifichi una hostPort, programma una quantità di pod corrispondente al numero di nodi worker.

Nota: quando associ un pod a una hostPort, il numero di posti in cui puoi programmare un pod è limitato.

L'esempio seguente mostra l'output del comando describe per un pod in stato Pending, frontend-port-77f67cff67-2bv7w. Il pod non è programmato perché la porta host richiesta non è disponibile per i nodi worker presenti nel 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 il motivo per cui non riesci a programmare i pod è dovuto al fatto che i nodi presentano dei taint non consentiti, otterrai un output simile a questo:

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

Per verificare i taint dei nodi, esegui questo comando:

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

Per mantenere i taint dei nodi, specifica un valore di tolleranza per un pod in PodSpec. Per maggiori dettagli, consulta la sezione Concepts sul sito web di Kubernetes. Oppure aggiungi - alla fine del valore del taint per rimuovere il taint del nodo:

$ kubectl taint nodes NODE_Name key1=value1:NoSchedule-

Se lo stato dei tuoi pod è ancora Pending, completa i passaggi descritti nella sezione Risoluzione di problemi aggiuntivi.

Il tuo container è nello stato Waiting

Il tuo container potrebbe essere nello stato Waiting a causa di un errore relativo all'immagine Docker o al nome del repository. Oppure il pod potrebbe essere nello stato Waiting anche se l'immagine non esiste o non disponi delle autorizzazioni.

Per verificare che l'immagine e il nome del repository siano corretti, accedi a Docker Hub, all'Amazon Elastic Container Registry (Amazon ECR) o a un altro repository di immagini del container. Confronta il repository o l'immagine contenuta nel repository con il nome di quest'ultimo o con quello dell'immagine indicato nelle specifiche del pod. Se l'immagine non esiste o non disponi delle autorizzazioni, completa i seguenti passaggi:

  1. Verifica che l'immagine specificata sia disponibile nel repository e che la configurazione delle autorizzazioni ne consenta l'estrazione.

  2. Estrai manualmente l'immagine per assicurarti che l'operazione sia consentita e verificare l'assenza di problemi relativi alla rete o alle autorizzazioni del repository. Per estrarre l'immagine dai nodi worker di Amazon EKS è necessario utilizzare Docker:

    $ docker pull yourImageURI:yourImageTag
  3. Per confermare l'esistenza dell'immagine, controlla che sia presente insieme al tag su Docker Hub o Amazon ECR.

Nota: se usi Amazon ECR, verifica che la policy del repository consenta l'estrazione dell'immagine per il NodeInstanceRole. Oppure verifica che il ruolo AmazonEC2ContainerRegistryReadOnly sia associato alla policy.
L'esempio seguente mostra un pod nello stato Pending con container nello stato Waiting a causa di un errore relativo all'estrazione dell'immagine:

$ 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 i tuoi container sono ancora nello stato Waiting, completa i passaggi indicati nella sezione Risoluzione di problemi aggiuntivi.

Lo stato del tuo pod è CrashLoopBackOff

Se ricevi il messaggio di output "Back-Off restarting failed container", significa che il container potrebbe essere stato chiuso subito dopo l'avvio da parte di Kubernetes.

Per cercare errori nei log del pod corrente, esegui questo comando:

$ kubectl logs YOUR_POD_NAME

Per cercare errori nei log del pod precedente che si è bloccato, esegui questo comando:

$ kubectl logs --previous YOUR-POD_NAME

Se un pod ha più container, aggiungi il nome di questi ultimi alla fine. Ad esempio:

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

se il probe di attività non restituisce lo stato Successful, verifica che sia configurato correttamente per l'applicazione. Per ulteriori informazioni, consulta la sezione Configure probes sul sito web di Kubernetes.

L'esempio seguente mostra un pod con stato CrashLoopBackOff dovuto alla chiusura dell'applicazione dopo l'avvio:

$ 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

Di seguito è riportato un esempio in cui il probe di attività per il pod non va a buon fine:

$ 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 lo stato dei tuoi pod è ancora CrashLoopBackOff, completa i passaggi indicati nella sezione Risoluzione di problemi aggiuntivi.

Il tuo pod è nello stato Terminating

Se i tuoi pod restano nello stato Terminating, verifica l'integrità del nodo su cui è eseguito il pod e i finalizer. Un finalizer è una funzione che elabora l'arresto prima che lo stato del pod venga modificato in Terminated. Per ulteriori informazioni, consulta la sezione Finalizers sul sito web di Kubernetes. Per controllare il finalizer per il pod in fase di arresto, esegui questo comando:

$ kubectl get po nginx -o yaml  

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

Nell'esempio precedente, lo stato del pod viene modificato in Terminated solo dopo che il finalizer sample/do-something è stato rimosso. In genere, un controller personalizzato elabora il finalizer e quindi lo rimuove. Il pod passerà quindi allo stato Terminated.

Per risolvere questo problema, verifica che il pod del controller personalizzato funzioni correttamente. Risolvi eventuali problemi rilevati con il pod del controller e lascia che il controller personalizzato completi il processo del finalizer. Il pod passerà quindi automaticamente allo stato Terminated. Oppure esegui questo comando per eliminare direttamente il finalizer:

$ kubectl edit po nginx

Risoluzione di problemi aggiuntivi

Se il pod è ancora bloccato, completa i seguenti passaggi:

  1. Per verificare la presenza dei nodi worker nel cluster e confermare che lo stato sia Ready, esegui questo comando:

    $ kubectl get nodes

    Se lo stato dei nodi è NotReady, consulta la sezione Come posso modificare lo stato dei nodi da NotReady o Unknown a Ready? Se i nodi non riescono a unirsi al cluster, consulta invece la sezione Come posso far sì che i miei nodi worker si uniscano al mio cluster Amazon EKS?

  2. Per verificare la versione del cluster di Kubernetes, esegui questo comando:

    $ kubectl version --short
  3. Per verificare la versione del nodo worker di Kubernetes, esegui questo comando:

    $ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
  4. Verifica che la versione del server di Kubernetes per il cluster corrisponda a quella dei nodi worker con un grado di disallineamento accettabile. Per ulteriori informazioni, consulta la sezione Version skew policy sul sito web di Kubernetes.
    Importante: le versioni delle patch possono essere diverse tra il cluster e il nodo worker. Ad esempio, v1.21.x per il cluster e v1.21.y per il nodo worker. Se le versioni del cluster e del nodo worker sono incompatibili, usa eksctl o AWS CloudFormation per creare un nuovo gruppo di nodi. In alternativa, utilizza una versione di Kubernetes compatibile per creare un nuovo gruppo di nodi gestiti (ad esempio Kubernetes: v1.21, platform: eks.1 e versioni successive). Quindi, elimina il gruppo di nodi che contiene la versione Kubernetes incompatibile.

  5. Verifica che il piano di controllo di Kubernetes sia in grado di comunicare con i nodi worker. Confronta le regole del firewall con quelle indicate nella sezione Considerazioni e requisiti relativi al gruppo di sicurezza Amazon EKS. Quindi, verifica che lo stato dei nodi sia Ready.

AWS UFFICIALE
AWS UFFICIALEAggiornata 3 mesi fa