Identidade da carga de trabalho

Nesta página, explicamos a maneira recomendada para seus aplicativos do GKE consumirem serviços fornecidos pelas APIs Google. Para isso, configure uma conta de serviço do Kubernetes para atuar como uma conta de serviço do Google. Todos os pods que estão sendo executados como a conta de serviço do Kubernetes usam a conta de serviço do Google para se autenticarem nos serviços de nuvem.

Visão geral

A identidade da carga de trabalho é a maneira recomendada para acessar os serviços do Google Cloud do GKE graças às propriedades de segurança e maleabilidade dela. Para saber mais, consulte as 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. Depois de configurar a relação entre uma conta de serviço do Kubernetes e uma do Google, qualquer carga de trabalho executada como conta de serviço do Kubernetes será automaticamente autenticada como conta de serviço do Google quando você acessar as APIs Google Cloud.

Para informações sobre como autorizar a conta de serviço do Google a acessar as APIs do Cloud, consulte Noções básicas sobre as 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".

Identidade entre clusters

A relação entre GSAs e KSAs é definida pelo namespace de identidade associado ao projeto. Todas as contas de serviço do Kubernetes que compartilham um nome, um nome de namespace e um namespace de identidade compartilham o mesmo acesso às GSAs. Isso pode ser útil se vários clusters tiverem as mesmas identidades, mas é perigoso se os nomes de conta de serviço e namespaces do Kubernetes não forem gerenciados com cuidado.

Por exemplo, o comando a seguir concede o mesmo acesso a todas as cargas de trabalho do Kubernetes em qualquer cluster no projeto que usa a conta de serviço padrão e o namespace e tem a identidade da carga de trabalho ativada no cluster. 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 namespaces de identidade separados.

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

Limitações

  • A Identidade da carga de trabalho está disponível para clusters que executam a versão 1.12 e superior do 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 a identidade de carga de trabalho estiver ativada, não será mais possível usar a conta de serviço padrão do Compute Engine. Para saber mais, consulte a seção de alternativas abaixo.

  • A identidade da carga de trabalho não pode ser usada com pods em execução na rede do host.

  • Os pods da infraestrutura do GKE, como o Stackdriver e o Heapster, continuarão usando a conta de serviço do nó.

Antes de começar

Prepare-se para a tarefa tomando as seguintes medidas:

  • Verifique se você ativou a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Verifique se o SDK do Cloud está instalado.
  • 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 Cloud IAM Service Account Credentials.

    Ativar API do Cloud IAM Credentials

  2. Crie um cluster com a Identidade da carga de trabalho ativada, substituindo [CLUSTER_NAME] pelo nome do cluster e [PROJECT_ID] pelo nome do projeto do Google Cloud:

    gcloud beta container clusters create [CLUSTER_NAME] \
      --cluster-version=1.12 \
      --identity-namespace=[PROJECT_ID].svc.id.goog
    

    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]
    

    em que [CLUSTER_NAME] é o 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. Caso já tenha uma conta de serviço, poderá usá-la em vez de criar uma nova.

    gcloud

    Substitua [GSA_NAME] pelo nome escolhido para a conta de serviço.

    gcloud iam service-accounts create [GSA_NAME]
    

    Configurar conector

    Observação: esta etapa requer Configurar conector. Siga as instruções de instalação para instalar Configurar conector no cluster.

    apiVersion: iam.cnrm.cloud.google.com/v1alpha1
    kind: IAMServiceAccount
    metadata:
      name: [GSA_NAME]
    spec:
      displayName: [GSA_NAME]
    Para implantar esse manifesto, faça o download para sua máquina como service-account.yaml. SubstituaGSA_NAME pelo nome escolhido para a conta de serviço. Depois, execute:

    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. Use o namespace criado na etapa anterior para a opção --namespace. Substitua [KSA_NAME] pelo nome que você quer usar para a conta de serviço.

    kubectl create serviceaccount \
     --namespace [K8S_NAMESPACE] \
     [KSA_NAME]
    

    Esta ação requer a permissão criar serviceaccounts 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 ligação de política do Cloud 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 na 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
    

    Configurar conector

    Observação: esta etapa requer Configurar conector. Siga as instruções de instalação para instalar Configurar conector no cluster.

    apiVersion: iam.cnrm.cloud.google.com/v1alpha1
    kind: IAMPolicy
    metadata:
      name: iampolicy-workload-identity-sample
    spec:
      resourceRef:
        apiVersion: iam.cnrm.cloud.google.com/v1alpha1
        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 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 --rm -it \
      --generator=run-pod/v1 \
      --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 fazer a limpeza

  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]
    

    Configurar conector

    Se você usou o Configurar conector para criar a conta de serviço, exclua o recurso da conta de serviço:

    kubectl delete -f service-account.yaml

    Esta 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 de carga de trabalho no cluster:

    gcloud beta 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 Cloud IAM Service Account Credentials.

    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 padrão para --workload-metadata-from-node=GKE_METADATA_SERVER

    gcloud beta container clusters update [CLUSTER_NAME] \
      --identity-namespace=[PROJECT_ID].svc.id.goog
    

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

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 o pool de nós atual para ativar GKE_METADATA_SERVER. 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 beta container node-pools update [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

Essa ação requer container.nodes.update permissões 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 beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

Se um cluster tiver a identidade de trabalho ativada, será possível desativá-la seletivamente em um pool de nós especificando explicitamente --workload-metadata-from-node=EXPOSED ou --workload-metadata-from-node=SECURE. Consulte Como proteger os metadados do cluster para mais informações.

gcloud beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE

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

Como fazer a limpeza

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

    gcloud beta container node-pools update [NODEPOOL_NAME] \
      --cluster=[CLUSTER_NAME] \
      --workload-metadata-from-node=EXPOSED
    

    Essa ação requer container.nodes.update permissões 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_SERVER. 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 beta 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. Exportar as chaves da conta de serviço e armazená-las como secrets do Kubernetes As chaves da conta de serviço do Google expiram após 10 anos, e são alternadas manualmente. Isso pode expandir o escopo de uma violação de segurança se ele não for detectado.

  2. Use a conta de serviço padrão do Compute Engine nos nós. A conta de serviço padrão do Compute Engine é compartilhada por todas as cargas de trabalho implantadas nesse nó. Isso pode resultar em excesso de aprovisionamento de permissões.

A seguir