Esta página mostra-lhe como resolver problemas com as contas de serviço do Google Kubernetes Engine (GKE).
Conceda a função necessária para o GKE às contas de serviço dos nós
As contas de serviço do IAM que os seus nós do GKE usam têm de ter todas as autorizações incluídas na função do IAM Conta de serviço do nó predefinida do Kubernetes Engine (roles/container.defaultNodeServiceAccount
). Se
uma conta de serviço do nó do GKE não tiver uma ou mais destas
autorizações, o GKE não pode realizar tarefas do sistema, como as seguintes:
- Envie registos do sistema e da aplicação de nós para o Cloud Logging.
- Envie métricas do sistema e da aplicação dos nós para o Cloud Monitoring.
- Operar o perfil de desempenho do redimensionador automático horizontal de pods.
As contas de serviço de nós podem não ter determinadas autorizações necessárias pelos seguintes motivos:
- A organização aplica a restrição da política da organização
iam.automaticIamGrantsForDefaultServiceAccounts
, o que impede que o Google Cloud conceda automaticamente funções de IAM a contas de serviço de IAM predefinidas. - A função de IAM que concede às contas de serviço dos nós personalizados não inclui todas as autorizações necessárias que estão incluídas na função
roles/container.defaultNodeServiceAccount
.
Se a conta de serviço do nó não tiver as autorizações necessárias para o GKE, pode ver erros e avisos como os seguintes:
- Na Google Cloud consola, na página Clusters do Kubernetes, é apresentada uma mensagem de erro Conceder autorizações críticas na coluna Notificações para um cluster específico.
Na Google Cloud consola, na página de detalhes do cluster de um cluster específico, é apresentada a seguinte mensagem de erro:
Grant roles/container.defaultNodeServiceAccount role to Node service account to allow for non-degraded operations.
Nos registos de atividade do administrador dos registos de auditoria do Cloud, as APIs como Google Cloud
monitoring.googleapis.com
têm os seguintes valores se as autorizações correspondentes para aceder a essas APIs estiverem em falta na conta de serviço do nó:- Gravidade:
ERROR
- Mensagem:
Permission denied (or the resource may not exist)
- Gravidade:
Faltam registos de nós específicos no Cloud Logging e os registos de pods do agente de registo nesses nós mostram erros
401
. Para obter estes registos de pods, execute o seguinte 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 o resultado for
true
, significa que a carga de trabalho do sistema está a ter401
erros, o que indica uma falta de autorizações.
Para resolver este problema, conceda a função Conta de serviço do nó predefinida do Kubernetes Engine (roles/container.defaultNodeServiceAccount
) no projeto à conta de serviço que está a causar os erros. Selecione uma das seguintes opções:
consola
Para encontrar o nome da conta de serviço que os seus nós usam, faça o seguinte:
Aceda à página Clusters do Kubernetes:
Na lista de clusters, clique no nome do cluster que quer inspecionar.
Encontre o nome da conta de serviço do nó. Vai precisar deste nome mais tarde.
- Para clusters do modo de piloto automático, na secção Segurança, encontre o campo Conta de serviço.
- Para clusters do modo padrão, faça o seguinte:
- Clique no separador Nós.
- Na tabela Conjuntos de nós, clique no nome de um conjunto de nós. É apresentada a página Detalhes do conjunto de nós.
- Na secção Segurança, encontre o campo Conta de serviço.
Se o valor no campo Conta de serviço for
default
, os seus nós usam a conta de serviço predefinida do Compute Engine. Se o valor neste campo não fordefault
, os seus nós usam uma conta de serviço personalizada.
Para conceder a função Kubernetes Engine Default Node Service Account
à conta de serviço, faça o seguinte:
Aceda à página Boas-vindas:
No campo Número do projeto, clique em
Copiar para a área de transferência.Aceda à página IAM:
Clique em
Conceder acesso.No campo Novos membros, especifique o nome da conta de serviço do nó. Se os seus nós usarem a conta de serviço do Compute Engine predefinida, especifique o seguinte valor:
PROJECT_NUMBER-compute@developer.gserviceaccount.com
Substitua
PROJECT_NUMBER
pelo número do projeto que copiou.No menu Selecionar uma função, selecione a função Conta de serviço do nó predefinido do Kubernetes Engine.
Clique em Guardar.
Para verificar se a função foi concedida, faça o seguinte:
- Na página IAM, clique no separador Vista por funções.
- Expanda a secção Conta de serviço do nó predefinido do Kubernetes Engine. É apresentada uma lista de responsáveis que têm esta função.
- Encontre a sua conta de serviço do nó na lista de responsáveis.
gcloud
Encontre o nome da conta de serviço que os seus nós usam:
- Para clusters no modo Autopilot, execute o seguinte comando:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccount
- Para clusters no modo padrão, execute o seguinte comando:
gcloud container clusters describe CLUSTER_NAME \ --location=LOCATION \ --format="table(nodePools.name,nodePools.config.serviceAccount)"
Se o resultado for
default
, os seus nós usam a conta de serviço predefinida do Compute Engine. Se o resultado não fordefault
, os seus nós usam uma conta de serviço personalizada.Encontre o seu Google Cloud número do projeto:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Substitua
PROJECT_ID
pelo ID do seu projeto.O resultado é semelhante ao seguinte:
12345678901
Conceda a função
roles/container.defaultNodeServiceAccount
à conta de serviço:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="SERVICE_ACCOUNT_NAME" \ --role="roles/container.defaultNodeServiceAccount"
Substitua
SERVICE_ACCOUNT_NAME
pelo nome da conta de serviço, que encontrou no passo anterior. Se os seus nós usarem a conta de serviço predefinida do Compute Engine, especifique o seguinte valor:serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com
Substitua
PROJECT_NUMBER
pelo número do projeto do passo anterior.Confirme se a função foi concedida com êxito:
gcloud projects get-iam-policy PROJECT_ID \ --flatten="bindings[].members" --filter=bindings.role:roles/container.defaultNodeServiceAccount \ --format='value(bindings.members)'
O resultado é o nome da sua conta de serviço.
Identifique clusters que têm contas de serviço de nós com autorizações em falta
Use as recomendações do GKE do NODE_SA_MISSING_PERMISSIONS
subtipo de recomendador para
identificar clusters do Autopilot e Standard que têm contas de serviço de nós com autorizações em falta. O Recomendador identifica apenas clusters criados a 1 de janeiro de 2024 ou após esta data. Para encontrar e corrigir as autorizações em falta através do Recomendador, faça o seguinte:
Encontre recomendações ativas no seu projeto para o subtipo do recomendador:
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"
Substitua o seguinte:
LOCATION
: a localização onde encontrar recomendações.PROJECT_ID
: o ID do seu Google Cloud projeto.
O resultado é semelhante ao seguinte, o que indica que um cluster tem uma conta de serviço do nó com autorizações em falta:
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
A recomendação pode demorar até 24 horas a aparecer. Para ver instruções detalhadas, consulte ver estatísticas e recomendações.
Para cada cluster que esteja na saída do passo anterior, encontre as contas de serviço dos nós associados e conceda a função necessária a essas contas de serviço. Para ver detalhes, consulte as instruções na secção Conceda às contas de serviço do nó a função necessária para o GKE.
Depois de conceder a função necessária às contas de serviço do nó identificadas, a recomendação pode persistir até 24 horas, a menos que a rejeite manualmente.
Identifique todas as contas de serviço de nós com autorizações em falta
Pode executar um script que procure pools de nós nos clusters padrão e do Autopilot do seu projeto para quaisquer contas de serviço de nós que não tenham as autorizações necessárias para o GKE. Este script usa a CLI gcloud e o utilitário jq
. Para ver o script, expanda a secção seguinte:
Veja o guião
#!/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
Este script aplica-se a todos os clusters do GKE no seu projeto.
Depois de identificar os nomes das contas de serviço com autorizações em falta, atribua-lhes a função necessária. Para ver detalhes, consulte as instruções na secção Conceda às contas de serviço do nó a função necessária para o GKE.
Restaure a conta de serviço predefinida para o seu Google Cloud projeto
A conta de serviço predefinida do GKE, container-engine-robot
, pode ser desvinculada acidentalmente de um projeto. A
função de agente de serviço do Kubernetes Engine
(roles/container.serviceAgent
) é uma função de gestão de identidade e de acesso (IAM)
que concede à conta de serviço as autorizações para gerir recursos do cluster. Se remover esta associação de funções da conta de serviço, a conta de serviço predefinida deixa de estar associada ao projeto, o que pode impedir a implementação de aplicações e a realização de outras operações de cluster.
Para ver se a conta de serviço foi removida do seu projeto, pode usar a Google Cloud consola ou a CLI do Google Cloud.
Consola
Na Google Cloud consola, aceda à página IAM e administração.
gcloud
Execute o seguinte comando:
gcloud projects get-iam-policy PROJECT_ID
Substitua
PROJECT_ID
pelo ID do seu projeto.
Se o painel de controlo ou o comando não apresentar container-engine-robot
entre as suas contas de serviço, a função não está associada.
Para restaurar a associação da função de agente do serviço do Kubernetes Engine (roles/container.serviceAgent
), execute os seguintes comandos:
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
Confirme que a associação de funções foi restaurada:
gcloud projects get-iam-policy PROJECT_ID
Se vir o nome da conta de serviço juntamente com a função container.serviceAgent
, a associação de funções é restaurada. Por exemplo:
- members:
- serviceAccount:service-1234567890@container-engine-robot.iam.gserviceaccount.com
role: roles/container.serviceAgent
Ative a conta de serviço predefinida do Compute Engine
A conta de serviço usada para o conjunto de nós é normalmente a conta de serviço predefinida do Compute Engine. Se esta conta de serviço predefinida for desativada, os seus nós podem não se registar no cluster.
Para ver se a conta de serviço está desativada no seu projeto, pode usar a Google Cloud consola ou a CLI gcloud.
Consola
Na Google Cloud consola, aceda à página IAM e administração.
gcloud
- Execute o seguinte comando:
gcloud iam service-accounts list --filter="NAME~'compute' AND disabled=true"
Se a conta de serviço estiver desativada, execute os seguintes comandos para ativar a conta de serviço:
Encontre o seu Google Cloud número do projeto:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Substitua
PROJECT_ID
pelo ID do seu projeto.O resultado é semelhante ao seguinte:
12345678901
Ative a conta de serviço:
gcloud iam service-accounts enable PROJECT_NUMBER-compute@developer.gserviceaccount.com
Substitua
PROJECT_NUMBER
pelo número do projeto da saída do passo anterior.
Para mais informações, consulte o artigo Resolva problemas de registo de nós.
Erro 400/403: autorizações de edição em falta na conta
Se a sua conta de serviço for eliminada, pode ver um erro de autorizações de edição em falta. Para saber como resolver problemas relacionados com este erro, consulte o artigo Erro 400/403: faltam autorizações de edição na conta.
O que se segue?
Se não conseguir encontrar uma solução para o seu problema na documentação, consulte a secção Obtenha apoio técnico para receber mais ajuda, incluindo aconselhamento sobre os seguintes tópicos:
- Abrindo um registo de apoio ao cliente através do contacto com o Cloud Customer Care.
- Receber apoio técnico da comunidade fazendo perguntas no StackOverflow e usando a etiqueta
google-kubernetes-engine
para pesquisar problemas semelhantes. Também pode juntar-se ao#kubernetes-engine
canal do Slack para receber mais apoio técnico da comunidade. - Abrir erros ou pedidos de funcionalidades através do rastreador de problemas público.