Risoluzione dei problemi relativi ai cluster Autopilot

I problemi con i cluster Autopilot di Google Kubernetes Engine (GKE) possono influire sulla disponibilità e sull'efficienza operativa della tua applicazione. Questi problemi possono interrompere l'intero ciclo di vita delle tue applicazioni, dal deployment iniziale alla scalabilità sotto carico.

Utilizza questa pagina per diagnosticare e risolvere i problemi comuni specifici dei cluster Autopilot. Trova indicazioni sulla risoluzione dei problemi di creazione dei cluster che impediscono il provisioning del cluster, dei problemi di scalabilità come gli errori out of resources e dei problemi specifici dei workload, come gli errori di archiviazione temporanea o i pod bloccati nello stato Pending.

Queste informazioni sono importanti per gli sviluppatori di applicazioni che devono garantire che il deployment e l'esecuzione delle loro applicazioni avvengano senza problemi e per gli amministratori e gli operatori della piattaforma responsabili della gestione complessiva dello stato e delle risorse dei cluster Autopilot. Per saperne di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei contenuti di Google Cloud , consulta Ruoli e attività comuni degli utenti GKE.

Problemi relativi ai cluster

Impossibile creare un cluster: 0 nodi registrati

Il seguente problema si verifica quando tenti di creare un cluster Autopilot con un account di servizio IAM disattivato o privo delle autorizzazioni richieste. La creazione del cluster non riesce e viene visualizzato il seguente messaggio di errore:

All cluster resources were brought up, but: only 0 nodes out of 2 have registered.

Per risolvere il problema, segui questi passaggi:

  1. Controlla se il service account Compute Engine predefinito o il account di servizio IAM personalizzato che vuoi utilizzare è disattivato:

    gcloud iam service-accounts describe SERVICE_ACCOUNT
    

    Sostituisci SERVICE_ACCOUNT con l'indirizzo email del account di servizio, ad esempio my-iam-account@my-first-project.iam.gserviceaccount.com.

    Se il account di servizio è disabilitato, l'output è simile al seguente:

    disabled: true
    displayName: my-service-account
    email: my-service-account@my-project.iam.gserviceaccount.com
    ...
    
  2. Se il account di servizio è disabilitato, abilitalo:

    gcloud iam service-accounts enable SERVICE_ACCOUNT
    

Se il account di servizio è abilitato e l'errore persiste, concedi al account di servizio le autorizzazioni minime richieste per GKE:

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:SERVICE_ACCOUNT" \
    --role roles/container.defaultNodeServiceAccount

Spazio dei nomi bloccato nello stato Terminating quando il cluster ha 0 nodi

Il seguente problema si verifica quando elimini uno spazio dei nomi in un cluster dopo che il cluster ha eseguito lo scale down a zero nodi. Il componente metrics-server non può accettare la richiesta di eliminazione dello spazio dei nomi perché il componente non ha repliche.

Per diagnosticare il problema, esegui questo comando:

kubectl describe ns/NAMESPACE_NAME

Sostituisci NAMESPACE_NAME con il nome dello spazio dei nomi.

L'output è il seguente:

Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request

Per risolvere il problema, scala un workload in modo da attivare GKE per creare un nuovo nodo. Quando il nodo è pronto, la richiesta di eliminazione dello spazio dei nomi viene completata automaticamente. Dopo che GKE ha eliminato lo spazio dei nomi, riduci nuovamente il workload.

Problemi di scalabilità

Scale up del nodo non riuscito: il pod rischia di non essere pianificato

Il seguente problema si verifica quando il logging delle porte seriali è disabilitato nel tuo progettoGoogle Cloud . I cluster GKE Autopilot richiedono il logging della porta seriale per eseguire il debug dei problemi dei nodi in modo efficace. Se il logging della porta seriale è disabilitato, Autopilot non può eseguire il provisioning dei nodi per l'esecuzione dei workload.

Il messaggio di errore nel log eventi di Kubernetes è simile al seguente:

LAST SEEN   TYPE      REASON          OBJECT                          MESSAGE
12s         Warning   FailedScaleUp   pod/pod-test-5b97f7c978-h9lvl   Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled

Il logging della porta seriale potrebbe essere disattivato a livello di organizzazione tramite una policy dell'organizzazione che applica il vincolo compute.disableSerialPortLogging. Il logging della porta seriale potrebbe essere disattivato anche a livello di progetto o di istanza di macchina virtuale (VM).

Per risolvere il problema, segui questi passaggi:

  1. Chiedi all' Google Cloud amministratore delle policy dell'organizzazione di rimuovere il vincolo compute.disableSerialPortLogging nel progetto con il tuo cluster Autopilot.
  2. Se non hai una policy dell'organizzazione che applica questo vincolo, prova ad attivare il logging delle porte seriali nei metadati del progetto. Questa azione richiede l'autorizzazione IAM compute.projects.setCommonInstanceMetadata.

Scale up dei nodi non riuscito: Compute Engine ha esaurito le risorse

Il seguente problema si verifica quando i workload richiedono più risorse di quelle disponibili per l'utilizzo nella regione o nella zona di Compute Engine. I pod potrebbero rimanere nello stato Pending.

  • Controlla gli eventi del pod:

    kubectl events --for='pod/POD_NAME' --types=Warning
    

    Sostituisci RESOURCE_NAME con il nome della risorsa Kubernetes in attesa. Ad esempio pod/example-pod.

    L'output è simile al seguente:

    LAST SEEN         TYPE            REASON                  OBJECT                   Message
    19m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    14m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    12m (x2 over 18m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    34s (x3 over 17m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    

Per risolvere il problema, prova quanto segue:

  • Esegui il deployment del pod in una regione o zona diversa. Se il pod ha una limitazione di zona, ad esempio un selettore di topologia, rimuovi la limitazione, se possibile. Per istruzioni, consulta Posiziona i pod GKE in zone specifiche.
  • Crea un cluster in una regione diversa e riprova il deployment.
  • Prova a utilizzare una classe di computing diversa. Le classi di computing supportate da tipi di macchine Compute Engine più piccoli hanno maggiori probabilità di avere risorse disponibili. Ad esempio, il tipo di macchina predefinito per Autopilot ha la disponibilità più elevata. Per un elenco delle classi di computing e dei tipi di macchina corrispondenti, consulta Quando utilizzare classi di computing specifiche.
  • Se esegui workload GPU, la GPU richiesta potrebbe non essere disponibile nella località del nodo. Prova a eseguire il deployment del workload in una località diversa o richiedi un tipo di GPU diverso.

Per evitare problemi di scale up causati dalla disponibilità delle risorse in futuro, prendi in considerazione i seguenti approcci:

Lo scale up dei nodi non è riuscito: risorse di zona dei pod superate

Il seguente problema si verifica quando Autopilot non esegue il provisioning di nuovi nodi per un pod in una zona specifica perché un nuovo nodo violerebbe i limiti delle risorse.

Il messaggio di errore nei log è simile al seguente:

    "napFailureReasons": [
            {
              "messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
              ...

Questo errore si riferisce a un evento noScaleUp, in cui il provisioning automatico dei nodi non ha eseguito il provisioning di alcun gruppo di nodi per il pod nella zona.

Se si verifica questo errore, verifica quanto segue:

Workload pianificato su serie di macchine meno recenti o bloccato nello stato Pending a causa di incompatibilità dello spazio di archiviazione

Questo problema si verifica quando un workload stateful utilizza un tipo di volume Persistent Disk precedente, ad esempio volumi Standard Persistent Disk (pd-standard) o SSD Persistent Disk (pd-ssd). Questi tipi di volumi non sono compatibili con le serie di macchine più recenti, come C3 o E4.

Questo problema si manifesta in uno dei due modi seguenti:

  • Sintomo 1: un workload che prevedi di eseguire su una serie di macchine per uso generico più recente (come C3) viene invece pianificato automaticamente su un nodo E2.
  • Sintomo 2: un pod che richiede esplicitamente una serie di macchine più recente (ad esempio, utilizzando i campi nodeSelector o una ComputeClass personalizzata) rimane bloccato nello stato Pending.

Causa principale

GKE Autopilot applica la compatibilità tra i tipi di archiviazione richiesti e la serie di macchine dei nodi. Le serie di macchine più recenti, come C3 ed E4, richiedono lo spazio di archiviazione Google Cloud Hyperdisk (ad esempio il tipo di disco hyperdisk-balanced). Queste serie di macchine non supportano i tipi di volumi Persistent Disk precedenti, come i volumi Standard Persistent Disk (pd-standard) o SSD Persistent Disk (pd-ssd).

  • Se non specifichi una serie di macchine, GKE Autopilot pianifica automaticamente il workload su un nodo E2, perché i nodi E2 supportano questi tipi di volumi Persistent Disk. Il workload esegue silenziosamente il fallback dall'hardware più recente predefinito.
  • Se richiedi esplicitamente una serie di macchine più recente (come C3 o E4), ma colleghi un tipo di volume Persistent Disk precedente, ad esempio volumi Standard Persistent Disk (pd-standard) o SSD Persistent Disk (pd-ssd), GKE Autopilot non può soddisfare entrambi i requisiti. Il pod rimane bloccato nello stato Pending.

Verifica

Per verificare se il tuo workload è interessato da questo vincolo di compatibilità, segui questi passaggi:

  1. Controlla la configurazione del volume del pod per verificare se utilizza un tipo di volume Persistent Disk precedente, ad esempio volumi Standard Persistent Disk (pd-standard) o SSD Persistent Disk (pd-ssd).
  2. Se il pod è bloccato nello stato Pending, controlla i log di visibilità del gestore della scalabilità automatica dei cluster. Cerca i log di valutazione del provisioning automatico dei nodi (NAP) simili ai seguenti:

    NAP: injected node groups for requirements...
    
  3. Esamina il messaggio di log per l'elenco families="...". Controlla se nell'elenco mancano famiglie di macchine più recenti (ad esempio identificatori e4 o c3). Gli identificatori mancanti indicano che GKE ha filtrato queste famiglie durante la pianificazione a causa del requisito di archiviazione. L'identificatore e4 viene utilizzato nei log interni per la serie di macchine E4.

Risoluzione

Per risolvere il problema, esegui una delle seguenti azioni:

  • Utilizza lo spazio di archiviazione Hyperdisk: aggiorna la definizione di StorageClass o del volume per utilizzare lo spazio di archiviazione Google Cloud Hyperdisk (ad esempio il tipo di disco hyperdisk-balanced), compatibile con le serie di macchine più recenti.
  • Consenti la pianificazione su serie precedenti: se devi utilizzare tipi di volumi Persistent Disk precedenti (come i volumi Standard Persistent Disk (pd-standard) o SSD Persistent Disk (pd-ssd)), rimuovi eventuali richieste esplicite per serie di macchine più recenti (come i campi nodeSelector o le ComputeClass personalizzate). La rimozione di queste richieste consente a GKE Autopilot di pianificare il pod su nodi compatibili come E2.

Problemi relativi ai workload

Workload bloccati con errore di archiviazione temporanea

GKE non creerà pod se le richieste di archiviazione temporanea dei pod superano il limite massimo di Autopilot di 10 GiB in GKE versione 1.28.6-gke.1317000 e successive.

Per diagnosticare questo problema, descrivi il controller del workload, ad esempio il deployment o il job:

kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME

Sostituisci quanto segue:

  • CONTROLLER_TYPE: il tipo di controller del workload, ad esempio replicaset o daemonset. Per un elenco dei tipi di controller, consulta Gestione dei workload.
  • CONTROLLER_NAME: il nome del workload bloccato.

Se il pod non viene creato perché la richiesta di archiviazione temporanea supera il valore massimo, l'output è simile al seguente:

# lines omitted for clarity

Events:

{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}

Per risolvere il problema, aggiorna le richieste di archiviazione temporanea in modo che lo spazio di archiviazione temporaneo totale richiesto dai container del workload e dai container inseriti dai webhook sia inferiore o uguale al massimo consentito. Per saperne di più sul valore massimo, consulta Richieste di risorse in Autopilot per la configurazione del workload.

Pod bloccati nello stato In attesa

Un pod potrebbe bloccarsi nello stato Pending se selezioni un nodo specifico da utilizzare per il pod, ma la somma delle richieste di risorse nel pod e nei DaemonSet che devono essere eseguiti sul nodo supera la capacità massima allocabile del nodo. Ciò potrebbe far sì che il pod riceva lo stato Pending e rimanga non pianificato.

Per evitare questo problema, valuta le dimensioni dei workload di cui hai eseguito il deployment per assicurarti che rientrino nelle richieste di risorse massime supportate per Autopilot.

Puoi anche provare a pianificare i DaemonSet prima di pianificare i pod dei workload normali.

Prestazioni del workload costantemente inaffidabili su un nodo specifico

In GKE 1.24 e versioni successive, se i workload su un nodo specifico subiscono costantemente interruzioni, arresti anomali o comportamenti inaffidabili simili, puoi segnalare a GKE il nodo problematico isolandolo con il seguente comando:

kubectl drain NODE_NAME --ignore-daemonsets

Sostituisci NODE_NAME con il nome del nodo problematico. Puoi trovare il nome del nodo eseguendo kubectl get nodes.

GKE esegue le seguenti operazioni:

  • Rimuove i workload esistenti dal nodo e interrompe la pianificazione dei workload su quel nodo.
  • Ricrea automaticamente su altri nodi i workload espulsi gestiti da un controller, ad esempio un deployment o un StatefulSet.
  • Termina tutti i workload che rimangono sul nodo e ripara o ricrea il nodo nel tempo.
  • Se utilizzi Autopilot, GKE arresta e sostituisce immediatamente il nodo e ignora qualsiasi PodDisruptionBudget configurato.

La pianificazione dei pod su cluster vuoti richiede più tempo del previsto

Questo evento si verifica quando esegui il deployment di un workload in un cluster Autopilot che non ha altri workload. I cluster Autopilot iniziano con zero nodi utilizzabili e scalano fino a zero nodi se il cluster è vuoto per evitare di avere risorse di computing inutilizzate nel cluster. Il deployment di un workload in un cluster con zero nodi attiva un evento di scale up.

In questo caso, Autopilot funziona come previsto e non è necessaria alcuna azione. Il deployment del workload verrà eseguito come previsto dopo l'avvio dei nuovi nodi.

Controlla se i pod sono in attesa di nuovi nodi:

  1. Descrivi il pod in attesa:

    kubectl describe pod POD_NAME
    

    Sostituisci POD_NAME con il nome del pod in attesa.

  2. Controlla la sezione Events dell'output. Se il pod è in attesa di nuovi nodi, l'output è simile al seguente:

    Events:
      Type     Reason            Age   From                                   Message
      ----     ------            ----  ----                                   -------
      Warning  FailedScheduling  11s   gke.io/optimize-utilization-scheduler  no nodes available to schedule pods
      Normal   TriggeredScaleUp  4s    cluster-autoscaler                     pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
    

    L'evento TriggeredScaleUp mostra che il cluster sta eseguendo lo scale up da zero nodi al numero di nodi necessari per eseguire il deployment del workload.

Impossibile pianificare i pod di sistema su cluster vuoti

Questo evento si verifica quando nessuno dei tuoi workload è in esecuzione in un cluster, il che comporta di fare lo scale down del cluster a zero nodi. I cluster Autopilot iniziano con zero nodi utilizzabili e fare lo scale down fino a zero nodi se non esegui workload nel cluster. Questo comportamento riduce al minimo lo spreco di risorse di calcolo nel cluster.

Quando un cluster fa lo scale down a zero nodi, i workload di sistema GKE non vengono pianificati e rimangono nello stato Pending. Si tratta di un comportamento previsto e non è necessaria alcuna azione. La volta successiva che esegui il deployment di un workload nel cluster, GKE eseguirà lo scale up del cluster e i pod di sistema in attesa verranno eseguiti su questi nodi.

Per verificare se i pod di sistema sono in attesa a causa di un cluster vuoto, segui questi passaggi:

  1. Controlla se il cluster ha nodi:

    kubectl get nodes
    

    L'output è il seguente, che indica che il cluster ha zero nodi:

    No resources found
    
  2. Controlla lo stato dei pod di sistema:

    kubectl get pods --namespace=kube-system
    

    L'output è simile al seguente:

    NAME                                                       READY   STATUS    RESTARTS   AGE
    antrea-controller-horizontal-autoscaler-6d97f7cf7c-ngfd2   0/1     Pending   0          9d
    egress-nat-controller-84bc985778-6jcwl                     0/1     Pending   0          9d
    event-exporter-gke-5c5b457d58-7njv7                        0/2     Pending   0          3d5h
    event-exporter-gke-6cd5c599c6-bn665                        0/2     Pending   0          9d
    konnectivity-agent-694b68fb7f-gws8j                        0/2     Pending   0          3d5h
    konnectivity-agent-7d659bf64d-lp4kt                        0/2     Pending   0          9d
    konnectivity-agent-7d659bf64d-rkrw2                        0/2     Pending   0          9d
    konnectivity-agent-autoscaler-5b6ff64fcd-wn7fw             0/1     Pending   0          9d
    konnectivity-agent-autoscaler-cc5bd5684-tgtwp              0/1     Pending   0          3d5h
    kube-dns-65ccc769cc-5q5q7                                  0/5     Pending   0          3d5h
    kube-dns-7f7cdb9b75-qkq4l                                  0/5     Pending   0          9d
    kube-dns-7f7cdb9b75-skrx4                                  0/5     Pending   0          9d
    kube-dns-autoscaler-6ffdbff798-vhvkg                       0/1     Pending   0          9d
    kube-dns-autoscaler-8b7698c76-mgcx8                        0/1     Pending   0          3d5h
    l7-default-backend-87b58b54c-x5q7f                         0/1     Pending   0          9d
    metrics-server-v1.31.0-769c5b4896-t5jjr                    0/1     Pending   0          9d
    
  3. Controlla il motivo per cui i pod di sistema hanno lo stato Pending:

    kubectl describe pod --namespace=kube-system SYSTEM_POD_NAME
    

    Sostituisci SYSTEM_POD_NAME con il nome di un pod di sistema dall'output del comando precedente.

    L'output è simile al seguente:

    ...
    Events:
    Type     Reason            Age                       From               Message
    ----     ------            ----                      ----               -------
    Warning  FailedScheduling  4m35s (x27935 over 3d5h)  default-scheduler  no nodes available to schedule pods
    ...
    

    Nell'output, il valore no nodes available to schedule pods nel campo Message per l'evento FailedScheduling indica che il pod di sistema non è stato pianificato perché il cluster è vuoto.

L'accesso ai nodi sottostanti è vietato in un cluster GKE Autopilot. Pertanto, è necessario eseguire l'utilità tcpdump dall'interno di un pod e poi copiarla utilizzando il comando kubectl cp. Se in genere esegui l'utilità tcpdump dall'interno di un pod in un cluster GKE Autopilot, potresti visualizzare il seguente errore:

    tcpdump: eth0: You don't have permission to perform this capture on that device
    (socket: Operation not permitted)

Questo accade perché GKE Autopilot, per impostazione predefinita, applica un contesto di sicurezza a tutti i pod che elimina la funzionalità NET_RAW per mitigare le potenziali vulnerabilità. Ad esempio:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: tcpdump
  name: tcpdump
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        # This section drops NET_RAW to mitigate security vulnerabilities
        drop:
        - NET_RAW

Come soluzione, se il tuo workload richiede la funzionalità NET_RAW, puoi riattivarla:

  1. Aggiungi la funzionalità NET_RAW alla sezione securityContext della specifica YAML del pod:

    securityContext:
      capabilities:
        add:
        - NET_RAW
    
  2. Esegui tcpdump dall'interno di un pod:

    tcpdump port 53 -w packetcap.pcap
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    
  3. Utilizza il comando kubectl cp per copiarlo sulla tua macchina locale per un'ulteriore analisi:

    kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
    
  4. Utilizza kubectl exec per eseguire il comando tcpdump per acquisire i pacchetti di rete e reindirizzare l'output:

    kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
    

Impossibile eseguire i pod su un nodo a causa di un errore di RunPodSandbox di NRI

In rari casi, un nodo Autopilot nelle classi di computing predefinita, Balanced, Scale-Out, autopilot e autopilot-spot può entrare in uno stato in cui i pod di sistema, come anetd, e potenzialmente i pod utente assegnati al nodo, non possono passare allo stato In esecuzione. Quando anetd non può passare a uno stato di esecuzione, il networking dei pod è parzialmente o completamente interrotto sul nodo. Questo stato di errore viene attivato solo durante alcuni upgrade del control plane del cluster.

Se noti il problema, puoi mitigarlo su un determinato nodo seguendo la procedura per mitigare le prestazioni inaffidabili del workload su un nodo specifico.

Per evitare che il problema si ripresenti, esegui manualmente l'upgrade del cluster a una delle seguenti versioni patch di GKE:

  • 1.35: tutte le versioni patch
  • 1.34: 1.34.1-gke.3899000 o versioni successive
  • 00:00:26,960 --> 00:00:33,200

Se sospetti che un nodo si trovi in questo stato di errore, puoi confermarlo seguendo questi passaggi:

  1. Trova il pod efficiency-daemon in esecuzione sul nodo sospetto:

    DAEMON_POD_NAME=$(kubectl get pods \
      --namespace kube-system \
      --selector k8s-app=efficiency-daemon \
      --field-selector spec.nodeName=NODE_NAME \
      --output custom-columns=":metadata.name" \
      --no-headers)
    echo $DAEMON_POD_NAME
    

    Se sul nodo non è presente un pod efficiency-daemon, il nodo non è interessato da questo problema specifico.

  2. Controlla se sono presenti errori specifici nel pod efficiency-daemon:

    kubectl logs -n kube-system $DAEMON_POD_NAME | grep "connect: operation not permitted" | wc -l
    

    Se l'output è maggiore di 10, è molto probabile che il nodo sia interessato da questo problema.

Se visualizzi continuamente il seguente messaggio di errore negli eventi pod per un pod assegnato al nodo, significa che il nodo è interessato da questo problema: Failed to create pod sandbox: rpc error: code = Unknown desc = NRI RunPodSandbox failed: rpc error: code = Unknown desc = internal error: reconciliation failed.

Passaggi successivi