Questa pagina ti aiuta a risolvere gli errori 400, 401, 403 e 404 che potresti incontrare quando utilizzi Google Kubernetes Engine (GKE).
Problema: errori di autenticazione e autorizzazione
Quando ti connetti ai cluster GKE, potresti ricevere un errore di autenticazione
e autorizzazione con il codice di stato HTTP 401 (Unauthorized)
. Questo problema potrebbe verificarsi quando provi a eseguire un comando kubectl
nel tuo cluster GKE da un ambiente locale.
La causa del problema potrebbe essere una delle seguenti:
- Il plug-in di autenticazione
gke-gcloud-auth-plugin
non è installato o configurato correttamente. - Non disponi delle autorizzazioni per connetterti al server API del cluster ed eseguire comandi
kubectl
.
Per diagnosticare la causa, completa i passaggi descritti nelle sezioni seguenti:
Connettiti al cluster utilizzando curl
Per diagnosticare la causa dell'errore di autenticazione e autorizzazione, connettiti al cluster utilizzando curl
. L'utilizzo di curl
aggira lo strumento a riga di comando kubectl
e il plug-in gke-gcloud-auth-plugin
.
Imposta le variabili di ambiente:
APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION --format "value(endpoint)") TOKEN=$(gcloud auth print-access-token)
Verifica che il token di accesso sia valido:
curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
Quando hai un token di accesso valido, questo comando invia una richiesta al server OAuth 2.0 di Google, che risponde con informazioni sul token.
Prova a connetterti all'endpoint API principale nel server API:
# Get cluster CA certificate gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --format "value(masterAuth.clusterCaCertificate)" | \ base64 -d > /tmp/ca.crt # Make API call with authentication and CA certificate curl -s -X GET "${APISERVER}/api/v1/namespaces" \ --header "Authorization: Bearer $TOKEN" \ --cacert /tmp/ca.crt
Se il comando
curl
ha esito positivo, viene visualizzato un elenco di spazi dei nomi. Procedi per verificare se il plug-in è la causa seguendo i passaggi descritti nella sezione Configurare il plug-in in kubeconfig.Se il comando
curl
non va a buon fine e l'output è simile al seguente, significa che non disponi delle autorizzazioni corrette per accedere al cluster:{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
Per risolvere il problema, rivolgiti all'amministratore per ottenere le autorizzazioni corrette per accedere al cluster.
Configurare l'utilizzo del plug-in in kubeconfig
Se ricevi errori di autenticazione e autorizzazione durante la connessione ai tuoi cluster, ma hai potuto connetterti al cluster utilizzando curl
, assicurati di poter accedere al cluster senza il plug-in gke-gcloud-auth-plugin
.
Per risolvere il problema, configura l'ambiente locale in modo da ignorare il codice binario gke-gcloud-auth-plugin
durante l'autenticazione al cluster. Nei client Kubernetes che eseguono la versione 1.25 e successive, il file binario gke-gcloud-auth-plugin
è obbligatorio, quindi devi utilizzare una versione 1.24 o precedente per lo strumento a riga di comando kubectl
.
Per accedere al cluster senza il plug-in:
Installa lo strumento a riga di comando
kubectl
con la versione 1.24 o precedente utilizzandocurl
. Nell'esempio seguente viene installato lo strumento con la versione 1.24:curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
Apri il file dello script di avvio della shell in un editor di testo. Ad esempio, apri
.bashrc
per la shell Bash:vi ~/.bashrc
Se utilizzi macOS, utilizza
~/.bash_profile
anziché.bashrc
in queste istruzioni.Aggiungi la seguente riga al file dello script di avvio e salvalo:
export USE_GKE_GCLOUD_AUTH_PLUGIN=False
Esegui lo script di avvio:
source ~/.bashrc
Recupera le credenziali per il tuo cluster, che configura il file
.kube/config
:gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION
Sostituisci quanto segue:
CLUSTER_NAME
: il nome del cluster.COMPUTE_LOCATION
: la posizione di Compute Engine.
Esegui un comando
kubectl
. Ad esempio:kubectl cluster-info
Se dopo aver eseguito questi comandi ricevi un errore 401 o un errore di autorizzazione simile, assicurati di disporre delle autorizzazioni corrette, quindi esegui di nuovo il passaggio che ha restituito l'errore.
Errore 400: il pool di nodi richiede la ricostituzione
Quando provi a eseguire un'azione che ricrea il piano di controllo e i nodi, può verificarsi il seguente errore:
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.
Ad esempio, questo errore può verificarsi quando completi una rotazione delle credenziali in corso.
Sul backend, i node pool sono contrassegnati per la ricostituzione, ma l'operazione di ricostituzione effettiva potrebbe richiedere del tempo prima di iniziare. Per questo motivo, l'operazione non va a buon fine perché GKE non ha ancora ricreato uno o più pool di nodi nel tuo cluster.
Per risolvere il problema, scegli una delle seguenti soluzioni:
- Attendi che la ricostruzione venga eseguita. L'operazione potrebbe richiedere ore, giorni o settimane, a seconda di fattori quali periodi di manutenzione ed esclusioni esistenti.
Avvia manualmente una ricreazione dei pool di nodi interessati avviando un upgrade alla stessa versione del piano di controllo.
Per avviare una ricreazione, esegui il seguente comando:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME
Al termine dell'upgrade, riprova a eseguire l'operazione.
Errore 401: accesso non autorizzato
Identificare i cluster con service account del nodo mancanti di 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 Google Cloud console. Vai alla pagina Cluster Kubernetes e controlla 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, scopri come visualizzare approfondimenti e consigli.
Per implementare questo consiglio, concedi il ruolo roles/container.defaultNodeServiceAccount
all'account di servizio del nodo.
Puoi eseguire uno script che cerca gli account di servizio dei nodi nei cluster standard
e Autopilot del tuo progetto per verificare la presenza di account di servizio dei nodi che non dispongono delle autorizzazioni necessarie per GKE. Questo script utilizza l'interfaccia alla gcloud CLI'utilità jq
. Per visualizzare lo script, espandi la sezione seguente:
Visualizza 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.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.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 gli account di servizio del nodo a cui mancano le 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 account di servizio Compute Engine predefinito nel progetto potrebbe
non ottenere automaticamente le autorizzazioni richieste per GKE.
-
Trova il nome dell'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 controllare.
- 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:
- Fai clic sulla scheda Nodi.
- Nella tabella Pool di nodi, fai clic sul nome di un pool di nodi. Viene visualizzata la pagina Dettagli pool di nodi.
- 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 privilegio minimo minimi.gcloud
Per i cluster in modalità Autopilot, esegui il seguente comando:
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccountPer 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 account di servizio predefinito di Compute Engine. Se l'output è notdefault
, 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 privilegio minimo minimi. -
Per concedere il ruolo
roles/container.defaultNodeServiceAccount
all'account di servizio predefinito Compute Engine, completa i seguenti passaggi:console
- Vai alla pagina Welcome (Ti diamo il benvenuto):
- Nel campo Numero progetto, fai clic su Copia negli appunti.
- Vai alla pagina IAM:
- Fai clic su Concedi l'accesso.
- Nel campo Nuovi principali, specifica il seguente valore:
SostituisciPROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_NUMBER
con il numero del progetto che hai copiato. - Nel menu Seleziona un ruolo, seleziona il ruolo Kubernetes Engine Default Node Service Account.
- Fai clic su Salva.
gcloud
- 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
- 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.
Errore 403: autorizzazioni insufficienti
Quando provi a connetterti a un cluster GKE utilizzando gcloud container clusters get-credentials
, ma l'account non dispone dell'autorizzazione per accedere al server API Kubernetes, si verifica il seguente errore:
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".
Per risolvere il problema, svolgi i seguenti passaggi:
Identifica l'account con il problema di accesso:
gcloud auth list
Concedi l'accesso richiesto all'account seguendo le istruzioni riportate in Autenticazione nel server dell'API Kubernetes.
Errore 403: budget di riprova esaurito
Quando provi a creare un cluster GKE, può verificarsi il seguente errore:
Error: googleapi: Error 403: Retry budget exhausted: Google Compute Engine:
Required permission 'PERMISSION_NAME' for 'RESOURCE_NAME'.
In questo messaggio di errore si applicano le seguenti variabili:
PERMISSION_NAME
: il nome di un'autorizzazione, ad esempiocompute.regions.get
.RESOURCE_NAME
: il percorso della Google Cloud risorsa a cui stavi tentando di accedere, ad esempio una regione Compute Engine.
Questo errore si verifica se l'account di servizio IAM associato al cluster non dispone delle autorizzazioni minime richieste per creare il cluster.
Per risolvere il problema:
- Crea o modifica un account di servizio IAM in modo che disponga di tutte le autorizzazioni necessarie per eseguire un cluster GKE. Per le istruzioni, consulta Utilizzare gli account di servizio IAM con privilegi minimi.
- Specifica l'account di servizio IAM aggiornato nel comando di creazione del cluster utilizzando il flag
--service-account
. Per le istruzioni, consulta Creare un cluster Autopilot.
In alternativa, ometti il flag --service-account
per consentire a GKE di utilizzare
l'account di servizio predefinito di Compute Engine nel progetto, che ha
le autorizzazioni richieste per impostazione predefinita.
Errore 404: risorsa non trovata
Se ricevi un errore 404 (Risorsa non trovata) quando chiami i comandi gcloud container
, risolvi il problema autenticandoti di nuovo in Google Cloud CLI:
gcloud auth login
Errore 400/403: autorizzazioni di modifica mancanti nell'account
Un errore di autorizzazione di modifica mancante nell'account (errore 400 o 403) indica che uno dei seguenti elementi è stato eliminato o modificato manualmente:
- Il tuo account di servizio predefinito Compute Engine.
- L'agente di servizio API di Google.
- Il service account associato a GKE.
Quando attivi l'API Compute Engine o Kubernetes Engine, Google Cloud vengono creati i seguenti account di servizio e agenti:
- Account di servizio predefinito Compute Engine nel progetto. GKE collega questo account di servizio ai nodi per impostazione predefinita per attività di sistema come il logging e il monitoraggio.
- Agente di servizio per le API di Google in un progetto gestito da Google, con autorizzazioni di modifica sul progetto.
- Agente di servizio Google Kubernetes Engine in un progetto gestito da Google, con il ruolo Agente di servizio Kubernetes Engine nel progetto.
La creazione e tutta la gestione del cluster non vanno a buon fine se, in qualsiasi momento, qualcuno modifica queste autorizzazioni, rimuove le associazioni di ruolo nel progetto, rimuove completamente l'account servizio o disattiva l'API.
Verifica le autorizzazioni per l'agente di servizio GKE
Per verificare se all'account di servizio Google Kubernetes Engine è stato assegnato il ruolo Agente di servizio Kubernetes Engine nel progetto, svolgi i seguenti passaggi:
Determina il nome dell'account di servizio Google Kubernetes Engine. Tutti gli account di servizio hanno il seguente formato:
service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
Sostituisci
PROJECT_NUMBER
con il numero del progetto.Verifica che al tuo account di servizio Google Kubernetes Engine non sia assegnato il ruolo Kubernetes Engine Service Agent nel progetto:
gcloud projects get-iam-policy PROJECT_ID
Sostituisci
PROJECT_ID
con l'ID progetto.
Per risolvere il problema, se qualcuno ha rimosso il ruolo Agente di servizio Kubernetes Engine dal tuo account di servizio Google Kubernetes Engine, aggiungilo di nuovo. In caso contrario, segui le seguenti istruzioni per riattivare l'API Kubernetes Engine, che ripristina le autorizzazioni e gli account di servizio:
Console
Vai alla pagina API e servizi nella Google Cloud console.
Seleziona il progetto.
Fai clic su Abilita API e servizi.
Cerca Kubernetes e seleziona l'API dai risultati di ricerca.
Fai clic su Attiva. Se hai già attivato l'API, devi prima disattivarla e poi riattivarla. L'attivazione dell'API e dei servizi correlati può richiedere diversi minuti.
gcloud
Esegui i seguenti comandi nellgcloud CLI:
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.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
Passaggi successivi
Se non riesci a trovare una soluzione al problema nella documentazione, consulta la pagina Ricevi 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
Stack Overflow
e utilizzando il tag
google-kubernetes-engine
per cercare problemi simili. Puoi anche partecipare al#kubernetes-engine
canale Slack per ricevere ulteriore assistenza dalla community. - Aprire bug o richieste di funzionalità utilizzando l'issue tracker pubblico.