Risoluzione dei problemi di logging in GKE


Questa pagina mostra come esaminare e risolvere i problemi relativi al logging di GKE.

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

Log del cluster mancanti in Cloud Logging

Verifica che il logging sia abilitato nel progetto

  1. Elenca i servizi attivati:

    gcloud services list --enabled --filter="NAME=logging.googleapis.com"
    

    Il seguente output indica che il logging è abilitato per il progetto:

    NAME                    TITLE
    logging.googleapis.com  Cloud Logging API
    

    (Facoltativo) Controlla i log nel visualizzatore log per determinare chi ha disattivato l'API e quando:

    protoPayload.methodName="google.api.serviceusage.v1.ServiceUsage.DisableService"
    protoPayload.response.services="logging.googleapis.com"
    
  2. Se il logging è disattivato, attivalo:

    gcloud services enable logging.googleapis.com
    

Verifica che il logging sia abilitato sul cluster

  1. Elenca i cluster:

    gcloud container clusters list \
        --project=PROJECT_ID \
        '--format=value(name,loggingConfig.componentConfig.enableComponents)' \
        --sort-by=name | column -t
    

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo Google Cloud ID progetto.

    L'output è simile al seguente:

    cluster-1              SYSTEM_COMPONENTS
    cluster-2              SYSTEM_COMPONENTS;WORKLOADS
    cluster-3
    

    Se il valore per il cluster è vuoto, la registrazione è disattivata. Ad esempio, cluster-3 in questo output ha il logging disabilitato.

  2. Abilita il logging del cluster se impostato su NONE:

    gcloud container clusters update CLUSTER_NAME  \
        --logging=SYSTEM,WORKLOAD \
        --location=COMPUTE_LOCATION
    

    Sostituisci quanto segue:

Verifica che i nodi nei pool di nodi abbiano l'ambito di accesso a Cloud Logging

Per consentire ai nodi di scrivere log in Cloud Logging è necessario uno dei seguenti ambiti:

  • https://www.googleapis.com/auth/logging.write
  • https://www.googleapis.com/auth/cloud-platform
  • https://www.googleapis.com/auth/logging.admin
  1. Controlla gli ambiti configurati su ogni pool di nodi del cluster:

    gcloud container node-pools list --cluster=CLUSTER_NAME \
        --format="table(name,config.oauthScopes)" \
        --location COMPUTE_LOCATION
    

    Sostituisci quanto segue:

    Esegui la migrazione dei workload dal vecchio node pool al node pool appena creato e monitora lo stato di avanzamento.

  2. Crea nuovi pool di nodi con l'ambito di registrazione corretto:

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=COMPUTE_LOCATION \
        --scopes="gke-default"
    

    Sostituisci quanto segue:

Identificare i cluster con account di servizio dei nodi in cui mancano autorizzazioni critiche

Per identificare i cluster con account di servizio dei nodi mancanti di autorizzazioni critiche, utilizza i consigli GKE del sottotipo di recommender NODE_SA_MISSING_PERMISSIONS:

  • Utilizza la console Google Cloud. Vai alla pagina Cluster Kubernetes e controlla se è presente il consiglio Concede autorizzazioni critiche nella colonna Notifiche per cluster specifici.
  • Utilizza l'interfaccia a riga di comando gcloud o l'API Recommender, specificando il NODE_SA_MISSING_PERMISSIONS sottotipo di motore per suggerimenti.

    Per eseguire query sui consigli, esegui il seguente comando:

    gcloud recommender recommendations list \
        --recommender=google.container.DiagnosisRecommender \
        --location LOCATION \
        --project PROJECT_ID \
        --format yaml \
        --filter="recommenderSubtype:NODE_SA_MISSING_PERMISSIONS"
    

Tieni presente che la visualizzazione del consiglio può richiedere fino a 24 ore. Per istruzioni dettagliate, consulta la sezione su come visualizzare approfondimenti e consigli.

Per implementare questo consiglio, concedi il ruolo roles/container.defaultNodeServiceAccount all'account di servizio del nodo.

Puoi seguire questo script per trovare tutti gli account di servizio dei nodi mancanti di autorizzazioni critiche per i cluster in modalità standard in un progetto.

#!/bin/bash

# Set your project ID
project_id=PROJECT_ID
project_number=$(gcloud projects describe "$project_id" --format="value(projectNumber)")
declare -a all_service_accounts
declare -a sa_missing_permissions

# Function to check if a service account has a specific permission
# $1: project_id
# $2: service_account
# $3: permission
service_account_has_permission() {
  local project_id="$1"
  local service_account="$2"
  local permission="$3"

  local roles=$(gcloud projects get-iam-policy "$project_id" \
          --flatten="bindings[].members" \
          --format="table[no-heading](bindings.role)" \
          --filter="bindings.members:\"$service_account\"")

  for role in $roles; do
    if role_has_permission "$role" "$permission"; then
      echo "Yes" # Has permission
      return
    fi
  done

  echo "No" # Does not have permission
}

# Function to check if a role has the specific permission
# $1: role
# $2: permission
role_has_permission() {
  local role="$1"
  local permission="$2"
  gcloud iam roles describe "$role" --format="json" | \
  jq -r ".includedPermissions" | \
  grep -q "$permission"
}


echo "--- 1. List all service accounts in all GKE node pools"
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" "service_account" "project_id" "cluster_name" "cluster_location" "nodepool_name"
while read cluster; do
  cluster_name=$(echo "$cluster" | awk '{print $1}')
  cluster_location=$(echo "$cluster" | awk '{print $2}')

  while read nodepool; do
    nodepool_name=$(echo "$nodepool" | awk '{print $1}')

    while read nodepool_details; do
      service_account=$(echo "$nodepool_details" | awk '{print $1}')

      if [[ "$service_account" == "default" ]]; then
        service_account="${project_number}-compute@developer.gserviceaccount.com"
      fi
      if [[ -n "$service_account" ]]; then
        printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" $service_account $project_id  $cluster_name $cluster_location $nodepool_name
        all_service_accounts+=( ${service_account} )
      else
        echo "cannot find service account" for node pool "$project_id\t$cluster_name\t$cluster_location\t$nodepool_details"
      fi
    done <<< "$(gcloud container node-pools describe "$nodepool_name" --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](config.serviceAccount)")"
  done <<< "$(gcloud container node-pools list --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](name)")"
done <<< "$(gcloud container clusters list --project "$project_id" --format="value(name,location)")"

echo "--- 2. Check if service accounts have permissions"
unique_service_accounts=($(echo "${all_service_accounts[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))

echo "Service accounts: ${unique_service_accounts[@]}"
printf "%-60s| %-40s| %-40s| %-20s\n" "service_account" "has_logging_permission" "has_monitoring_permission" "has_performance_hpa_metric_write_permission"
for sa in "${unique_service_accounts[@]}"; do
  logging_permission=$(service_account_has_permission "$project_id" "$sa" "logging.logEntries.create")
  monitoring_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.timeSeries.create")
  performance_hpa_metric_write_permission=$(service_account_has_permission "$project_id" "$sa" "autoscaling.sites.writeMetrics")
  printf "%-60s| %-40s| %-40s| %-20s\n" $sa $logging_permission $monitoring_permission $performance_hpa_metric_write_permission

  if [[ "$logging_permission" == "No" || "$monitoring_permission" == "No" || "$performance_hpa_metric_write_permission" == "No" ]]; then
    sa_missing_permissions+=( ${sa} )
  fi
done

echo "--- 3. List all service accounts that don't have the above permissions"
if [[ "${#sa_missing_permissions[@]}" -gt 0 ]]; then
  printf "Grant roles/container.defaultNodeServiceAccount to the following service accounts: %s\n" "${sa_missing_permissions[@]}"
else
  echo "All service accounts have the above permissions"
fi

Identificare gli account di servizio dei nodi a cui mancano autorizzazioni critiche in un cluster

GKE utilizza gli account di servizio IAM collegati ai tuoi nodi per eseguire attività di sistema come il logging e il monitoraggio. Come minimo, questi account di servizio dei nodi devono avere il ruolo Kubernetes Engine Default Node Service Account (roles/container.defaultNodeServiceAccount) nel tuo progetto. Per impostazione predefinita, GKE utilizza l'account di servizio predefinito di Compute Engine, creato automaticamente nel progetto, come account di servizio del nodo.

Se la tua organizzazione applica il vincolo del criterio dell'organizzazione iam.automaticIamGrantsForDefaultServiceAccounts, il service account Compute Engine predefinito nel progetto potrebbe non ottenere automaticamente le autorizzazioni richieste per GKE.

  • Per identificare il problema, controlla la presenza di errori 401 nel workload di logging di sistema nel tuo cluster:

    [[ $(kubectl logs -l k8s-app=fluentbit-gke -n kube-system -c fluentbit-gke | grep -cw "Received 401") -gt 0 ]] && echo "true" || echo "false"
    

    Se l'output è true, il carico di lavoro del sistema presenta errori 401, che indicano una mancanza di autorizzazioni. Se l'output è false, salta il resto di questi passaggi e prova una procedura di risoluzione dei problemi diversa.

  1. Trova il nome dell'account di servizio utilizzato dai tuoi nodi:

    console

    1. Vai alla pagina Cluster Kubernetes:

      Vai ai cluster Kubernetes

    2. Nell'elenco dei cluster, fai clic sul nome del cluster che vuoi controllare.
    3. A seconda della modalità di funzionamento del cluster, esegui una delle seguenti operazioni:
      • Per i cluster in modalità Autopilot, nella sezione Sicurezza, individua il campo Account di servizio.
      • Per i cluster in modalità standard:
        1. Fai clic sulla scheda Nodi.
        2. Nella tabella Pool di nodi, fai clic sul nome di un pool di nodi. Viene visualizzata la pagina Dettagli pool di nodi.
        3. Nella sezione Sicurezza, individua il campo Account di servizio.

    Se il valore nel campo Account di servizio è default, i nodi utilizzano l'account di servizio predefinito di Compute Engine. Se il valore in questo campo non è default, i tuoi nodi utilizzano un account di servizio personalizzato. Per concedere il ruolo richiesto a un account di servizio personalizzato, consulta Utilizzare gli account di servizio IAM con privilegi minimi.

    gcloud

    Per i cluster in modalità Autopilot, esegui il seguente comando:

    gcloud container clusters describe CLUSTER_NAME \
        --location=LOCATION \
        --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccount

    Per i cluster in modalità standard, esegui il seguente comando:

    gcloud container clusters describe CLUSTER_NAME \
        --location=LOCATION \
        --format="table(nodePools.name,nodePools.config.serviceAccount)"

    Se l'output è default, i nodi utilizzano il service account predefinito di Compute Engine. Se l'output è not default, i tuoi nodi utilizzano un account di servizio personalizzato. Per concedere il ruolo richiesto a un account di servizio personalizzato, consulta Utilizzare gli account di servizio IAM con privilegi minimi.

  2. Per concedere il ruolo roles/container.defaultNodeServiceAccount all'account di servizio predefinito di Compute Engine, completa i seguenti passaggi:

    console

    1. Vai alla pagina Welcome (Ti diamo il benvenuto):

      Vai a Benvenuto

    2. Nel campo Numero progetto, fai clic su Copia negli appunti.
    3. Vai alla pagina IAM:

      Vai a IAM

    4. Fai clic su Concedi accesso.
    5. Nel campo Nuove entità, specifica il seguente valore:
      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      Sostituisci PROJECT_NUMBER con il numero del progetto che hai copiato.
    6. Nel menu Seleziona un ruolo, seleziona il ruolo Kubernetes Engine Default Node Service Account.
    7. Fai clic su Salva.

    gcloud

    1. Trova il Google Cloud numero del progetto:
      gcloud projects describe PROJECT_ID \
          --format="value(projectNumber)"

      Sostituisci PROJECT_ID con l'ID progetto.

      L'output è simile al seguente:

      12345678901
      
    2. Concedi il ruolo roles/container.defaultNodeServiceAccount all'account di servizio predefinito Compute Engine:
      gcloud projects add-iam-policy-binding PROJECT_ID \
          --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
          --role="roles/container.defaultNodeServiceAccount"

      Sostituisci PROJECT_NUMBER con il numero del progetto del passaggio precedente.

Verifica che le quote dell'API di scrittura Cloud Logging non siano state raggiunte

Verifica di non aver raggiunto le quote di scrittura dell'API per Cloud Logging.

  1. Vai alla pagina Quote nella console Google Cloud.

    Vai a Quote

  2. Filtra la tabella per "API Cloud Logging".

  3. Verifica di non aver raggiunto nessuna delle quote.

Eseguire il debug dei problemi di logging GKE con gcpdiag

Se mancano o ricevi log incompleti dal tuo cluster GKE, utilizza lo strumento gcpdiag per la risoluzione dei problemi.

gcpdiag è uno strumento open source. Non è un prodotto Google Cloud supportato ufficialmente. Puoi utilizzare lo strumento gcpdiag per identificare e risolvere i problemi Google Cloud del progetto. Per maggiori informazioni, consulta il progetto gcpdiag su GitHub.

Quando i log del cluster GKE sono mancanti o incompleti, esamina le potenziali cause concentrandoti sulle seguenti impostazioni di configurazione di base che sono essenziali per le funzioni di logging adeguate:

  • Logging a livello di progetto:assicurati che nel progetto Google Cloud che ospita il cluster GKE sia attivata l'API Cloud Logging.
  • Logging a livello di cluster:verifica che il logging sia attivato esplicitamente nella configurazione del cluster GKE.
  • Autorizzazioni pool di nodi:verifica che i nodi all'interno dei pool di nodi del cluster abbiano attivato l'ambito "Scrittura di Cloud Logging", che consente loro di inviare i dati dei log.
  • Autorizzazioni account di servizio:verifica che l'account di servizio utilizzato dai pool di nodi disponga delle autorizzazioni IAM necessarie per interagire con Cloud Logging. In particolare, in genere è richiesto il ruolo "roles/logging.logWriter".
  • Quote di scrittura dell'API Cloud Logging:verifica che le quote di scrittura dell'API Cloud Logging non siano state superate nel periodo di tempo specificato.

Console Google Cloud

  1. Completa e poi copia il seguente comando.
  2. gcpdiag runbook gke/logs \
        --parameter project_id=PROJECT_ID \
        --parameter name=GKE_NAME \
        --parameter location=LOCATION
  3. Apri la console Google Cloud e attiva Cloud Shell.
  4. Apri Cloud Console
  5. Incolla il comando copiato.
  6. Esegui il comando gcpdiag, che scarica l'immagine Docker gcpdiag, quindi esegui i controlli diagnostici. Se applicabile, segui le istruzioni di output per risolvere i problemi relativi ai controlli non riusciti.

Docker

Puoi eseguire gcpdiag utilizzando un wrapper che avvia gcpdiag in un container Docker. È necessario installare Docker o Podman.

  1. Copia ed esegui il seguente comando sulla tua workstation locale.
    curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
  2. Esegui il comando gcpdiag.
    ./gcpdiag runbook gke/logs \
        --parameter project_id=PROJECT_ID \
        --parameter name=GKE_NAME \
        --parameter location=LOCATION

Visualizza i parametri disponibili per questo runbook.

Sostituisci quanto segue:

  • PROJECT_ID: l'ID del progetto contenente la risorsa.
  • GKE_NAME: il nome del cluster GKE.
  • LOCATION: la zona o la regione del cluster GKE.

Flag utili:

Per un elenco e una descrizione di tutti i flag dello strumento gcpdiag, consulta le istruzioni per l'utilizzo di gcpdiag.

Passaggi successivi

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