Risolvere i problemi di contesa delle risorse

Puoi risolvere i problemi relativi ai container lenti, con prestazioni insufficienti o terminati in Google Distributed Cloud diagnosticando la contesa delle risorse. Le cause comuni includono la limitazione della CPU, i pod OOMKilled, la latenza del server etcd e del server API e i colli di bottiglia della CPU o dello spazio di archiviazione vSphere. Identificare la causa ti aiuta ad adattare le risorse per i tuoi workload, nodi e VM per mantenere stabili i cluster.

Panoramica

A volte Google Distributed Cloud potrebbe riscontrare una contesa delle risorse, con conseguente rallentamento, prestazioni inferiori o interruzione dei container. Ciò può accadere a causa di un consumo elevato di CPU o memoria da parte dei container.

Come funziona la gestione della CPU e della memoria

  • CPU:

    • Un pod viene pianificato su un nodo in base alle richieste di CPU specificate dai container nel pod.
    • Un container in un pod non può utilizzare più CPU del limite specificato dal container
    • L'utilizzo della CPU del container è limitato al limite della CPU.
    • Se l'utilizzo della CPU è limitato a livello di nodo, ai container vengono assegnati automaticamente i cicli della CPU proporzionali alle richieste.

    Scopri di più su come vengono pianificati i pod con richieste di risorse.

  • Memoria:

    • Un pod viene pianificato su un nodo in base alle richieste di memoria specificate dai container nel pod.
    • Un container non può utilizzare più memoria del limite specificato dal container.
    • Se non viene specificato un limite di memoria, un container potrebbe consumare tutta la memoria disponibile su un nodo. In questo caso, il sistema potrebbe attivare l'OOM-Killer (Out Of Memory Killer) ed espellere i pod con priorità bassa.

Per ulteriori informazioni, consulta le seguenti risorse:

Problemi

Il container diventa lento

I problemi di conflitto della CPU possono rallentare i container. Di seguito sono riportati alcuni dei possibili motivi:

Utilizzo elevato della CPU nel container:

Un container può diventare lento se non riceve cicli della CPU proporzionali alle richieste della CPU o se le richieste della CPU sono state impostate su un valore inferiore a quello necessario per il container. Controlla quindi il rapporto tra il limite della CPU e l'utilizzo della CPU per il container.

Nella console Google Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

  avg_over_time({
    "__name__"="kubernetes.io/anthos/container/cpu/limit_utilization",
    "monitored_resource"="k8s_container",
    "cluster_name"="CLUSTER_NAME",
    "container_name"="CONTAINER_NAME",
    "pod_name"="POD_NAME",
    "namespace_name"="NAMESPACE_NAME"
  }[${__interval}])

Scegli una delle seguenti opzioni:

Utilizzo elevato della CPU sul nodo

Se il rapporto tra il limite di CPU e l'utilizzo non è elevato per nessun singolo container del pod, è possibile che il nodo non disponga di cicli di CPU sufficienti da allocare all'insieme di container in esecuzione sul nodo. Segui questi passaggi per verificare il rapporto tra l'utilizzo effettivo della CPU e le CPU allocabili sul nodo:

  1. Recupera il nodo per il pod che funziona lentamente:

    kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wide
    
  2. Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

    avg_over_time({
      "__name__"="kubernetes.io/anthos/node/cpu/allocatable_utilization",
      "monitored_resource"="k8s_node",
      "cluster_name"="CLUSTER_NAME",
      "node_name"="NODE_NAME"
    }[${__interval}])
    

    Se questo rapporto è elevato (>=0,8), significa che il nodo non dispone di cicli della CPU sufficienti ed è in oversubscription. Segui questi passaggi per controllare l'utilizzo della CPU per tutti gli altri pod su quel nodo e verifica se esiste un altro container che utilizza più CPU.

    1. Recupera tutti i pod sul nodo:
    kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME
    
    1. Controlla l'utilizzo della CPU su ogni container:
    avg_over_time({
      "__name__"="kubernetes.io/anthos/container/cpu/limit_utilization",
      "monitored_resource"="k8s_container",
      "cluster_name"="CLUSTER_NAME",
      "container_name"="CONTAINER_NAME",
      "pod_name"="POD_NAME",
      "namespace_name"="NAMESPACE_NAME"
    }[${__interval}])
    

    Se sul nodo è presente un altro container che utilizza una CPU elevata, aumenta le richieste e i limiti di CPU sul container che funziona lentamente. In questo modo, il pod verrà ricreato su un altro nodo per ottenere i cicli della CPU richiesti.

Se è un pod di sistema a funzionare lentamente, contatta l'Assistenza Google.

Oversubscription della CPU a livello di vSphere

Se il consumo della CPU non è elevato né sul nodo né sul pod e il container è ancora lento, è possibile che la VM sia in oversubscription a livello di vSphere. Di conseguenza, il nodo non è in grado di ottenere i cicli della CPU previsti dalla virtualizzazione sottostante.

Segui questi passaggi per verificare se la VM è in overcommit. Se viene rilevato un oversubscription, prova quanto segue:

  • Sposta alcune VM su altri host.
  • Valuta e riduci il numero di vCPU per VM per l'host.
  • Assegna più risorse alle VM del cluster.
  • Aumenta le richieste e i limiti di CPU sul container. In questo modo, il pod verrà ricreato su un altro nodo per ottenere i cicli della CPU richiesti.

Il pod viene terminato per memoria esaurita (OOMKilled)

I pod possono essere terminati con l'errore OOMKilled a causa di perdite di memoria o di una configurazione errata delle richieste e dei limiti di memoria sui container. Di seguito sono riportati alcuni dei possibili motivi:

Utilizzo elevato della memoria nel container

Un pod può essere terminato per memoria esaurita se un container nel pod consuma più della memoria totale allocata. Controlla quindi il rapporto tra le richieste di memoria e i limiti di memoria del container.

Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

avg_over_time({
  "__name__"="kubernetes.io/anthos/container/memory/limit_utilization",
  "monitored_resource"="k8s_container",
  "memory_type"="non-evictable",
  "cluster_name"="CLUSTER_NAME",
  "container_name"="CONTAINER_NAME",
  "pod_name"="POD_NAME",
  "namespace_name"="NAMESPACE_NAME"
}[${__interval}])

Scegli una delle seguenti opzioni:

Utilizzo elevato della memoria utilizzata sul nodo

Un pod può essere terminato per memoria esaurita se la memoria utilizzata da tutti i pod in esecuzione sul nodo supera la memoria disponibile. Quindi, controlla se la condizione MemoryPressure sul nodo è True.

  1. Esegui il seguente comando e controlla la sezione Conditions:

    kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAME
    
  2. Se la condizione MemoryPressure è True, controlla l'utilizzo della memoria sul nodo:

    avg_over_time({
      "__name__"="kubernetes.io/anthos/node/memory/allocatable_utilization",
      "monitored_resource"="k8s_node",
      "memory_type"="non-evictable",
      "cluster_name"="CLUSTER_NAME",
      "node_name"="NODE_NAME",
    }[${__interval}])
    

    Se questo rapporto è elevato (>= 0,8), significa che il nodo non dispone di memoria sufficiente da allocare al pod, probabilmente a causa di alcuni processi o di altri pod che consumano molta memoria.

  3. Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui la seguente query per controllare la memoria utilizzata per i container sul nodo:

    avg_over_time({
      "__name__"="kubernetes.io/anthos/container_memory_usage_bytes",
      "monitored_resource"="k8s_node",
      "cluster_name"="CLUSTER_NAME",
      "node_name"="NODE_NAME",
    }[${__interval}])
    

    Se un container utilizza molta memoria, esamina il funzionamento del container o, se necessario, aumenta la richiesta di memoria per il container.

Se è un pod di sistema che consuma molta memoria, contatta l'Assistenza Google.

Inoltre, puoi attivare la funzionalità di scalabilità automatica in Google Distributed Cloud per fare lo scale up e lo scale down automatici dei node pool in base alle esigenze dei tuoi workload.

Scopri come attivare il gestore della scalabilità automatica.

Problemi di etcd

A volte, Cluster Anthos su VMware potrebbe riscontrare errori dei container a causa di problemi del server etcd e potresti osservare quanto segue:

  • Log del server API ripetuti nel formato:

    etcdserver: request timed out e etcdserver: leader changed

  • Log etcd ripetuti nel formato:

    W | wal: sync duration of 2.466870869s, expected less than 1s e W | etcdserver: read-only range request * took too long

Di seguito sono riportati alcuni dei possibili motivi:

Limitazione CPU

Il server etcd potrebbe essere lento a causa della limitazione della CPU sul pod del server etcd e/o sul nodo su cui è in esecuzione il server etcd. Consulta i passaggi nella sezione Il container diventa lento per verificare la presenza di eventuali problemi di conflitto della CPU.

Se rilevi una contesa della CPU sul pod del server ectd o sul nodo, aggiungi CPU al nodo del control plane del cluster utente. Utilizza gkectl update per modificare il campo cpus nel file di configurazione del cluster utente.

Pod etcd OOMkilled

Il pod etcd potrebbe essere terminato per memoria esaurita (OOMkilled) a causa di problemi di conflitto delle risorse. Consulta i passaggi nella sezione Il pod viene terminato per memoria esaurita (OOMkilled) per verificare se sono presenti problemi di conflitto di memoria con il pod del server etcd e/o con il nodo su cui è in esecuzione il server etcd.

Se rilevi OOMkill per il pod etcd, aumenta la memoria disponibile per il nodo del control plane del cluster utente. Utilizza gkectl update per modificare il campo memoryMB nel file di configurazione del cluster utente.

Lentezza del disco

Se non ci sono problemi con il consumo di CPU o memoria nel pod del server etcd o nel nodo, etcd potrebbe essere lento se il datastore sottostante è lento o limitato.

Verifica che non siano presenti i seguenti problemi:

  • Per verificare se il server etcd impiega troppo tempo per leggere/scrivere sul disco sottostante:

    1. Recupera i log etcd:

      kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_POD
      
    2. Cerca le voci del seguente pattern per rilevare se etcd impiega troppo tempo per leggere dal disco:

      W | etcdserver: read-only range request "key:\"/registry/configmaps/default/clusterapi-vsphere-controller-manager-leader-election\" " with result "range_response_count:1 size:685" took too long (6.893127339s) to execute

    3. Cerca le voci del seguente pattern per rilevare se etcd impiega troppo tempo per scrivere sul disco:

      W | wal: sync duration of 2.466870869s, expected less than 1s

    Se uno o entrambi i pattern di log riportati sopra vengono visualizzati di frequente nei log etcd, significa che il disco è lento. Poi controlla le prestazioni del datastore e dei dischi.

  • Per controllare le metriche etcd:

    1. Recupera le latenze di sincronizzazione wal di etcd:

      Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

      histogram_quantile(0.99,
        sum by ("le") (
          increase({
            "__name__"="kubernetes.io/anthos/etcd_disk_wal_fsync_duration_seconds_bucket",
            "monitored_resource"="k8s_container",
            "cluster_name"="CLUSTER_NAME",
            "pod_name"="POD_NAME",
            "namespace_name"="NAMESPACE_NAME"
          }[${__interval}])
        )
      )
      
    2. Recupera le latenze di scrittura di etcd:

      Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

      histogram_quantile(0.99,
        sum by ("le") (
          increase({
            "__name__"="kubernetes.io/anthos/etcd_disk_backend_commit_duration_seconds",
            "monitored_resource"="k8s_container",
            "cluster_name"="CLUSTER_NAME",
            "pod_name"="POD_NAME",
            "namespace_name"="NAMESPACE_NAME"
          }[${__interval}])
        )
      )
      

    Se p99 per etcd_disk_wal_fsync_duration_seconds è costantemente superiore a 10 ms e/o p99 per etcd_disk_backend_commit_duration_seconds è costantemente superiore a 25 ms, significa che il disco è lento. Poi controlla le prestazioni del datastore e dei dischi.

Latenze di lettura/scrittura sul disco della VM

Segui questi passaggi per verificare le latenze di lettura/scrittura sul disco virtuale della VM

  1. Identifica il nodo del pod etcd lento:

    kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owide
    
  2. Accedi a vSphere e seleziona la VM identificata nel passaggio precedente: In vSphere, vai a Monitora > Prestazioni > Avanzate e seleziona Disco virtuale dalla sezione Visualizza per identificare le latenze di lettura e scrittura per i dischi virtuali.

    Se la latenza di lettura/scrittura del disco virtuale è elevata:

    • Esamina le altre VM in esecuzione nel datastore per verificare l'utilizzo elevato di operazioni di I/O al secondo (IOPS). Se una VM mostra picchi nelle IOPS, valuta il funzionamento della VM.
    • Consulta il tuo team di laboratorio/infrastruttura per assicurarti che la larghezza di banda di lettura e scrittura non sia limitata in nessun punto.
    • Consulta il tuo team di laboratorio/infrastruttura per identificare eventuali problemi di prestazioni del disco e prestazioni dello spazio di archiviazione.

Per saperne di più, consulta le best practice per la scalabilità delle risorse.

Problemi del server API

Se i container in Google Distributed Cloud riscontrano latenza durante la comunicazione con il server API o se i comandi Kubectl non vanno a buon fine o richiedono troppo tempo per rispondere, potrebbero esserci problemi con il server API.

Di seguito sono riportati alcuni dei possibili motivi:

Volume elevato di richieste API

Il server API potrebbe rispondere lentamente se la frequenza e il volume delle richieste sono troppo elevati. Il tempo di risposta lento potrebbe persistere anche dopo che il server API inizia a limitare le richieste. Controlla quindi la frequenza delle richieste API sul server API.

Nella consoleGoogle Cloud > Monitoring > Esplora metriche, nell'editor PromQL, esegui questa query:

sum by (verb) (
  rate({
    "__name__"="kubernetes.io/anthos/apiserver_request_total",
    "monitored_resource"="k8s_container",
    "cluster_name"="CLUSTER_NAME",
    "pod_name"="APISERVER_POD_NAME",
    "namespace_name"="NAMESPACE_NAME"
   }[${__interval}])
)

Se si verifica un aumento imprevisto delle richieste API, utilizza Audit Logging di Cloud per identificare il pod che potrebbe eseguire query sul server API troppo spesso.

  • Se si tratta di un pod di sistema, contatta l'Assistenza Google.
  • Se si tratta di un pod utente, indaga ulteriormente per determinare se le richieste API sono previste.

Limitazione CPU

Un tasso di richieste elevato sul server API può causare la limitazione della CPU. Il server API potrebbe quindi rallentare a causa della contesa della CPU sul pod del server API e/o sul nodo.

Consulta la sezione Il container diventa lento per verificare se sono presenti problemi di conflitto della CPU con il pod e/o il nodo.

Pod del server API OOMkilled

Il pod del server API potrebbe essere terminato per memoria esaurita (OOMKilled) a causa di problemi di conflitto di risorse. Consulta i passaggi nella sezione Il pod viene terminato per OOM (Out of Memory) per verificare se sono presenti problemi di conflitto di memoria con il pod e/o il nodo.

Risposte etcd lente

Il server API si basa sulla comunicazione con il cluster etcd per gestire le richieste di lettura/scrittura ai client. Se etcd è lento o non risponde, anche il server API diventa lento.

Recupera i log del server API per verificare se il server API è lento a causa dei problemi di etcd:

kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n APISERVER_NAMESPACE APISERVER_POD_NAME

Se osservi log ricorrenti come etcdserver: request timedout o etcdserver: leader changed, segui i passaggi descritti in Problemi di etcd per risolvere eventuali problemi relativi al disco.

Se il cluster non esporta le metriche

Le tecniche mostrate in precedenza in questo documento si basano sull'esportazione delle metriche dal cluster a un progetto Google Cloud .

Se il tuo cluster non esporta metriche, puoi utilizzare la riga di comando per esaminare la contesa delle risorse. Ecco alcuni comandi che puoi eseguire sulla tua workstation di amministrazione per visualizzare le metriche.

Visualizza le metriche per un nodo:

kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
    /apis/metrics.k8s.io/v1beta1/nodes/NODE_NAME | jq

Sostituisci quanto segue:

  • CLUSTER_KUBECONFIG: il percorso del file kubeconfig del cluster
  • NODE_NAME: il nome del nodo

Visualizza le metriche di un pod:

kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
    /apis/metrics.k8s.io/v1beta1/namespaces/NAMESPACE/pods/POD_NAME | jq

Sostituisci quanto segue:

  • NAMESPACE: lo spazio dei nomi del pod
  • POD_NAME: il nome del pod

Visualizza le metriche per tutti i nodi:

kubectl --kubeconfig CLUSTER_KUBECONFIG top node

Visualizza le metriche per tutti i pod in uno spazio dei nomi:

kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --namespace NAMESPACE

Visualizza le metriche per i container in tutti i pod di uno spazio dei nomi:

kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --containers --namespace NAMESPACE

Per saperne di più, consulta kubectl top pod e kubectl top node.

Puoi anche eseguire il comando top dall'interno di un container in esecuzione su un nodo.

Ecco due modi per eseguire un comando all'interno di un container:

Passaggi successivi

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

Puoi anche consultare Assistenza per ulteriori informazioni sulle risorse di assistenza, tra cui: