Nesta página, explicamos a maneira recomendada para seus aplicativos do Google Kubernetes Engine (GKE) consumirem serviços fornecidos pelas APIs Google.
Visão geral
A Identidade da carga de trabalho é a maneira recomendada para acessar os serviços do Google Cloud em aplicativos sendo executados no GKE. Esse método fornece propriedades de segurança e gerenciamento aprimorados. Para ver informações sobre maneiras alternativas de acessar as APIs do Google Cloud usando o GKE, consulte a seção sobre alternativas abaixo.
Terminologia
Neste documento, diferenciamos as contas de serviço do Kubernetes das contas de serviço do Google. As contas de serviço do Kubernetes são recursos do Kubernetes, enquanto as contas de serviço do Google são específicas do Google Cloud. Outras documentações do Google Cloud se referem às contas de serviço do Google como "contas de serviço".
Conceitos
Os aplicativos em execução no GKE precisam ser autenticados para usar as APIs do Google Cloud, como as APIs de computação, armazenamento, banco de dados ou machine learning.
Com a Identidade da carga de trabalho, é possível configurar uma conta de serviço do Kubernetes para agir como uma conta de serviço do Google. Os pods em execução como conta de serviço do Kubernetes serão automaticamente autenticados como a conta de serviço do Google ao acessar as APIs Google Cloud. Isso permite atribuir identidades e autorizações distintas e distintas para cada aplicativo no seu cluster.
Para ter um mapeamento seguro entre as contas de serviço do Kubernetes e as do Google, a Identidade da carga de trabalho introduz o conceito de um pool de identidades de carga de trabalho de um cluster, o que permite que o gerenciamento de identidade e acesso (IAM) confie e entenda as credenciais da conta de serviço do Kubernetes.
Quando você ativa a Identidade da carga de trabalho no
cluster do GKE, o pool de identidades da carga de trabalho do cluster é definido como PROJECT_ID.svc.id.goog
.
Isso permite que o IAM autentique contas de serviço do Kubernetes como o
seguinte nome de membro:
serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/KSA_NAME]
Neste nome de membro:
PROJECT_ID.svc.id.goog
é o pool de identidades de carga de trabalho definido no cluster.KSA_NAME
é o nome da conta de serviço do Kubernetes que fez a solicitação.K8S_NAMESPACE
é o namespace do Kubernetes em que a conta de serviço do Kubernetes está definida.
Há apenas um pool de identidades de carga de trabalho fixo por projeto do Google Cloud, PROJECT_ID.svc.id.goog
, e ele é criado automaticamente para você.
Semelhança de identidade entre clusters
Todas as contas de serviço do Kubernetes que compartilham um nome, um pool de identidades da carga de trabalho e um nome de namespace resolvem para o mesmo nome de membro e, portanto, compartilham o acesso aos recursos do Google Cloud. Essa identidade comum permite que os aplicativos em um pool de identidades de carga de trabalho acessem um recurso externo em vez de cluster por cluster.
Para entender melhor esse ponto, considere o exemplo a seguir. Os clusters A, B
e C estão inscritos no mesmo pool de identidades de carga de trabalho. Quando os aplicativos no namespace
backend
acessam os recursos do Google Cloud, as identidades deles são
mapeadas para uma conta de serviço comum do Google chamada back
, independentemente
do cluster que hospeda o aplicativo. A conta de serviço do Google back
pode ser
autorizada com qualquer número de APIs do Google Cloud, desde o Cloud Storage ao Cloud SQL.
Devido à igualdade de identidade, é importante que todos os clusters em um pool de identidades de
carga de trabalho sejam confiáveis e bem controlados. Se você revisitar o exemplo anterior, se o Cluster C
pertence a uma equipe separada e não confiável, ele também pode criar um namespace backend
e acessar as APIs do Google Cloud como se fossem backend
no Cluster A ou B.
Para impedir que clusters compartilhem permissões, os clusters precisam estar em projetos separados ou usar nomes distintos de namespaces do Kubernetes. Por exemplo: os usuários com clusters permissivos "dev" e clusters "prod" bloqueados precisam considerar separar esses clusters em projetos diferentes para conseguir pools de identidade de carga de trabalho separados.
Limitações
Atualmente, há apenas um pool de identidades de carga de trabalho fixo por projeto do Google Cloud,
PROJECT_ID.svc.id.goog
, e ele é criado automaticamente para você.Atualmente, a Identidade da carga de trabalho não é compatível quando uma carga de trabalho está em execução em clusters do Anthos no VMware.
A identidade de carga de trabalho substitui a necessidade de usar Ocultação de metadados e, por isso, as duas abordagens são incompatíveis. Os metadados confidenciais protegidos por ocultação de metadados também são protegidos pela identidade da carga de trabalho.
Quando o servidor de metadados do GKE for ativado em um pool de nós, os pods não poderão mais acessar o servidor de metadados do Compute Engine. Em vez disso, a solicitação feita a partir desses pods para as APIs de metadados será encaminhada para o servidor de metadados do GKE. A única exceção são os pods em execução na rede do host (veja o próximo item).
A Identidade da carga de trabalho não pode ser usada por pods em execução na rede do host. A solicitação feita a partir desses pods para as APIs de metadados será encaminhada para o servidor de metadados do Compute Engine.
O servidor de metadados do GKE precisa de alguns segundos para começar a aceitar solicitações em um pod recém-criado. Portanto, as tentativas de autenticação usando a Identidade da carga de trabalho nos primeiros segundos da vida de um pod podem falhar. Tentar novamente a chamada resolverá o problema. Para mais informações, consulte a seção de solução de problemas abaixo.
Os agentes integrados de geração de registros e monitoramento do GKE continuarão a usar a conta de serviço do nó.
A Identidade da carga de trabalho não é compatível com nós do Windows.
A Identidade da carga de trabalho requer a configuração manual para que o Cloud Run para Anthos no Google Cloud continue a lançar métricas de solicitação.
A Identidade da carga de trabalho instalará
ip-masq-agent
se o cluster for criado sem a sinalização--disable-default-snat
.
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Verifique se você ativou a API Google Kubernetes Engine. Ativar a API Google Kubernetes Engine
- Verifique se o SDK do Cloud está instalado.
Defina as configurações padrão da gcloud
usando um dos métodos a seguir:
- Use
gcloud init
se quiser orientações para definir os padrões. - Use
gcloud config
para definir individualmente a região, a zona e o ID do projeto.
Como usar o gcloud init
Se você receber o erro One of [--zone, --region] must be supplied: Please specify
location
, conclua esta seção.
-
Execute
gcloud init
e siga as instruções:gcloud init
Se você estiver usando SSH em um servidor remoto, utilize a sinalização
--console-only
para impedir que o comando inicie um navegador:gcloud init --console-only
-
Siga as instruções para autorizar a
gcloud
a usar sua conta do Google Cloud. - Crie uma nova configuração ou selecione uma atual.
- Escolha um projeto do Google Cloud.
- Escolha uma zona padrão do Compute Engine.
Como usar o gcloud config
- Defina o ID do projeto padrão:
gcloud config set project PROJECT_ID
- Se você estiver trabalhando com clusters zonais, defina a zona do Compute padrão:
gcloud config set compute/zone COMPUTE_ZONE
- Se você estiver trabalhando com clusters regionais, defina a região do Compute padrão:
gcloud config set compute/region COMPUTE_REGION
- Atualize
gcloud
para a versão mais recente:gcloud components update
Como ativar a identidade da carga de trabalho em um cluster
É possível ativar a Identidade da carga de trabalho em um cluster novo ou atual usando a ferramenta gcloud
.
Verifique se você ativou a API Service Account Credentials do IAM.
Para criar um novo cluster com a Identidade da carga de trabalho ativada, use o seguinte comando:
gcloud container clusters create CLUSTER_NAME \ --workload-pool=PROJECT_ID.svc.id.goog
Substitua:
CLUSTER_NAME
: o nome do cluster.PROJECT_ID
: o ID do seu projeto do Google Cloud.
Essa ação requer a permissão
container.clusters.create
no projeto.Para ativar a Identidade da carga de trabalho em um cluster atual, modifique o cluster com o seguinte comando:
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID.svc.id.goog
Os pools de nós existentes não são afetados. novos pools de nós assumem
--workload-metadata=GKE_METADATA
como padrão.Essa ação exige permissões
container.clusters.update
no cluster.
Migrar aplicativos para a Identidade da carga de trabalho
Selecione a estratégia de migração ideal para seu ambiente. Os pools de nós podem ser migrados no local ou é possível criar novos pools de nós com a Identidade da carga de trabalho ativada. Recomendamos a criação de novos pools de nós se você também precisar modificar seu aplicativo para que ele seja compatível com esse recurso.
Opção 1: criação do pool de nós com a Identidade da carga de trabalho (recomendado)
Adicione um novo pool de nós ao cluster com a Identidade da carga de trabalho ativada e migre manualmente cargas de trabalho para esse pool. Isso só funcionará se a identidade da carga de trabalho estiver ativada no cluster.
gcloud container node-pools create NODEPOOL_NAME \
--cluster=CLUSTER_NAME \
--workload-metadata=GKE_METADATA
Se um cluster tiver a identidade de carga de trabalho ativada, será possível desativá-la seletivamente em um pool de nós especificando explicitamente --workload-metadata=GCE_METADATA
. Consulte Como proteger os metadados do cluster para mais informações.
Opção 2: modificação do pool de nós
Modifique um pool de nós atual para ativar GKE_METADATA
. Essa atualização só será bem-sucedida se a identidade da carga de trabalho estiver ativada no cluster. Isso ativa imediatamente a identidade da carga de trabalho para cargas de trabalho implantadas no pool de nós. Essa alteração impedirá
que as cargas de trabalho usem a conta de serviço do Compute Engine
e precisará ser lançada com cuidado.
gcloud container node-pools update NODEPOOL_NAME \
--cluster=CLUSTER_NAME \
--workload-metadata=GKE_METADATA
Essa ação requer permissões container.nodes.update
no projeto.
Como autenticar no Google Cloud
Nesta seção, explicamos como um aplicativo pode ser autenticado no Google Cloud com a Identidade da carga de trabalho. Para fazer isso, atribua uma conta de serviço do Kubernetes ao aplicativo e configure-a para atuar como uma conta de serviço do Google:
Configure
kubectl
para se comunicar com o cluster:gcloud container clusters get-credentials CLUSTER_NAME
Substitua
CLUSTER_NAME
pelo nome do cluster que você criou na etapa anterior.Essa ação requer a permissão
container.clusters.get
no projeto.Como a maioria dos outros recursos, as contas de serviço do Kubernetes residem em um namespace. Crie o namespace a ser usado para a conta de serviço do Kubernetes.
kubectl create namespace K8S_NAMESPACE
Essa ação requer a permissão para criar o RBAC de namespace no cluster.
Crie a conta de serviço do Kubernetes a ser usada para seu aplicativo:
kubectl create serviceaccount --namespace K8S_NAMESPACE KSA_NAME
Substitua:
K8S_NAMESPACE
, o nome do namespace do Kubernetes que você criou na etapa anterior;KSA_NAME
: o nome que você quer usar para a conta de serviço do Kubernetes.
Essa ação requer a permissão para criar contas de serviço de RBAC no namespace.
Como alternativa, é possível usar o namespace padrão ou a conta de serviço padrão do Kubernetes em qualquer namespace.
Crie uma conta de serviço do Google para seu aplicativo. Se você tiver uma conta de serviço atual, poderá usá-la em vez de criar uma nova conta de serviço. A conta de serviço não precisa estar no mesmo projeto que o cluster. É possível usar qualquer conta de serviço do Google na sua organização.
gcloud
Substitua
GSA_NAME
pelo nome escolhido para a conta de serviço.gcloud iam service-accounts create GSA_NAME
Config Connector
Se você já tiver o Config Connector instalado em um cluster, poderá criar um novo cluster do GKE com a identidade da carga de trabalho ativada usando uma configuração do Config Connector.
Observação: esta etapa requer o Config Connector. Siga estas instruções para instalar o Config Connector no cluster.
Para implantar esse manifesto, faça o download dele para sua máquina comoservice-account.yaml
. SubstituaGSA_NAME
pelo nome escolhido para a conta de serviço. Em seguida, usekubectl
para aplicar o manifesto.kubectl apply -f service-account.yaml
Essa ação requer a permissão
iam.serviceAccounts.create
no projeto.Para ver informações sobre como autorizar contas de serviço do Google a acessar as APIs do Google Cloud, consulte Como entender as contas de serviço.
Permita que a conta de serviço do Kubernetes atue como a conta de serviço do Google. Para isso, crie uma vinculação de política do IAM entre as duas contas. Essa vinculação permite que a conta de serviço do Kubernetes atue como a conta de serviço do Google.
gcloud
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/KSA_NAME]" \ GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
Config Connector
Observação: esta etapa requer o Config Connector. Siga estas instruções para instalar o Config Connector no cluster.
Para implantar esse manifesto, faça o download dele para sua máquina comopolicy-binding.yaml
. SubstituaGSA_NAME
,PROJECT_ID
K8S_NAMESPACE
eKSA_NAME
pelos valores correspondentes do seu ambiente. Depois, execute:kubectl apply -f policy-binding.yaml
Essa ação requer a permissão
iam.serviceAccounts.setIamPolicy
no projeto.Adicione a anotação
iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID
à conta de serviço do Kubernetes usando o endereço de e-mail da conta de serviço do Google.kubectl
kubectl annotate serviceaccount \ --namespace K8S_NAMESPACE \ KSA_NAME \ iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
yaml
apiVersion: v1 kind: ServiceAccount metadata: annotations: iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com name: KSA_NAME namespace: K8S_NAMESPACE
Esta ação requer permissões de edição de RBAC na conta de serviço do Kubernetes.
Verifique se as contas de serviço estão configuradas corretamente. Para isso, crie um pod com a conta de serviço do Kubernetes que executa a imagem do contêiner
cloud-sdk
e conecte-se a ele com uma sessão interativa.kubectl
kubectl run -it \ --image google/cloud-sdk:slim \ --serviceaccount KSA_NAME \ --namespace K8S_NAMESPACE \ workload-identity-test
yaml
apiVersion: v1 kind: Pod metadata: name: workload-identity-test namespace: K8S_NAMESPACE spec: containers: - image: google/cloud-sdk:slim name: workload-identity-test command: ["sleep","infinity"] serviceAccountName: KSA_NAME
A imagem
google/cloud-sdk
inclui a ferramenta de linha de comandogcloud
, que é uma maneira conveniente de consumir as APIs Google Cloud. Pode levar algum tempo para fazer o download da imagem.Essa ação requer a permissão para criar o RBAC de pods no namespace.
Agora você está conectado a um shell interativo no pod criado. Execute o seguinte comando no pod:
gcloud auth list
Se as contas de serviço estiverem configuradas corretamente, o endereço de e-mail da conta de serviço do Google será listado como a identidade ativa (e única). Isso demonstra que, por padrão, o pod usa a autoridade da conta de serviço do Google ao chamar APIs Google Cloud.
Como usar a identidade de carga de trabalho do seu código
A autenticação nos serviços do Google Cloud usando o código segue o mesmo processo que a autenticação usando o servidor de metadados do Compute Engine. Quando você usa a Identidade da carga de trabalho, suas solicitações para o servidor de metadados da instância são encaminhadas para o servidor de metadados do GKE. O código atual que autentica usando o servidor de metadados da instância (como o código que usa as bibliotecas de cliente do Google Cloud) funcionará sem precisar de modificações.
Noções básicas do servidor de metadados do GKE
O servidor de metadados do GKE é um novo servidor de metadados projetado para uso com o Kubernetes. Ele é executado como um daemonset
com um pod em cada nó do cluster. O servidor de metadados intercepta solicitações HTTP para
http://metadata.google.internal (169.254.169.254:80
), incluindo solicitações, como
GET /computeMetadata/v1/instance/service-accounts/default/token
, para recuperar um
token para a conta de serviço do Google que o pod está configurado para atuar como. O tráfego para o servidor de metadados nunca sai da instância de VM que hospeda o pod.
O servidor de metadados do GKE implementa apenas um subconjunto de endpoints do servidor de metadados do Compute Engine que são relevantes e seguros para as cargas de trabalho do Kubernetes:
/computeMetadata/v1/instance/attributes/cluster-location
/computeMetadata/v1/instance/attributes/cluster-name
/computeMetadata/v1/instance/attributes/cluster-uid
/computeMetadata/v1/instance/hostname
/computeMetadata/v1/instance/id
/computeMetadata/v1/project/numeric-project-id
/computeMetadata/v1/project/project-id
/computeMetadata/v1/instance/service-accounts
/computeMetadata/v1/instance/service-accounts/default
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email
/computeMetadata/v1/instance/service-accounts/default/identity
/computeMetadata/v1/instance/service-accounts/default/identity?audience=audience
/computeMetadata/v1/instance/service-accounts/default/scopes
/computeMetadata/v1/instance/service-accounts/default/token
/computeMetadata/v1/instance/service-accounts/default/token?scopes=comma-separated-list-of-scopes
Como revogar o acesso
Revogue o acesso à conta de serviço do Google usando o IAM:
gcloud
gcloud iam service-accounts remove-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/KSA_NAME]" \ GSA_NAME@GSA_PROJECT_ID.iam.gserviceaccount.com
Substitua:
PROJECT_ID
, o contêiner do ID do projeto do cluster do GKE;K8S_NAMESPACE
, o nome do namespace do Kubernetes em que a conta de serviço do Kubernetes está localizada;KSA_NAME
, o nome da conta de serviço do Kubernetes que terá o acesso revogado;GSA_NAME
, o nome da conta de serviço do Google;GSA_PROJECT_ID
, o ID do projeto que contém a conta de serviço do Google.
Config Connector
Se você usou o Config Connector para criar a conta de serviço, exclua-a com
kubectl
.kubectl delete -f service-account.yaml
Essa ação exige permissões
iam.serviceAccounts.setIamPolicy
na conta de serviço.Pode levar até 30 minutos para que os tokens em cache expirem. É possível verificar se os tokens em cache já expiraram com este comando:
gcloud auth list
Os tokens em cache expiram se a saída desse comando não incluir mais
GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
.Remova a anotação da conta de serviço do Kubernetes. Esta etapa é opcional porque o acesso foi revogado pelo IAM.
kubectl annotate serviceaccount \ --namespace K8S_NAMESPACE \ KSA_NAME \ iam.gke.io/gcp-service-account=GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
Solução de problemas
O pod não pode se autenticar no Google Cloud
Se não for possível autenticar seu aplicativo no Google Cloud, confira se as configurações a seguir estão definidas corretamente:
Verifique se você ativou a API Service Account Credentials do IAM no projeto que contém o cluster do GKE.
Garanta que a Identidade da carga de trabalho esteja ativada no cluster. Para isso, verifique se ela tem um pool definido de Identidade da carga de trabalho:
gcloud container clusters describe CLUSTER_NAME \ --format="value(workloadIdentityConfig.workloadPool)"
Verifique se o servidor de metadados do GKE (GKE_METADATA) está configurado no pool de nós em que o aplicativo está sendo executado:
gcloud container node-pools describe NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --format="value(config.workloadMetadataConfig.mode)"
Confira se a conta de serviço do Kubernetes está anotada corretamente:
kubectl describe serviceaccount \ --namespace K8S_NAMESPACE \ KSA_NAME
É preciso haver uma anotação no seguinte formato:
iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
Verifique se a conta de serviço do Google está configurada corretamente:
gcloud iam service-accounts get-iam-policy \ GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
Confira se há uma vinculação no seguinte formato:
- members: - serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/KSA_NAME] role: roles/iam.workloadIdentityUser
Se você tiver uma política de rede de cluster, certifique-se de que a saída para 127.0.0.1/32 na porta 988 esteja permitida:
kubectl describe networkpolicy NETWORK_POLICY_NAME
Erros de tempo limite na inicialização do pod
O servidor de metadados do GKE precisa de alguns segundos para começar a aceitar solicitações em um pod recém-criado. Portanto, as tentativas de autenticação usando a Identidade da carga de trabalho nos primeiros segundos da vida de um pod podem falhar em aplicativos e nas bibliotecas de cliente do Google Cloud configuradas com um tempo limite curto.
Se você encontrar erros de tempo limite, altere o código do aplicativo para aguardar alguns segundos e tentar novamente. Como alternativa, é possível implantar um initContainer que aguarda até que o servidor de metadados do GKE esteja pronto antes de executar o contêiner principal do pod.
Veja um pod com um initContainer de exemplo:
apiVersion: v1
kind: Pod
metadata:
name: pod-with-initcontainer
spec:
serviceAccountName: ksa-name
initContainers:
- image: gcr.io/google.com/cloudsdktool/cloud-sdk:326.0.0-alpine
name: workload-identity-initcontainer
command: '/bin/bash'
- '-c'
- |
curl -s -H 'Metadata-Flavor: Google' 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token' --retry 30 --retry-connrefused --retry-max-time 30 > /dev/null || exit 1
containers:
- image: gcr.io/your-project/your-image
name: your-main-application-container
Como desativar a Identidade da carga de trabalho em um cluster
Desative a Identidade da carga de trabalho em cada pool de nós:
gcloud container node-pools update NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --workload-metadata=GCE_METADATA
Repita esse comando em cada pool de nós no cluster.
Desative a identidade de carga de trabalho no cluster:
gcloud container clusters update CLUSTER_NAME \ --disable-workload-identity
Essa ação exige permissões
container.clusters.update
no cluster.
Como desativar a identidade da carga de trabalho na sua organização
Do ponto de vista da segurança, a Identidade da carga de trabalho permite que o GKE declare identidades das contas de serviço do Kubernetes que podem ser autenticadas e autorizadas nos recursos do Google Cloud. Os administradores que realizaram ações para isolar cargas de trabalho de recursos do Google Cloud, como desativar a criação de contas de serviço ou desativar a criação de chaves de conta de serviço, também poderão desativar a Identidade da carga de trabalho na organização se quiserem.
Consulte estas instruções para desativar a Identidade da carga de trabalho na sua organização.
Alternativas à Identidade da carga de trabalho
Há dois métodos alternativos para acessar as APIs do Cloud do GKE. Com o lançamento da identidade da carga de trabalho, não recomendamos mais essas abordagens por causa dos compromissos que elas exigem.
Exporte as chaves da conta de serviço e armazene-as como secrets do Kubernetes. As chaves da conta de serviço do Google expiram após 10 anos e são alternadas manualmente. A exportação de chaves da conta de serviço tem o potencial de expandir o escopo de uma violação de segurança se ela não for detectada.
Use a conta de serviço do Compute Engine dos nós. É possível executar pools de nós como qualquer conta de serviço do IAM no projeto. Se você não especificar uma conta de serviço durante a criação do pool de nós, o GKE usará a conta de serviço padrão do Compute Engine do projeto. A conta de serviço do Compute Engine é compartilhada por todas as cargas de trabalho implantadas no nó. Isso pode resultar em excesso de provisionamento de permissões.
A seguir
- Leia a visão geral de segurança do GKE.
- Saiba mais sobre pods.
- Saiba como proteger metadados de cluster.
- Saiba mais sobre as contas de serviço do Google.