Identidade da carga de trabalho

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 no GKE, devido às propriedades de segurança e maleabilidade dela. Para informações sobre maneiras alternativas de acessar as APIs Cloud no GKE, consulte a seção alternativas abaixo.

As cargas de trabalho em execução no GKE precisam ser autenticadas para usar as APIs Google Cloud, como as APIs Compute, APIs Storage e APIs Database ou APIs Machine Learning.

Graças à Identidade da carga de trabalho, você configura uma conta de serviço do Kubernetes (KSA, na sigla em inglês) para atuar como uma conta de serviço do Google (GSA, na sigla em inglês). Qualquer carga de trabalho em execução como KSA é autenticada automaticamente como a GSA ao acessar as APIs Google Cloud.

Para informações sobre como autorizar GSAs a acessar as APIs Google Cloud, consulte Noções básicas sobre contas de serviço.

Terminologia

Neste documento, diferenciamos as contas de serviço do Kubernetes (KSAs, na sigla em inglês) e as contas de serviço do Google (GSAs, na sigla em inglês). As KSAs são recursos do Kubernetes, enquanto as GSAs são específicas do Google Cloud. Outra documentação do Google Cloud refere-se às GSAs como "contas de serviço".

Como autenticar contas de serviço do Kubernetes

Por padrão, o Google Cloud não pode autenticar solicitações de uma conta de serviço do Kubernetes (KSA), porque a carga de trabalho não entende quais credenciais de autenticação apresentar ao Google Cloud e porque as únicas credenciais disponíveis para a carga de trabalho se originam do sistema de identidade do Kubernetes, que não é confiável para o Google Cloud.

A Identidade da carga de trabalho introduz o conceito de pool de identidades de carga de trabalho de um cluster, permitindo que o Cloud Identity and Access Management (Cloud IAM) confie em sistemas de identidade externos e os entenda, como credenciais de KSA. A identidade da carga de trabalho intercepta chamadas para o servidor de metadados do Compute Engine para trocar credenciais do pool de identidades da carga de trabalho por credenciais dos GSAs associados. Isso permite que as cargas de trabalho sejam autenticadas em todas as outras APIs do Google Cloud.

Ao ativar a Identidade da carga de trabalho no cluster do GKE, defina o pool de identidades da carga de trabalho do cluster como some.workload-pool.id.goog. O GKE autentica solicitações de KSAs para o Google Cloud usando o nome de membro a seguir:

serviceAccount:some.workload-pool.id.goog[k8s_namespace/ksa_name]

Neste nome de membro:

  • some.workload-pool.id.goog é o pool de identidades de carga de trabalho definido no cluster.
  • ksa_name é o nome da KSA que faz a solicitação;
  • k8s_namespace é o namespace do Kubernetes em que a KSA é 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ê.

Como criar uma relação entre KSAs e GSAs

Como a identidade da carga de trabalho permite que o Google Cloud autentique KSAs, use o Cloud IAM para autorizar uma KSA a agir como uma GSA.

A GSA não precisa estar no mesmo projeto do cluster. Use qualquer GSA na sua organização. Por exemplo, os comandos a seguir autorizam um KSA hospedado em cluster_project a agir como um GSA em gsa_project:

gcloud config set project gsa_project
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:cluster_project.svc.id.goog[k8s_namespace/ksa_name]" \
  gsa_name@gsa_project.iam.gserviceaccount.com

Neste exemplo:

  • cluster_project é o ID do projeto de um projeto do cluster.
  • gsa_project é o ID do projeto de um projeto do GSA que não está no cluster.

Para anotar a KSA e concluir a vinculação entre KSA e GSA:

kubectl annotate serviceaccount \
  --namespace k8s_namespace \
   ksa_name \
   iam.gke.io/gcp-service-account=gsa_name@gsa_project.iam.gserviceaccount.com

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 de carga de trabalho, suas solicitações para o servidor de metadados da instância são roteadas 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 modificações.

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 GSA em que o pod está configurado. O tráfego para o servidor de metadados nunca sai da instância de VM que hospeda o pod.

Como compartilhar identidades entre clusters

Todas as KSAs que compartilham um nome, nome de namespace e pool de identidade de carga de trabalho resolvem para o mesmo nome de membro e, portanto, compartilham o acesso aos GSAs. Isso poderá ser útil se vários clusters tiverem as mesmas identidades, mas perigoso se os nomes das KSA e os namespaces não forem gerenciados com cuidado.

Por exemplo, se a identidade de carga estiver ativada no cluster, o comando a seguir concederá o mesmo acesso a todas as cargas de trabalho do Kubernetes em qualquer cluster no projeto que use a conta de serviço e o namespace padrão:

gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:project-id.svc.id.goog[default/default]" \
  gsa-name@project-id.iam.gserviceaccount.com

Substitua:

  • project-id: o ID do projeto que usa a conta de serviço padrão.
  • gsa-name: o nome do GSA.

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 um cluster local do Anthos GKE.

  • 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 estiver 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 desses pods para APIs Metadata 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 com 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 leva alguns segundos para começar a ser executado em um pod recém-criado. Portanto, as tentativas de autenticação ou autorização usando a identidade da carga de trabalho feita nos primeiros segundos da vida útil de um pod podem falhar. Tentar novamente a chamada resolverá o problema.

  • Os agentes 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.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

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.

  1. 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
  2. Siga as instruções para autorizar a gcloud a usar sua conta do Google Cloud.
  3. Crie uma nova configuração ou selecione uma atual.
  4. Escolha um projeto do Google Cloud.
  5. 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

Ativar a Identidade da carga de trabalho em um novo cluster

Nesta seção, explicamos como criar um cluster com a Identidade da carga de trabalho ativada e como iniciar um pod com uma identidade de conta de serviço do Google (GSA).

  1. Verifique se você ativou a API Service Account Credentials do Cloud IAM.

    Ativar API do Cloud IAM Credentials

  2. Crie um cluster com a identidade da carga de trabalho ativada usando o seguinte comando:

    gcloud beta container clusters create cluster-name \
      --release-channel regular \
      --workload-pool=project-id.svc.id.goog
    

    Substitua:

    • cluster-name: o nome do cluster.
    • project-id: o ID do seu projeto do Google Cloud.

    A criação do cluster leva vários minutos.

    Essa ação requer a permissão container.clusters.create no projeto.

    Execute o restante das etapas com um papel menos privilegiado, de acordo com o princípio do menor privilégio. Cada etapa registra as permissões necessárias.

  3. 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.

  4. Crie a conta de serviço do Google. Essa ação requer a permissão iam.serviceAccounts.create no projeto. Se você tiver uma conta de serviço atual, poderá usá-la em vez de criar uma nova conta de serviç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.

    apiVersion: iam.cnrm.cloud.google.com/v1beta1
    kind: IAMServiceAccount
    metadata:
      name: [GSA_NAME]
    spec:
      displayName: [GSA_NAME]
    Para implantar esse manifesto, faça o download dele para sua máquina como service-account.yaml. Substitua GSA_NAME pelo nome escolhido para a conta de serviço. Em seguida, use kubectl para aplicar o manifesto.

    kubectl apply -f service-account.yaml
  5. 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 Criar RBAC de namespace no cluster.

  6. Crie a conta de serviço do Kubernetes.

    kubectl create serviceaccount --namespace k8s-namespace ksa-name
    

    Substitua:

    • k8s-namespace: o nome do namespace que você criou na etapa anterior.
    • ksa-name: o nome que você quer usar para a conta de serviço do Kubernetes.

    Esta ação requer a permissão para criar contas de serviço 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.

  7. Permita que a conta de serviço do Kubernetes use a conta de serviço do Google criando uma vinculação de política do IAM entre as duas. Essa vinculação permite que a conta de serviço do Kubernetes atue como a conta de serviço do Google. Essa ação requer a permissão iam.serviceAccounts.setIamPolicy no projeto.

    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.

    apiVersion: iam.cnrm.cloud.google.com/v1beta1
    kind: IAMPolicy
    metadata:
      name: iampolicy-workload-identity-sample
    spec:
      resourceRef:
        apiVersion: iam.cnrm.cloud.google.com/v1beta1
        kind: IAMServiceAccount
        name: [GSA_NAME]
      bindings:
        - role: roles/iam.workloadIdentityUser
          members:
            - serviceAccount:[PROJECT_ID].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]]
    Para implantar esse manifesto, faça o download dele para sua máquina como policy-binding.yaml. Substitua GSA_NAME, PROJECT_ID K8S_NAMESPACE e KSA_NAME pelos valores correspondentes do seu ambiente. Depois, execute:

    kubectl apply -f policy-binding.yaml
  8. 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 annotate serviceaccount \
      --namespace k8s-namespace \
      ksa-name \
      iam.gke.io/gcp-service-account=gsa-name@project-id.iam.gserviceaccount.com
    

    Esta ação requer permissões de edição de RBAC na conta de serviço do Kubernetes.

  9. 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 run -it \
      --image google/cloud-sdk:slim \
      --serviceaccount ksa-name \
      --namespace k8s-namespace \
      workload-identity-test
    

    A imagem google/cloud-sdk inclui a ferramenta de linha de comando gcloud, 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 de criação de pods RBAC no namespace.

    Agora você está conectado a um shell interativo no pod criado. Execute o seguinte comando:

    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 limpar

  1. Revogue o acesso à conta de serviço do Google:

    gcloud

    Substitua gsa-name pelo nome escolhido para a conta de serviço.

    gcloud iam service-accounts delete gsa-name
    

    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.

  2. 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.

  3. 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.

Ativar a Identidade da carga de trabalho em um cluster atual

  1. Verifique se você ativou a API Service Account Credentials do Cloud IAM.

    Ativar API do Cloud IAM Credentials

  2. Modifique o cluster para ativar a identidade da carga de trabalho. Os pools de nós atuais não são afetados. Novos pools de nós assumem --workload-metadata=GKE_METADATA como padrão.

    gcloud container clusters update cluster-name \
      --workload-pool=project-id.svc.id.goog
    

Migrar cargas de trabalho 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: 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.

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.

Opção 2: criação de pool de nós com a Identidade da carga de trabalho.

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.

Como limpar

  1. Modifique pools de nós atuais para desativar a Identidade da carga de trabalho:

    gcloud container node-pools update nodepool-name \
      --cluster=cluster-name \
      --workload-metadata=GCE_METADATA
    

    Essa ação requer permissões container.nodes.update no projeto.

  2. Modifique o cluster para desativar a identidade da carga de trabalho. Os pools de nós atuais não são afetados, mas a modificação é bloqueada se qualquer pool de nós estiver usando GKE_METADATA. Em pools de nós criados após a desativação da identidade da carga de trabalho, os pods em execução no pool de nós têm acesso ao servidor de metadados do Compute Engine subjacente do nó.

    gcloud container clusters update cluster-name \
      --disable-workload-identity
    

    Essa ação exige permissões container.clusters.update no cluster.

Alternativas

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.

  1. 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.

  2. 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.

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 de KSA que podem ser autenticadas e autorizadas para os recursos do Google Cloud. Para 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 contas de serviço, os administradores também podem desativar a identidade da carga de trabalho para a organização.

Consulte estas instruções para desativar a Identidade da carga de trabalho na sua organização.

A seguir