Falsch konfigurierte oder fehlende Berechtigungen für Google Kubernetes Engine-Dienstkonten (GKE) können zu verschiedenen Problemen führen, z. B. dass Knoten nicht registriert werden können oder Arbeitslasten nicht auf Google Cloud -Dienste zugreifen können.
In diesem Dokument erfahren Sie, wie Sie Probleme beheben, die durch falsch konfigurierte, deaktivierte oder gelöschte Dienstkonten verursacht werden.
Diese Informationen sind wichtig für Plattformadministratoren und ‑operatoren sowie für Sicherheitsexperten, die IAM-Berechtigungen auf Projektebene für GKE-Knoten und GKE-Kernkomponenten konfigurieren und verwalten. Weitere Informationen zu den gängigen Rollen und Beispielaufgaben, auf die wir in Google Cloud -Inhalten verweisen, finden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.
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 für ein 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.automaticIamGrantsForDefaultServiceAccountserzwungen, wodurch verhindert wird, dass Google Cloud automatisch IAM-Rollen für Standard-IAM-Dienstkonten gewährt. - Die IAM-Rolle, die Sie benutzerdefinierten Knotendienstkonten zuweisen, enthält nicht alle erforderlichen Berechtigungen, die in der Rolle
roles/container.defaultNodeServiceAccountenthalten sind.
Wenn Ihrem Knotendienstkonto 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 Cluster-Detailseite 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 Audit-Logs für Administratoraktivitäten für Google Cloud -APIs wie
monitoring.googleapis.comdie folgenden Werte, wenn die entsprechenden Berechtigungen für den Zugriff auf diese APIs im Dienstkonto des Knotens 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
trueist, 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:
Rufen Sie die Seite Kubernetes-Cluster auf:
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
defaultist, verwenden Ihre Knoten das Compute Engine-Standarddienstkonto. Wenn der Wert in diesem Feld nichtdefaultist, 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 des Dienstkontos Ihres Knotens an. Wenn Ihre Knoten das Compute Engine-Standarddienstkonto verwenden, geben Sie den folgenden Wert an:
PROJECT_NUMBER-compute@developer.gserviceaccount.comErsetzen Sie
PROJECT_NUMBERdurch 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 in der Liste der Hauptkonten nach dem Dienstkonto Ihres Knotens.
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
defaultist, verwenden Ihre Knoten das Compute Engine-Standarddienstkonto. Wenn die Ausgabe nichtdefaultist, verwenden Ihre Knoten ein benutzerdefiniertes Dienstkonto.So finden Sie Ihre Google Cloud Projektnummer:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"Ersetzen Sie
PROJECT_IDdurch Ihre Projekt-ID.Die Ausgabe sieht etwa so aus:
12345678901Weisen Sie dem Dienstkonto die Rolle
roles/container.defaultNodeServiceAccountzu:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="SERVICE_ACCOUNT_NAME" \ --role="roles/container.defaultNodeServiceAccount"Ersetzen Sie
SERVICE_ACCOUNT_NAMEdurch 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.comErsetzen Sie
PROJECT_NUMBERdurch 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 Recommender-Untertyps NODE_SA_MISSING_PERMISSIONS, um Autopilot- und Standardcluster zu identifizieren, die Knotendienstkonten mit fehlenden Berechtigungen haben. Recommender identifiziert nur Cluster, die am oder nach dem 1. Januar 2024 erstellt wurden. So finden und beheben Sie die fehlenden Berechtigungen mit Recommender:
Suchen Sie in Ihrem Projekt nach aktiven Empfehlungen 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 nach Empfehlungen gesucht werden soll.PROJECT_ID: Projekt-ID in Google Cloud .
Die Ausgabe sieht etwa so aus. Sie gibt an, 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-1Es kann bis zu 24 Stunden dauern, bis die Empfehlung angezeigt wird. Eine ausführliche 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 Knotendienstkonten zuweisen.
Nachdem Sie den identifizierten Knotendienstkonten die erforderliche Rolle zugewiesen haben, bleibt die Empfehlung möglicherweise bis zu 24 Stunden bestehen, sofern Sie sie nicht manuell verwerfen.
Alle Knotendienstkonten mit fehlenden Berechtigungen identifizieren
Sie können ein Skript ausführen, das in den Standard- und Autopilot-Clustern Ihres Projekts nach Knoten-Dienstkonten sucht, die nicht die erforderlichen Berechtigungen für GKE haben. In diesem Skript werden die gcloud CLI und das jq-Dienstprogramm verwendet. Maximieren Sie den folgenden Abschnitt, um das Script aufzurufen:
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"
fiDieses 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 in der Anleitung im Abschnitt Knotendienstkonten 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 -Konsole 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_IDErsetzen Sie
PROJECT_IDdurch 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_IDdurch Ihre Projekt-ID.Die Ausgabe sieht etwa so aus:
12345678901Aktivieren Sie das Dienstkonto:
gcloud iam service-accounts enable PROJECT_NUMBER-compute@developer.gserviceaccount.comErsetzen Sie
PROJECT_NUMBERdurch 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, können Sie Support anfordern. Dort erhalten Sie unter anderem Hilfe zu den folgenden Themen:
- Sie können eine Supportanfrage stellen, indem Sie sich an Cloud Customer Care wenden.
- Support von der Community erhalten, indem Sie Fragen auf Stack Overflow stellen und mit dem Tag
google-kubernetes-enginenach ähnlichen Problemen suchen. Sie können auch dem#kubernetes-engine-Slack-Kanal beitreten, um weiteren Community-Support zu erhalten. - Sie können Probleme oder Feature Requests über die öffentliche Problemverfolgung melden.