Questa pagina mostra come risolvere i problemi relativi agli account di servizio Google Kubernetes Engine (GKE).
Concedi il ruolo richiesto per GKE ai service account dei nodi
I service account IAM utilizzati dai nodi GKE
devono disporre di tutte le autorizzazioni incluse nel ruolo IAM
Kubernetes Engine Default Node Service Account
(roles/container.defaultNodeServiceAccount
). Se
in un account di servizio del nodo GKE mancano una o più di queste
autorizzazioni, GKE non può eseguire attività di sistema come le seguenti:
- Invia i log di sistema e delle applicazioni dai nodi a Cloud Logging.
- Invia le metriche di sistema e delle applicazioni dai nodi a Cloud Monitoring.
- Gestisci il profilo di rendimento di Horizontal Pod Autoscaler.
I service account dei nodi potrebbero non disporre di determinate autorizzazioni richieste per motivi come i seguenti:
- L'organizzazione applica il
vincolo del criterio dell'organizzazione
iam.automaticIamGrantsForDefaultServiceAccounts
, che impedisce a Trusted Cloud di concedere automaticamente ruoli IAM ai service account IAM predefiniti. - Il ruolo IAM che concedi ai service account dei nodi personalizzati non include tutte le autorizzazioni richieste incluse nel ruolo
roles/container.defaultNodeServiceAccount
.
Se il account di servizio del nodo non dispone delle autorizzazioni richieste da GKE, potresti visualizzare errori e avvisi come i seguenti:
- Nella console Trusted Cloud , nella pagina Cluster Kubernetes, viene visualizzato un messaggio di errore Concedi autorizzazioni critiche nella colonna Notifiche per un cluster specifico.
Nella Trusted Cloud console, nella pagina dei dettagli del cluster per un cluster specifico, viene visualizzato il seguente messaggio di errore:
Grant roles/container.defaultNodeServiceAccount role to Node service account to allow for non-degraded operations.
In Audit log di Cloud, i log Attività di amministrazione per le API Trusted Cloud come
monitoring.googleapis.com
hanno i seguenti valori se le autorizzazioni corrispondenti per accedere a queste API non sono presenti nell'account di servizio del nodo:- Gravità:
ERROR
- Messaggio:
Permission denied (or the resource may not exist)
- Gravità:
I log per nodi specifici non sono presenti in Cloud Logging e i log dei pod per l'agente di logging su questi nodi mostrano errori
401
. Per ottenere i log di questi pod, esegui questo comando:[[ $(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.
Per risolvere il problema, concedi il ruolo Kubernetes Engine Default Node Service Account (roles/container.defaultNodeServiceAccount
) al service account che causa gli errori. Seleziona una delle seguenti opzioni:
console
Per trovare il nome dell'account di servizio utilizzato dai tuoi nodi:
Vai alla pagina Cluster Kubernetes:
Nell'elenco dei cluster, fai clic sul nome del cluster che vuoi controllare.
Trova il nome del account di servizio del nodo. Avrai bisogno di questo nome in un secondo momento.
- Per i cluster in modalità Autopilot, nella sezione Sicurezza, trova 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 nodi utilizzano un account di servizio personalizzato.
Per concedere il ruolo Kubernetes Engine Default Node Service Account
all'account di servizio:
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 nome del service account del nodo. Se i nodi utilizzano il service account predefinito di Compute Engine, specifica il seguente valore:
PROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com
Sostituisci
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.
Per verificare che il ruolo sia stato concesso:
- Nella pagina IAM, fai clic sulla scheda Visualizza per ruoli.
- Espandi la sezione Kubernetes Engine Default Node Service Account. Viene visualizzato un elenco delle entità che hanno questo ruolo.
- Trova l'account di servizio del nodo nell'elenco delle entità.
gcloud
Trova il nome del account di servizio utilizzato dai tuoi nodi:
- Per i cluster in modalità Autopilot, esegui questo comando:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccount
- Per 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 nodi utilizzano un account di servizio personalizzato.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:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="SERVICE_ACCOUNT_NAME" \ --role="roles/container.defaultNodeServiceAccount"
Sostituisci
SERVICE_ACCOUNT_NAME
con il nome del account di servizio che hai trovato nel passaggio precedente. Se i nodi utilizzano ilaccount di serviziot Compute Engine predefinito, specifica il valore seguente:serviceAccount:PROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com
Sostituisci
PROJECT_NUMBER
con il numero di progetto del passaggio precedente.Verifica che il ruolo sia stato concesso correttamente:
gcloud projects get-iam-policy PROJECT_ID \ --flatten="bindings[].members" --filter=bindings.role:roles/container.defaultNodeServiceAccount \ --format='value(bindings.members)'
L'output è il nome del tuo account di servizio.
Identificare i cluster con service account del nodo con autorizzazioni mancanti
Utilizza i suggerimenti di GKE del NODE_SA_MISSING_PERMISSIONS
sottotipo di suggerimento per
identificare i cluster Autopilot e Standard che hanno service account dei nodi con autorizzazioni mancanti. Recommender identifica
solo i cluster creati a partire dal 1° gennaio 2024. Per trovare e correggere le autorizzazioni mancanti utilizzando Recommender:
Trova i suggerimenti attivi nel tuo progetto per il sottotipo di motore per suggerimenti
NODE_SA_MISSING_PERMISSIONS
:gcloud recommender recommendations list \ --recommender=google.container.DiagnosisRecommender \ --location LOCATION \ --project PROJECT_ID \ --format yaml \ --filter="recommenderSubtype:NODE_SA_MISSING_PERMISSIONS"
Sostituisci quanto segue:
LOCATION
: la posizione in cui trovare i suggerimenti.PROJECT_ID
: il tuo ID progetto Trusted Cloud .
L'output è simile al seguente, che indica che un cluster ha un account di servizio nodo con autorizzazioni mancanti:
associatedInsights: # lines omitted for clarity recommenderSubtype: NODE_SA_MISSING_PERMISSIONS stateInfo: state: ACTIVE targetResources: - //container.googleapis.com/projects/12345678901/locations/us-central1/clusters/cluster-1
Potrebbero essere necessarie fino a 24 ore prima che il consiglio venga visualizzato. Per istruzioni dettagliate, vedi Visualizzare approfondimenti e consigli.
Per ogni cluster nell'output del passaggio precedente, trova gli account di servizio dei nodi associati e concedi il ruolo richiesto a questi account di servizio. Per i dettagli, consulta le istruzioni nella sezione Concedere ai service account dei nodi il ruolo richiesto per GKE.
Dopo aver concesso il ruolo richiesto ai service account del nodo identificati, il consiglio potrebbe rimanere attivo fino a 24 ore, a meno che non lo ignori manualmente.
Identifica tutti i service account del nodo con autorizzazioni mancanti
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
Questo script si applica a tutti i cluster GKE del progetto.
Dopo aver identificato i nomi dei service account con le autorizzazioni mancanti, concedi loro il ruolo richiesto. Per maggiori dettagli, consulta le istruzioni nella sezione Concedere ai service account dei nodi il ruolo richiesto per GKE.
Ripristina il account di servizio predefinito nel tuo progetto Trusted Cloud
Il account di servizio predefinito di GKE, container-engine-robot
, può
essere scollegato accidentalmente da un progetto. Il
ruolo agente di servizio Kubernetes Engine
(roles/container.serviceAgent
) è un ruolo Identity and Access Management (IAM)
che concede al account di servizio le autorizzazioni per gestire le risorse del cluster. Se
rimuovi questo binding del ruolo dall'account di servizio, l'account di servizio predefinito
viene scollegato dal progetto, il che può impedirti di eseguire il deployment
delle applicazioni ed eseguire altre operazioni del cluster.
Per verificare se l'account di servizio è stato rimosso dal tuo progetto, puoi utilizzare la console Trusted Cloud o Google Cloud CLI.
Console
Nella Trusted Cloud console, vai alla pagina IAM e amministrazione.
gcloud
Esegui questo comando:
gcloud projects get-iam-policy PROJECT_ID
Sostituisci
PROJECT_ID
con l'ID progetto.
Se la dashboard o il comando non mostra container-engine-robot
tra
i tuoi service account, il ruolo non è associato.
Per ripristinare l'associazione del ruolo Agente di servizio Kubernetes Engine
(roles/container.serviceAgent
), esegui questi comandi:
PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID" \
--format 'get(projectNumber)') \
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot.s3ns-system.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
Verifica che l'associazione di ruolo sia stata ripristinata:
gcloud projects get-iam-policy PROJECT_ID
Se vedi il nome del account di servizio insieme al ruolo container.serviceAgent
, l'associazione del ruolo è stata ripristinata. Ad esempio:
- members:
- serviceAccount:service-1234567890@container-engine-robot.s3ns-system.iam.gserviceaccount.com
role: roles/container.serviceAgent
Abilita l'account di servizio predefinito Compute Engine
Il service account utilizzato per il pool di nodi è in genere l'account di servizio predefinito di Compute Engine. Se questo account di servizio predefinito viene disattivato, la registrazione dei nodi nel cluster potrebbe non riuscire.
Per verificare se il account di servizio è disattivato nel tuo progetto, puoi utilizzare la consoleTrusted Cloud o gcloud CLI.
Console
Nella Trusted Cloud console, vai alla pagina IAM e amministrazione.
gcloud
- Esegui questo comando:
gcloud iam service-accounts list --filter="NAME~'compute' AND disabled=true"
Se il account di servizio è disattivato, esegui questi comandi per abilitarlo:
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
Attiva il account di servizio:
gcloud iam service-accounts enable PROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com
Sostituisci
PROJECT_NUMBER
con il numero del tuo progetto dall'output del passaggio precedente.
Per ulteriori informazioni, consulta la sezione Risoluzione dei problemi di registrazione dei nodi.
Errore 400/403: autorizzazioni di modifica mancanti nell'account
Se il tuo account di servizio viene eliminato, potresti visualizzare un errore relativo alle autorizzazioni di modifica mancanti. Per scoprire come risolvere questo errore, consulta Errore 400/403: autorizzazioni di modifica mancanti nell'account.
Passaggi successivi
Se non riesci a trovare una soluzione al tuo problema nella documentazione, consulta la sezione Richiedere assistenza per ulteriore aiuto, inclusi consigli sui seguenti argomenti:
- Aprire una richiesta di assistenza contattando l'assistenza clienti cloud.
- Ricevere assistenza dalla community
ponendo domande su StackOverflow e utilizzando il tag
google-kubernetes-engine
per cercare problemi simili. Puoi anche unirti al canale Slack#kubernetes-engine
per ulteriore assistenza della community. - Apertura di bug o richieste di funzionalità utilizzando lo strumento di monitoraggio dei problemi pubblico.