Auf dieser Seite erfahren Sie, wie Sie Probleme mit Dienstkonten in der Google Kubernetes Engine (GKE) beheben.
Erforderliche Rolle für GKE Knotendienstkonten zuweisen
Für GKE-Cluster mit Kubernetes-Version 1.33 oder niedriger müssen die IAM-Dienstkonten, die von Ihren GKE-Knoten verwendet werden, alle Berechtigungen haben, die in der IAM-Rolle Kubernetes Engine-Standardknoten-Dienstkonto (roles/container.defaultNodeServiceAccount
) enthalten sind. Wenn einem GKE-Knotendienstkonto eine oder mehrere dieser Berechtigungen fehlen, kann GKE keine Systemaufgaben wie die folgenden ausführen:
- System- und Anwendungslogs von Knoten an Cloud Logging senden.
- System- und Anwendungsmesswerte von Knoten an Cloud Monitoring senden.
- Leistungsprofil des horizontalen Pod-Autoscalers anpassen
Knoten-Dienstkonten haben möglicherweise aus folgenden Gründen nicht die erforderlichen Berechtigungen:
- In der Organisation wird die Einschränkung für die Organisationsrichtlinie
iam.automaticIamGrantsForDefaultServiceAccounts
erzwungen, die verhindert, dass Google Cloud automatisch IAM-Rollen für Standard-IAM-Dienstkonten gewährt. - Die IAM-Rolle, die Sie Dienstkonten für benutzerdefinierte Knoten zuweisen, enthält nicht alle erforderlichen Berechtigungen, die in der Rolle
roles/container.defaultNodeServiceAccount
enthalten sind.
Wenn Ihrem Knoten-Dienstkonto die von GKE benötigten Berechtigungen fehlen, werden möglicherweise Fehler und Hinweise wie die folgenden angezeigt:
- In der Google Cloud Console wird auf der Seite Kubernetes-Cluster in der Spalte Benachrichtigungen für einen bestimmten Cluster die Fehlermeldung Kritische Berechtigungen erteilen angezeigt.
In der Google Cloud Console wird auf der Seite mit den Clusterdetails für einen bestimmten Cluster die folgende Fehlermeldung angezeigt:
Grant roles/container.defaultNodeServiceAccount role to Node service account to allow for non-degraded operations.
In Cloud-Audit-Logs haben Administratoraktivitätslogs für Google Cloud APIs wie
monitoring.googleapis.com
die folgenden Werte, wenn dem Knotendienstkonto die entsprechenden Berechtigungen für den Zugriff auf diese APIs fehlen:- Schweregrad:
ERROR
- Nachricht:
Permission denied (or the resource may not exist)
- Schweregrad:
Logs für bestimmte Knoten fehlen in Cloud Logging und die Pod-Logs für den Logging-Agent auf diesen Knoten enthalten
401
-Fehler. Führen Sie den folgenden Befehl aus, um diese Pod-Logs abzurufen:[[ $(kubectl logs -l k8s-app=fluentbit-gke -n kube-system -c fluentbit-gke | grep -cw "Received 401") -gt 0 ]] && echo "true" || echo "false"
Wenn die Ausgabe
true
ist, treten bei der Systemarbeitslast401
-Fehler auf, die auf fehlende Berechtigungen hinweisen.
Weisen Sie zur Behebung dieses Problems dem Dienstkonto, das die Fehler verursacht, die Rolle „Kubernetes Engine Default Node Service Account“ (roles/container.defaultNodeServiceAccount
) für das Projekt zu. Wählen Sie eine der folgenden Optionen aus:
Console
So finden Sie den Namen des Dienstkontos, das von Ihren Knoten verwendet wird:
Zur Seite Kubernetes-Cluster
Klicken Sie in der Clusterliste auf den Namen des Clusters, den Sie prüfen möchten.
Suchen Sie nach dem Namen des Knotendienstkontos. Sie benötigen diesen Namen später.
- Suchen Sie bei Clustern im Autopilot-Modus im Abschnitt Sicherheit nach dem Feld Dienstkonto.
- Führen Sie für Cluster im Standardmodus die folgenden Schritte aus:
- Klicken Sie auf den Tab Knoten.
- Klicken Sie in der Tabelle Knotenpools auf einen Knotenpoolnamen. Die Seite Knotenpooldetails wird geöffnet.
- Suchen Sie im Abschnitt Sicherheit nach dem Feld Dienstkonto.
Wenn der Wert im Feld Dienstkonto
default
ist, verwenden Ihre Knoten das Compute Engine-Standarddienstkonto. Wenn der Wert in diesem Feld nichtdefault
ist, verwenden Ihre Knoten ein benutzerdefiniertes Dienstkonto.
So weisen Sie dem Dienstkonto die Rolle Kubernetes Engine Default Node Service Account
zu:
Rufen Sie die Seite Willkommen auf:
Klicken Sie im Feld Projektnummer auf
In die Zwischenablage kopieren.Rufen Sie die IAM-Seite auf.
Klicken Sie auf
Zugriffsrechte erteilen.Geben Sie im Feld Neue Hauptkonten den Namen Ihres Knotendienstkontos an. Wenn Ihre Knoten das Compute Engine-Standarddienstkonto verwenden, geben Sie den folgenden Wert an:
PROJECT_NUMBER-compute@developer.gserviceaccount.com
Ersetzen Sie
PROJECT_NUMBER
durch die kopierte Projektnummer.Wählen Sie im Menü Rolle auswählen die Rolle Kubernetes Engine Default Node Service Account aus.
Klicken Sie auf Speichern.
So prüfen Sie, ob die Rolle gewährt wurde:
- Klicken Sie auf der Seite IAM auf den Tab Nach Rollen ansehen.
- Maximieren Sie den Bereich Kubernetes Engine Default Node Service Account. Eine Liste der Hauptkonten mit dieser Rolle wird angezeigt.
- Suchen Sie Ihr Knotendienstkonto in der Liste der Hauptkonten.
gcloud
So finden Sie den Namen des Dienstkontos, das von Ihren Knoten verwendet wird:
- Führen Sie für Cluster im Autopilot-Modus den folgenden Befehl aus:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccount
- Führen Sie für Cluster im Standardmodus den folgenden Befehl aus:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="table(nodePools.name,nodePools.config.serviceAccount)"
Wenn die Ausgabe
default
ist, verwenden Ihre Knoten das Compute Engine-Standarddienstkonto. Wenn die Ausgabe nichtdefault
ist, verwenden Ihre Knoten ein benutzerdefiniertes Dienstkonto.So finden Sie Ihre Google Cloud Projektnummer:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Ersetzen Sie
PROJECT_ID
durch Ihre Projekt-ID.Die Ausgabe sieht etwa so aus:
12345678901
Weisen Sie dem Dienstkonto die Rolle
roles/container.defaultNodeServiceAccount
zu:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="SERVICE_ACCOUNT_NAME" \ --role="roles/container.defaultNodeServiceAccount"
Ersetzen Sie
SERVICE_ACCOUNT_NAME
durch den Namen des Dienstkontos, den Sie im vorherigen Schritt ermittelt haben. Wenn Ihre Knoten das Compute Engine-Standarddienstkonto verwenden, geben Sie den folgenden Wert an:serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com
Ersetzen Sie
PROJECT_NUMBER
durch die Projektnummer aus dem vorherigen Schritt.Prüfen Sie, ob die Rolle erfolgreich gewährt wurde:
gcloud projects get-iam-policy PROJECT_ID \ --flatten="bindings[].members" --filter=bindings.role:roles/container.defaultNodeServiceAccount \ --format='value(bindings.members)'
Die Ausgabe ist der Name Ihres Dienstkontos.
Cluster mit Knotendienstkonten mit fehlenden Berechtigungen identifizieren
Verwenden Sie GKE-Empfehlungen des NODE_SA_MISSING_PERMISSIONS
Empfehlungssubtyps, um Autopilot- und Standardcluster mit Knoten-Servicekonten mit fehlenden Berechtigungen zu identifizieren. Der Recommender identifiziert nur Cluster, die am oder nach dem 1. Januar 2024 erstellt wurden. So finden und beheben Sie fehlende Berechtigungen mit Recommender:
So finden Sie aktive Empfehlungen in Ihrem Projekt für den Recommender-Untertyp
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"
Ersetzen Sie Folgendes:
LOCATION
: Der Standort, an dem Empfehlungen zu finden sind.PROJECT_ID
: Projekt-ID in Google Cloud .
Die Ausgabe sieht etwa so aus. Sie weist darauf hin, dass für ein Cluster ein Knotendienstkonto mit fehlenden Berechtigungen vorhanden ist:
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
Es kann bis zu 24 Stunden dauern, bis die Empfehlung angezeigt wird. Eine detaillierte Anleitung finden Sie unter Insights und Empfehlungen ansehen.
Suchen Sie für jeden Cluster in der Ausgabe des vorherigen Schritts die zugehörigen Knoten-Dienstkonten und weisen Sie diesen Dienstkonten die erforderliche Rolle zu. Weitere Informationen finden Sie im Abschnitt Erforderliche Rolle für GKE für Knoten-Dienstkonten zuweisen.
Nachdem Sie den identifizierten Knotendienstkonten die erforderliche Rolle zugewiesen haben, wird die Empfehlung möglicherweise bis zu 24 Stunden lang angezeigt, sofern Sie sie nicht manuell schließen.
Alle Knotendienstkonten mit fehlenden Berechtigungen identifizieren
Sie können ein Skript ausführen, das in den Standard- und Autopilot-Clustern Ihres Projekts nach Knotendienstkonten sucht, die nicht die erforderlichen Berechtigungen für GKE haben. In diesem Skript werden die gcloud CLI und das jq
-Dienstprogramm verwendet. Wenn Sie das Skript aufrufen möchten, maximieren Sie den folgenden Abschnitt:
Skript ansehen
#!/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
Dieses Script gilt für alle GKE-Cluster in Ihrem Projekt.
Nachdem Sie die Namen der Dienstkonten mit fehlenden Berechtigungen ermittelt haben, weisen Sie ihnen die erforderliche Rolle zu. Weitere Informationen finden Sie im Abschnitt Knoten-Dienstkonten die erforderliche Rolle für GKE zuweisen.
Standarddienstkonto für Ihr Google Cloud -Projekt wiederherstellen
Die Verknüpfung des GKE-Standarddienstkontos container-engine-robot
mit einem Projekt kann versehentlich aufgehoben werden. Die Rolle Kubernetes Engine-Dienst-Agent (roles/container.serviceAgent
) ist eine IAM-Rolle (Identity and Access Management), mit der dem Dienstkonto Berechtigungen zum Verwalten von Clusterressourcen erteilt werden. Wenn Sie diese Rollenbindung aus dem Dienstkonto entfernen, wird die Verknüpfung des Standarddienstkontos mit dem Projekt aufgehoben. Dies kann verhindern, dass Anwendungen bereitgestellt und andere Clustervorgänge ausgeführt werden.
Mit der Google Cloud Console oder der Google Cloud CLI können Sie prüfen, ob das Dienstkonto aus Ihrem Projekt entfernt wurde.
Console
Rufen Sie in der Google Cloud Console die Seite IAM & Verwaltung auf.
gcloud
Führen Sie dazu diesen Befehl aus:
gcloud projects get-iam-policy PROJECT_ID
Ersetzen Sie
PROJECT_ID
durch Ihre Projekt-ID.
Wenn im Dashboard oder im Befehl unter Ihren Dienstkonten container-engine-robot
nicht angezeigt wird, wurde die Verknüpfung mit dem Dienstkonto aufgehoben.
Führen Sie die folgenden Befehle aus, um die Bindung der Rolle „Kubernetes Engine-Dienst-Agent“ (roles/container.serviceAgent
) wiederherzustellen:
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
Prüfen Sie, ob die Rollenbindung wiederhergestellt wurde:
gcloud projects get-iam-policy PROJECT_ID
Wenn der Name des Dienstkontos zusammen mit der Rolle container.serviceAgent
angezeigt wird, wurde die Rollenbindung wiederhergestellt. Beispiel:
- members:
- serviceAccount:service-1234567890@container-engine-robot.iam.gserviceaccount.com
role: roles/container.serviceAgent
Compute Engine-Standarddienstkonto aktivieren
Das für den Knotenpool verwendete Dienstkonto ist in der Regel das Compute Engine-Standarddienstkonto. Wenn dieses Standarddienstkonto deaktiviert ist, können Ihre Knoten möglicherweise nicht beim Cluster registriert werden.
Mit derGoogle Cloud -Console oder der gcloud CLI können Sie prüfen, ob das Dienstkonto in Ihrem Projekt deaktiviert ist.
Console
Rufen Sie in der Google Cloud Console die Seite IAM & Verwaltung auf.
gcloud
- Führen Sie dazu diesen Befehl aus:
gcloud iam service-accounts list --filter="NAME~'compute' AND disabled=true"
Wenn das Dienstkonto deaktiviert ist, führen Sie die folgenden Befehle aus, um es zu aktivieren:
So finden Sie Ihre Google Cloud Projektnummer:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Ersetzen Sie
PROJECT_ID
durch Ihre Projekt-ID.Die Ausgabe sieht etwa so aus:
12345678901
Aktivieren Sie das Dienstkonto:
gcloud iam service-accounts enable PROJECT_NUMBER-compute@developer.gserviceaccount.com
Ersetzen Sie
PROJECT_NUMBER
durch die Projektnummer aus der Ausgabe des vorherigen Schritts.
Weitere Informationen finden Sie unter Fehlerbehebung bei der Knotenregistrierung.
Fehler 400/403: Dem Konto fehlen Bearbeitungsberechtigungen
Wenn Ihr Dienstkonto gelöscht wird, wird möglicherweise der Fehler „Fehlende Bearbeitungsberechtigungen“ angezeigt. Informationen zum Beheben dieses Fehlers finden Sie unter Fehler 400/403: Dem Konto fehlen Bearbeitungsberechtigungen.
Nächste Schritte
Wenn Sie in der Dokumentation keine Lösung für Ihr Problem finden, lesen Sie den Abschnitt Support erhalten. Dort finden Sie weitere Hilfe, z. B. zu den folgenden Themen:
- Sie können eine Supportanfrage erstellen, indem Sie sich an den Cloud Customer Care wenden.
- Support von der Community erhalten, indem Sie Fragen auf Stack Overflow stellen und mit dem Tag
google-kubernetes-engine
nach ähnlichen Problemen suchen. Sie können auch dem#kubernetes-engine
-Slack-Kanal beitreten, um weiteren Community-Support zu erhalten. - Sie können Fehler melden oder Funktionsanfragen stellen, indem Sie die öffentliche Problemverfolgung verwenden.