Risolvere i problemi relativi ai workload di cui è stato eseguito il deployment


Questa pagina mostra come risolvere gli errori relativi ai carichi di lavoro di cui è stato eseguito il deployment in Google Kubernetes Engine (GKE).

Per consigli più generali sulla risoluzione dei problemi delle applicazioni, consulta la sezione Risoluzione dei problemi delle applicazioni nella documentazione di Kubernetes.

Tutti gli errori: controlla lo stato del pod

Se si verificano problemi con i pod di un carico di lavoro, Kubernetes aggiorna lo stato del pod con un messaggio di errore. Visualizza questi errori controllando lo stato di un pod utilizzando la console Google Cloud o lo strumento a riga di comando kubectl.

Console

Procedi nel seguente modo:

  1. Nella console Google Cloud, vai alla pagina Carichi di lavoro.

    Vai a Carichi di lavoro

  2. Seleziona il carico di lavoro che vuoi esaminare. La scheda Panoramica visualizza lo stato del carico di lavoro.

  3. Nella sezione Pod gestiti, fai clic su un messaggio di stato di errore.

kubectl

Per visualizzare tutti i pod in esecuzione nel cluster, esegui il seguente comando:

kubectl get pods

L'output è simile al seguente:

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

I potenziali errori sono elencati nella colonna Status.

Per visualizzare ulteriori informazioni su un pod specifico, esegui il seguente comando:

kubectl describe pod POD_NAME

Sostituisci POD_NAME con il nome del pod che vuoi esaminare.

Nell'output, il campo Events mostra ulteriori informazioni sugli errori.

Per ulteriori informazioni, visualizza i log del contenitore:

kubectl logs POD_NAME

Questi log possono aiutarti a identificare se un comando o un codice nel contenitore ha causato un arresto anomalo del pod.

Dopo aver identificato l'errore, utilizza le sezioni seguenti per provare a risolverlo.

Errore: CrashLoopBackOff

Uno stato CrashLoopBackOff non indica che si è verificato un errore specifico, ma indica che un container si arresta in modo anomalo ripetutamente dopo il riavvio. Quando un container si arresta in modo anomalo o esce poco dopo l'avvio (CrashLoop), Kubernetes tenta di riavviarlo. A ogni riavvio non riuscito, il ritardo (BackOff) prima del tentativo successivo aumenta in modo esponenziale (10 secondi, 20 secondi, 40 secondi e così via), fino a un massimo di cinque minuti.

Le sezioni seguenti ti aiutano a identificare il motivo per cui il contenitore potrebbe avere un arresto anomalo.

Utilizzare il playbook interattivo sui pod con arresto anomalo in loop

Per iniziare a risolvere i problemi che causano uno stato CrashLoopBackOff, utilizza il playbook interattivo nella console Google Cloud:

  1. Vai al playbook interattivo sui pod con arresto anomalo in loop:

    Vai a Playbook

  2. Nell'elenco a discesa Cluster, seleziona il cluster di cui vuoi risolvere i problemi. Se non riesci a trovare il cluster, inserisci il nome del cluster nel campo Filtra.

  3. Nell'elenco a discesa Spazio dei nomi, seleziona lo spazio dei nomi di cui vuoi risolvere i problemi. Se non riesci a trovare il tuo spazio dei nomi, inseriscilo nel campo Filtra.

  4. Esamina ciascuna sezione per identificare la causa:

    1. Identifica gli errori dell'applicazione
    2. Esamina i problemi di memoria
    3. Analisi delle interruzioni del nodo
    4. Esamina gli errori dei probe di attività
    5. Correla eventi di modifica
  5. (Facoltativo) Per ricevere notifiche su errori CrashLoopBackOff futuri, nella sezione Suggerimenti per la mitigazione futura, seleziona Crea un avviso.

Controllare i log

Un container potrebbe arrestarsi in modo anomalo per diversi motivi e la verifica dei log di un pod può aiutarti a risolvere il problema alla radice.

Puoi controllare i log con la console Google Cloud o lo strumento a riga di comando kubectl.

Console

Procedi nel seguente modo:

  1. Vai alla pagina Carichi di lavoro nella console Google Cloud.

    Vai a Carichi di lavoro

  2. Seleziona il carico di lavoro che vuoi esaminare. La scheda Panoramica visualizza lo stato del carico di lavoro.

  3. Nella sezione Pod gestiti, fai clic sul pod problematico.

  4. Nel menu del pod, fai clic sulla scheda Log.

kubectl

  1. Visualizza tutti i pod in esecuzione nel cluster:

    kubectl get pods
    
  2. Nell'output del comando precedente, cerca un pod con l'errore CrashLoopBackOff nella colonna Status.

  3. Recupera i log del pod:

    kubectl logs POD_NAME
    

    Sostituisci POD_NAME con il nome del pod problematico.

    Puoi anche passare il flag -p per ottenere i log per l'istanza precedente del contenitore di un pod, se esistente.

Controlla il codice di uscita del contenitore in crash

Per capire meglio il motivo dell'arresto anomalo del contenitore, individua il codice di uscita:

  1. Descrivi il pod:

    kubectl describe pod POD_NAME
    

    Sostituisci POD_NAME con il nome del pod problematico.

  2. Controlla il valore nel campo containers: CONTAINER_NAME: last state: exit code:

    • Se il codice di uscita è 1, il contenitore si è arrestato in modo anomalo a causa di un arresto anomalo dell'applicazione.
    • Se il codice di uscita è 0, controlla per quanto tempo è stata in esecuzione l'app. I contenitori vengono chiusi quando esce il processo principale dell'applicazione. Se l'esecuzione dell'app termina molto rapidamente, il contenitore potrebbe continuare a riavviarsi. Se si verifica questo errore, una soluzione è impostare il campo restartPolicy su OnFailure. Dopo aver apportato questa modifica, l'app si riavvia solo quando il codice di uscita non è 0.

Connettiti a un contenitore in esecuzione

Per eseguire comandi bash dal contenitore in modo da poter testare la rete o verificare se hai accesso a file o database utilizzati dalla tua applicazione, apri una shell per il pod:

kubectl exec -it POD_NAME -- /bin/bash

Se il pod contiene più di un container, aggiungi -c CONTAINER_NAME.

Errori: ImagePullBackOff ed ErrImagePull

Uno stato ImagePullBackOff o ErrImagePull indica che l'immagine utilizzata da un contenitore non può essere caricata dal registry delle immagini.

Puoi verificare questo problema utilizzando la console Google Cloud o lo strumento a riga di comando kubectl.

Console

Procedi nel seguente modo:

  1. Nella console Google Cloud, vai alla pagina Carichi di lavoro.

    Vai a Carichi di lavoro

  2. Seleziona il carico di lavoro che vuoi esaminare. La scheda Panoramica visualizza lo stato del carico di lavoro.

  3. Nella sezione Pod gestiti, fai clic sul pod problematico.

  4. Nel menu del pod, fai clic sulla scheda Eventi.

kubectl

Per ottenere maggiori informazioni sull'immagine del contenitore di un pod, esegui il seguente comando:

kubectl describe pod POD_NAME

Problema: l'immagine non viene trovata

Se l'immagine non viene trovata, completa i seguenti passaggi:

  1. Verifica che il nome dell'immagine sia corretto.
  2. Verifica che il tag dell'immagine sia corretto. Prova :latest o nessun tag per recuperare l'immagine più recente.
  3. Se l'immagine ha un percorso del registry completo, verifica che esista nel registro Docker che stai utilizzando. Se fornisci solo il nome dell'immagine, controlla il registro Docker Hub.
  4. Nei cluster GKE Standard, prova a eseguire il pull dell'immagine Docker manualmente:

    1. Utilizza SSH per connetterti al nodo:

      Ad esempio, per utilizzare SSH per connetterti a una VM, esegui il seguente comando:

      gcloud compute ssh VM_NAME --zone=ZONE_NAME
      

      Sostituisci quanto segue:

    2. Genera un file di configurazione in /home/[USER]/.docker/config.json:

      docker-credential-gcr configure-docker
      

      Assicurati che il file di configurazione in /home/[USER]/.docker/config.json includa il registry dell'immagine nel campo credHelpers. Ad esempio, il seguente file include le informazioni di autenticazione per le immagini ospitate su asia.gcr.io, eu.gcr.io, gcr.io, marketplace.gcr.io e us.gcr.io:

      {
      "auths": {},
      "credHelpers": {
        "asia.gcr.io": "gcr",
        "eu.gcr.io": "gcr",
        "gcr.io": "gcr",
        "marketplace.gcr.io": "gcr",
        "us.gcr.io": "gcr"
      }
      }
      
    3. Prova a eseguire il pull dell'immagine:

      docker pull IMAGE_NAME
      

    Se l'estrazione dell'immagine funziona manualmente, probabilmente devi specificare ImagePullSecrets su un pod. I pod possono fare riferimento ai secret di estrazione delle immagini solo nel proprio spazio dei nomi, quindi questa procedura deve essere eseguita una volta per spazio dei nomi.

Errore: autorizzazione negata

Se ricevi l'errore "Autorizzazione negata" o "Nessun accesso in pull", verifica di aver eseguito l'accesso e di avere accesso all'immagine. Prova uno dei seguenti metodi, a seconda del registry in cui ospiti le immagini.

Artifact Registry

Se l'immagine si trova in Artifact Registry, l'account di servizio del pool di nodi deve disporre dell'accesso in lettura al repository che contiene l'immagine.

Concedi il ruolo artifactregistry.reader all'account di servizio:

gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
    --location=REPOSITORY_LOCATION \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role="roles/artifactregistry.reader"

Sostituisci quanto segue:

  • REPOSITORY_NAME: il nome del repository Artifact Registry.
  • REPOSITORY_LOCATION: la regione del repository Artifact Registry.
  • SERVICE_ACCOUNT_EMAIL: l'indirizzo email dell'account di servizio IAM associato al tuo pool di nodi.

Container Registry

Se l'immagine si trova in Container Registry, il service account del pool di nodi ha bisogno dell'accesso in lettura al bucket Cloud Storage che contiene l'immagine.

Concedi il ruolo roles/storage.objectViewer all'account di servizio in modo che possa leggere dal bucket:

gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role=roles/storage.objectViewer

Sostituisci quanto segue:

  • SERVICE_ACCOUNT_EMAIL: l'indirizzo email dell'account servizio associato al tuo pool di nodi. Puoi elencare tutti gli account di servizio nel tuo progetto utilizzando gcloud iam service-accounts list.
  • BUCKET_NAME: il nome del bucket Cloud Storage che contiene le immagini. Puoi elencare tutti i bucket del tuo progetto utilizzando gcloud storage ls.

Se l'amministratore del registry ha configurato repository gcr.io in Artifact Registry per archiviare le immagini per il dominio gcr.io anziché in Container Registry, devi concedere l'accesso in lettura ad Artifact Registry anziché a Container Registry.

Registry privato

Se l'immagine si trova in un registry privato, potresti aver bisogno di chiavi per accedere alle immagini. Per ulteriori informazioni, consulta la sezione Utilizzo dei registry privati nella documentazione di Kubernetes.

Errore 401 Unauthorized: Cannot pull images from private container registry repository

Quando estrae un'immagine da un repository Container Registry privato, potrebbe verificarsi un errore simile al seguente:

gcr.io/PROJECT_ID/IMAGE:TAG: rpc error: code = Unknown desc = failed to pull and
unpack image gcr.io/PROJECT_ID/IMAGE:TAG: failed to resolve reference
gcr.io/PROJECT_ID/IMAGE]:TAG: unexpected status code [manifests 1.0]: 401 Unauthorized

Warning  Failed     3m39s (x4 over 5m12s)  kubelet            Error: ErrImagePull
Warning  Failed     3m9s (x6 over 5m12s)   kubelet            Error: ImagePullBackOff
Normal   BackOff    2s (x18 over 5m12s)    kubelet            Back-off pulling image

Per risolvere l'errore:

  1. Identifica il nodo su cui è in esecuzione il pod:

    kubectl describe pod POD_NAME | grep "Node:"
    
  2. Verifica che il nodo identificato nel passaggio precedente abbia l'ambito di archiviazione:

    gcloud compute instances describe NODE_NAME \
        --zone=COMPUTE_ZONE --format="flattened(serviceAccounts[].scopes)"
    

    L'ambito di accesso del nodo deve contenere almeno uno dei seguenti ambiti:

    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform
    

    Se il nodo non contiene uno di questi ambiti, ricrea il pool di nodi.

  3. Ricrea il pool di nodi a cui appartiene il nodo con un ambito sufficiente. Non puoi modificare i nodi esistenti, devi ricrearli con l'ambito corretto.

    • Consigliato: crea un nuovo pool di nodi con l'ambito gke-default:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="gke-default"
      
    • Crea un nuovo pool di nodi con ambito di archiviazione:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="https://www.googleapis.com/auth/devstorage.read_only"
      

Errore: pod non pianificabile

Uno stato PodUnschedulable indica che il pod non può essere pianificato per motivi di risorse insufficienti o per qualche errore di configurazione.

Se hai configurato le metriche del control plane, puoi trovare ulteriori informazioni su questi errori nelle metriche dello scheduler e nelle metriche del server API.

Utilizzare il playbook interattivo per i pod non pianificabili

Puoi risolvere i problemi relativi agli errori PodUnschedulable utilizzando il playbook interattivo nella console Google Cloud:

  1. Vai al playbook interattivo per i pod non pianificabili:

    Vai a Playbook

  2. Nell'elenco a discesa Cluster, seleziona il cluster di cui vuoi risolvere i problemi. Se non riesci a trovare il cluster, inserisci il nome del cluster nel campo Filtra.

  3. Nell'elenco a discesa Spazio dei nomi, seleziona lo spazio dei nomi di cui vuoi risolvere i problemi. Se non riesci a trovare lo spazio dei nomi, inseriscilo nel campo Filtra.

  4. Per aiutarti a identificare la causa, esamina ciascuna sezione del manuale operativo:

    1. Esamina CPU e memoria
    2. Esamina il numero massimo di pod per nodo
    3. Esamina il comportamento del gestore della scalabilità automatica
    4. Esamina altre modalità di errore
    5. Correla eventi di modifica
  5. (Facoltativo) Per ricevere notifiche su errori PodUnschedulable futuri, nella sezione Suggerimenti per la mitigazione futura, seleziona Crea un avviso .

Errore: risorse insufficienti

Potresti visualizzare un messaggio di errore che indica una mancanza di CPU, memoria o un'altra risorsa. Ad esempio: No nodes are available that match all of the predicates: Insufficient cpu (2), che indica che su due nodi non è disponibile sufficiente CPU per soddisfare le richieste di un pod.

Se le richieste di risorse del pod superano quelle di un singolo nodo di qualsiasi node pool idoneo, GKE non pianifica il pod e non attiva lo scale up per aggiungere un nuovo nodo. Affinché GKE possa pianificare il pod, devi richiedere meno risorse per il pod o creare un nuovo pool di nodi con risorse sufficienti.

Puoi anche attivare il provisioning automatico dei nodi in modo che GKE possa creare automaticamente pool di nodi con nodi su cui possono essere eseguiti i pod non pianificati.

La richiesta di CPU predefinita è 100 m o il 10% di una CPU (o un core). Se vuoi richiedere più o meno risorse, specifica il valore nella specifica del pod in spec: containers: resources: requests.

Errore: MatchNodeSelector

MatchNodeSelector indica che non sono presenti nodi corrispondenti al selettore di etichette del pod.

Per verificare, controlla le etichette specificate nel campo nodeSelector della specifica del pod in spec: nodeSelector.

Per vedere come sono etichettati i nodi del cluster, esegui il seguente comando:

kubectl get nodes --show-labels

Per associare un'etichetta a un nodo, esegui il seguente comando:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

Sostituisci quanto segue:

  • NODE_NAME: il nodo a cui vuoi aggiungere un'etichetta.
  • LABEL_KEY: la chiave dell'etichetta.
  • LABEL_VALUE: il valore dell'etichetta.

Per saperne di più, consulta Assegnazione di pod ai nodi nella documentazione di Kubernetes.

Errore: PodToleratesNodeTaints

PodToleratesNodeTaints indica che il pod non può essere pianificato su nessun nodo perché non ha tolleranze corrispondenti alle incompatibilità dei nodi esistenti.

Per verificare che sia così, esegui questo comando:

kubectl describe nodes NODE_NAME

Nell'output, controlla il campo Taints, che elenca le coppie chiave-valore e gli effetti di pianificazione.

Se l'effetto elencato è NoSchedule, nessun pod può essere pianificato su quel nodo a meno che non abbia una tolleranza corrispondente.

Un modo per risolvere il problema è rimuovere l'alterazione. Ad esempio, per rimuovere un'alterazione NoSchedule, esegui il seguente comando:

kubectl taint nodes NODE_NAME key:NoSchedule-

Errore: PodFitsHostPorts

L'errore PodFitsHostPorts indica che un nodo sta tentando di utilizzare una porta già occupata.

Per risolvere il problema, ti consigliamo di seguire le best practice di Kubernetes e di utilizzare un NodePort anziché un hostPort.

Se devi utilizzare un hostPort, controlla i manifest dei pod e assicurati che tutti i pod sullo stesso nodo abbiano valori univoci definiti per hostPort.

Errore: non ha disponibilità minima

Se un nodo dispone di risorse adeguate, ma visualizzi ancora il messaggio Does not have minimum availability, controlla lo stato del pod. Se lo stato è SchedulingDisabled o Cordoned, il nodo non può pianificare nuovi pod. Puoi controllare lo stato di un nodo utilizzando la console Google Cloud o lo strumento a riga di comando kubectl.

Console

Procedi nel seguente modo:

  1. Vai alla pagina Google Kubernetes Engine nella console Google Cloud.

    Vai a Google Kubernetes Engine

  2. Seleziona il cluster che vuoi esaminare. La scheda Nodi mostra i nodi e il relativo stato.

Per attivare la pianificazione sul nodo, svolgi i seguenti passaggi:

  1. Nell'elenco, fai clic sul nodo che vuoi esaminare.

  2. Nella sezione Dettagli nodo, fai clic su Rimuovi da cordone.

kubectl

Per ottenere gli stati dei nodi, esegui il seguente comando:

kubectl get nodes

Per attivare la pianificazione sul nodo, esegui:

kubectl uncordon NODE_NAME

Errore: limite massimo di pod per nodo raggiunto

Se il limite di pod massimi per nodo viene raggiunto da tutti i nodi del cluster, i pod rimarranno bloccati nello stato Non pianificabile. Nella scheda Eventi del pod, viene visualizzato un messaggio che include la frase Too many pods.

Per risolvere il problema, segui questi passaggi:

  1. Controlla la configurazione di Maximum pods per node dalla scheda Nodi nei dettagli del cluster GKE nella console Google Cloud.

  2. Recupera un elenco di nodi:

    kubectl get nodes
    
  3. Per ogni nodo, verifica il numero di pod in esecuzione sul nodo:

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. Se viene raggiunto il limite, aggiungi un nuovo pool di nodi o altri nodi al pool di nodi esistente.

Problema: dimensione massima pool di nodi raggiunta con la scalabilità automatica del cluster abilitata

Se il pool di nodi ha raggiunto la dimensione massima in base alla configurazione del gestore della scalabilità automatica del cluster, GKE non attiva lo scale up per il pod che altrimenti verrebbe pianificato con questo pool di nodi. Se vuoi che il pod venga pianificato con questo pool di nodi, modifica la configurazione del gestore della scalabilità automatica del cluster.

Problema: dimensione massima del pool di nodi raggiunta con il gestore della scalabilità automatica del cluster disabilitato

Se il pool di nodi ha raggiunto il numero massimo di nodi e il gestore della scalabilità automatica dei cluster è disabilitato, GKE non può pianificare il pod con il pool di nodi. Aumenta le dimensioni del node pool o abilita la scalabilità automatica del cluster per consentire a GKE di ridimensionare automaticamente il cluster.

Errore: PersistentVolumeClaim non vincolati

Unbound PersistentVolumeClaims indica che il pod fa riferimento a un PersistentVolumeClaim non associato. Questo errore può verificarsi se non è stato eseguito il provisioning del volume permanente. Puoi verificare che il provisioning non sia riuscito recuperando gli eventi per il tuo PersistentVolumeClaim ed esaminandoli per verificare la presenza di errori.

Per ottenere gli eventi, esegui il seguente comando:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

Sostituisci quanto segue:

  • STATEFULSET_NAME: il nome dell'oggetto StatefulSet.
  • PVC_NAME: il nome dell'oggetto PersistentVolumeClaim.

Ciò può accadere anche se si è verificato un errore di configurazione durante il pre-provisioning manuale di un volume permanente e la relativa associazione a una richiesta di volume permanente.

Per risolvere questo errore, prova a eseguire di nuovo il provisioning preventivo del volume.

Errore: quota insufficiente

Verifica che il tuo progetto disponga di una quota Compute Engine sufficiente per consentire a GKE di eseguire l'upgrade del cluster. Se GKE tenta di aggiungere un nodo al cluster per pianificare il pod e l'aumento di scala supererebbe la quota disponibile del progetto, riceverai il messaggio di errore scale.up.error.quota.exceeded.

Per saperne di più, consulta Errori di ScaleUp.

Problema: API deprecate

Assicurati di non utilizzare API ritirate che vengono rimosse con la versione minore del tuo cluster. Per saperne di più, consulta Ritiro di funzionalità di GKE.

Errore: non sono disponibili porte libere per le porte del pod richieste

Se viene visualizzato un errore simile al seguente, è probabile che tu abbia più pod nello stesso nodo con lo stesso valore definito nel campo hostPort:

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

L'associazione di un pod a un hostPort limita la pianificazione del pod da parte di GKE perché ogni combinazione di hostIP, hostPort e protocol deve essere unica.

Per risolvere il problema, ti consigliamo di seguire le best practice di Kubernetes e di utilizzare un NodePort anziché un hostPort.

Se devi utilizzare un hostPort, controlla i manifest dei pod e assicurati che tutti i pod sullo stesso nodo abbiano valori univoci definiti per hostPort.

Passaggi successivi

Se hai bisogno di ulteriore assistenza, contatta l'assistenza clienti Google Cloud.