Questa pagina ti aiuta a risolvere i problemi relativi alla pipeline di logging di Google Kubernetes Engine (GKE), ad esempio i log che non vengono visualizzati in Cloud Logging. Per maggiori informazioni su come utilizzare i log per risolvere i problemi relativi a carichi di lavoro e cluster, consulta Introduzione alla risoluzione dei problemi di GKE.
Log del cluster mancanti in Cloud Logging
Verifica che la registrazione sia abilitata nel progetto
Elenco servizi attivati:
gcloud services list --enabled --filter="NAME=logging.googleapis.com"
L'output seguente 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 l'ha disattivata:
protoPayload.methodName="google.api.serviceusage.v1.ServiceUsage.DisableService" protoPayload.response.services="logging.googleapis.com"
Se il logging è disabilitato, abilitalo:
gcloud services enable logging.googleapis.com
Verifica che il logging sia abilitato sul cluster.
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 ID progetto Trusted Cloud by S3NS .
L'output è simile al seguente:
cluster-1 SYSTEM_COMPONENTS cluster-2 SYSTEM_COMPONENTS;WORKLOADS cluster-3
Se il valore del cluster è vuoto, la registrazione è disattivata. Ad esempio,
cluster-3
in questo output ha la registrazione disabilitata.Abilita il logging del cluster se impostato su
NONE
:gcloud container clusters update CLUSTER_NAME \ --logging=SYSTEM,WORKLOAD \ --location=COMPUTE_LOCATION
Sostituisci quanto segue:
CLUSTER_NAME
: il nome del tuo cluster.COMPUTE_LOCATION
: la posizione di Compute Engine per il tuo cluster.
Dopo aver verificato di aver abilitato la registrazione nel progetto e nel cluster, valuta la possibilità di utilizzare Gemini Cloud Assist Investigations per ottenere ulteriori informazioni sui log e risolvere i problemi. Per ulteriori informazioni sui diversi modi per avviare un'indagine utilizzando Esplora log, consulta Risolvere i problemi relativi alle indagini di Gemini Cloud Assist nella documentazione di Gemini.
Verifica che i nodi nei pool di nodi abbiano l'ambito di accesso Cloud Logging
Per scrivere log in Cloud Logging, i nodi devono disporre di 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
Controlla gli ambiti configurati in 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:
CLUSTER_NAME
: il nome del tuo cluster.COMPUTE_LOCATION
: la posizione di Compute Engine per il tuo cluster.
Esegui la migrazione dei workload dal vecchio pool di nodi a quello appena creato e monitora l'avanzamento.
Crea nuovi pool di nodi con l'ambito di logging corretto:
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --scopes="gke-default"
Sostituisci quanto segue:
CLUSTER_NAME
: il nome del tuo cluster.COMPUTE_LOCATION
: la posizione di Compute Engine per il tuo cluster.
Identificare i cluster con service account del nodo a cui mancano le autorizzazioni critiche
Per identificare i cluster con service account nodo a cui mancano autorizzazioni critiche, utilizza i consigli di GKE del NODE_SA_MISSING_PERMISSIONS
sottotipo di suggeritore:
- Utilizza la console Trusted Cloud . Vai alla pagina Cluster Kubernetes. Nella colonna Notifiche per cluster specifici, controlla il suggerimento Concedi autorizzazioni critiche.
Utilizza gcloud CLI o l'API Recommender specificando il sottotipo di motore per suggerimenti
NODE_SA_MISSING_PERMISSIONS
.Per eseguire una query per questo consiglio, 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"
Per implementare questo consiglio, concedi il ruolo roles/container.defaultNodeServiceAccount
al account di servizio del nodo.
Puoi eseguire uno script che cerca i node pool nei cluster Standard e Autopilot del tuo progetto per individuare eventuali service account dei nodi che non dispongono delle autorizzazioni richieste per GKE. Questo script utilizza gcloud CLI e l'utilità
jq
. Per visualizzare lo script, espandi la sezione seguente:
Visualizzare lo script
#!/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"
}
# Function to add $1 into the service account array all_service_accounts
# $1: service account
add_service_account() {
local service_account="$1"
all_service_accounts+=( ${service_account} )
}
# Function to add service accounts into the global array all_service_accounts for a Standard GKE cluster
# $1: project_id
# $2: location
# $3: cluster_name
add_service_accounts_for_standard() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read nodepool; do
nodepool_name=$(echo "$nodepool" | awk '{print $1}')
if [[ "$nodepool_name" == "" ]]; then
# skip the empty line which is from running `gcloud container node-pools list` in GCP console
continue
fi
while read nodepool_details; do
service_account=$(echo "$nodepool_details" | awk '{print $1}')
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.s3ns-system.iam.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
add_service_account "${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)")"
}
# Function to add service accounts into the global array all_service_accounts for an Autopilot GKE cluster
# Autopilot cluster only has one node service account.
# $1: project_id
# $2: location
# $3: cluster_name
add_service_account_for_autopilot(){
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read service_account; do
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.s3ns-system.iam.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
add_service_account "${service_account}"
else
echo "cannot find service account" for cluster "$project_id\t$cluster_name\t$cluster_location\t"
fi
done <<< "$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --project "$project_id" --format="table[no-heading](autoscaling.autoprovisioningNodePoolDefaults.serviceAccount)")"
}
# Function to check whether the cluster is an Autopilot cluster or not
# $1: project_id
# $2: location
# $3: cluster_name
is_autopilot_cluster() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
autopilot=$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --format="table[no-heading](autopilot.enabled)")
echo "$autopilot"
}
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}')
# how to find a cluster is a Standard cluster or an Autopilot cluster
autopilot=$(is_autopilot_cluster "$project_id" "$cluster_location" "$cluster_name")
if [[ "$autopilot" == "True" ]]; then
add_service_account_for_autopilot "$project_id" "$cluster_location" "$cluster_name"
else
add_service_accounts_for_standard "$project_id" "$cluster_location" "$cluster_name"
fi
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")
time_series_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.timeSeries.create")
metric_descriptors_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.metricDescriptors.create")
if [[ "$time_series_create_permission" == "No" || "$metric_descriptors_create_permission" == "No" ]]; then
monitoring_permission="No"
else
monitoring_permission="Yes"
fi
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 i service account del nodo a cui mancano le autorizzazioni critiche in un cluster
GKE utilizza i service account IAM collegati ai nodi per
eseguire attività di sistema come il logging e il monitoraggio. Come minimo, questi service account nodo
devono avere il ruolo
Kubernetes Engine Default Node Service Account
(roles/container.defaultNodeServiceAccount
) sul tuo progetto. Per impostazione predefinita,
GKE utilizza l'account di servizio predefinito di Compute Engine,
che viene creato automaticamente nel tuo progetto, come service account del nodo.
Se la tua organizzazione applica il
vincolo di policy dell'organizzazione iam.automaticIamGrantsForDefaultServiceAccounts
, ilaccount di serviziot Compute Engine predefinito nel tuo progetto potrebbe
non ottenere automaticamente le autorizzazioni richieste per GKE.
Per verificare se mancano le autorizzazioni di logging, controlla la presenza di errori
401
nel logging del 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 errori401
, 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.Per identificare tutte le autorizzazioni critiche mancanti, controlla lo script.
-
Trova il nome del account di servizio utilizzato dai tuoi nodi:
Console
- Vai alla pagina Cluster Kubernetes:
- Nell'elenco dei cluster, fai clic sul nome del cluster che vuoi ispezionare.
- 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 Service account.
- Per i cluster in modalità Standard:
- Fai clic sulla scheda Nodi.
- Nella tabella Pool di nodi, fai clic sul nome di un node pool. Viene visualizzata la pagina Dettagli node pool.
- Nella sezione Sicurezza, trova il campo Service account.
Se il valore nel campo Service account è
default
, i nodi utilizzano il account di servizio predefinito di Compute Engine. Se il valore in questo campo non èdefault
, i tuoi nodi utilizzano unaccount di serviziot personalizzato. Per concedere il ruolo richiesto a un account di servizio personalizzato, consulta Utilizzare i service account IAM con privilegio minimo minimi.gcloud
Per i cluster in modalità Autopilot, esegui questo comando:
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccountPer i cluster in modalità Standard, esegui questo comando:
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --format="table(nodePools.name,nodePools.config.serviceAccount)"Se l'output è
default
, i nodi utilizzano il account di servizio predefinito di Compute Engine. Se l'output non èdefault
, i tuoi nodi utilizzano un account di servizio personalizzato. Per concedere il ruolo richiesto a un account di servizio personalizzato, consulta Utilizzare i service account IAM con privilegio minimo minimi. -
Per concedere il ruolo
roles/container.defaultNodeServiceAccount
al account di servizio predefinito di Compute Engine, completa i seguenti passaggi:console
- Vai alla pagina Benvenuto:
- Nel campo Numero progetto, fai clic su Copia negli appunti.
- Vai alla pagina IAM:
- Fai clic su Concedi l'accesso.
- Nel campo Nuove entità, specifica il seguente valore:
SostituisciPROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com
PROJECT_NUMBER
con il numero di progetto che hai copiato. - Nel menu Seleziona un ruolo, seleziona il ruolo Service account predefinito del nodo Kubernetes Engine.
- Fai clic su Salva.
gcloud
- Trova il numero del tuo progetto Trusted Cloud :
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Sostituisci
PROJECT_ID
con l'ID progetto.L'output è simile al seguente:
12345678901
- Concedi il ruolo
roles/container.defaultNodeServiceAccount
all'account di servizio predefinito di Compute Engine:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com" \ --role="roles/container.defaultNodeServiceAccount"
Sostituisci
PROJECT_NUMBER
con il numero di progetto del passaggio precedente.
- Verifica che i service account dei nodi dispongano delle autorizzazioni richieste. Controlla lo script per la verifica.
Uno script per identificare le autorizzazioni mancanti per il service account del nodo GKE
Puoi eseguire uno script che cerca i node pool nei cluster Standard e Autopilot del tuo progetto per individuare eventuali service account dei nodi che non dispongono delle autorizzazioni richieste per GKE. Questo script utilizza gcloud CLI e l'utilità
jq
. Per visualizzare lo script, espandi la sezione seguente:
Visualizzare lo script
#!/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"
}
# Function to add $1 into the service account array all_service_accounts
# $1: service account
add_service_account() {
local service_account="$1"
all_service_accounts+=( ${service_account} )
}
# Function to add service accounts into the global array all_service_accounts for a Standard GKE cluster
# $1: project_id
# $2: location
# $3: cluster_name
add_service_accounts_for_standard() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read nodepool; do
nodepool_name=$(echo "$nodepool" | awk '{print $1}')
if [[ "$nodepool_name" == "" ]]; then
# skip the empty line which is from running `gcloud container node-pools list` in GCP console
continue
fi
while read nodepool_details; do
service_account=$(echo "$nodepool_details" | awk '{print $1}')
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.s3ns-system.iam.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
add_service_account "${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)")"
}
# Function to add service accounts into the global array all_service_accounts for an Autopilot GKE cluster
# Autopilot cluster only has one node service account.
# $1: project_id
# $2: location
# $3: cluster_name
add_service_account_for_autopilot(){
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read service_account; do
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.s3ns-system.iam.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
add_service_account "${service_account}"
else
echo "cannot find service account" for cluster "$project_id\t$cluster_name\t$cluster_location\t"
fi
done <<< "$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --project "$project_id" --format="table[no-heading](autoscaling.autoprovisioningNodePoolDefaults.serviceAccount)")"
}
# Function to check whether the cluster is an Autopilot cluster or not
# $1: project_id
# $2: location
# $3: cluster_name
is_autopilot_cluster() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
autopilot=$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --format="table[no-heading](autopilot.enabled)")
echo "$autopilot"
}
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}')
# how to find a cluster is a Standard cluster or an Autopilot cluster
autopilot=$(is_autopilot_cluster "$project_id" "$cluster_location" "$cluster_name")
if [[ "$autopilot" == "True" ]]; then
add_service_account_for_autopilot "$project_id" "$cluster_location" "$cluster_name"
else
add_service_accounts_for_standard "$project_id" "$cluster_location" "$cluster_name"
fi
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")
time_series_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.timeSeries.create")
metric_descriptors_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.metricDescriptors.create")
if [[ "$time_series_create_permission" == "No" || "$metric_descriptors_create_permission" == "No" ]]; then
monitoring_permission="No"
else
monitoring_permission="Yes"
fi
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
Verifica che le quote dell'API Cloud Logging per la scrittura non siano state raggiunte
Verifica di non aver raggiunto le quote di scrittura API per Cloud Logging.
Vai alla pagina Quote nella console Trusted Cloud .
Filtra la tabella per "API Cloud Logging".
Verifica di non aver raggiunto nessuna quota.