Configurar a autenticação de identidade da carga de trabalho gerenciada para o GKE

Neste documento, explicamos como configurar identidades gerenciadas de carga de trabalho para o Google Kubernetes Engine (GKE) nos clusters gerenciados por frotas do GKE. Também explica como implantar uma carga de trabalho e verificar a identidade e o certificado dela.

A configuração e o uso de identidades gerenciadas da carga de trabalho para o GKE envolvem as seguintes etapas:

  1. Configure o Certificate Authority Service para emitir certificados para identidades das cargas de trabalho gerenciadas.

  2. Vincule as CAs ao pool de Identidade da carga de trabalho.

  3. Autorize que identidades das cargas de trabalho gerenciadas solicitem certificados do pool de AC.

  4. Implante cargas de trabalho com identidades das cargas de trabalho gerenciadas.

Pool de identidade da carga de trabalho gerenciado pelo Google

Quando você adiciona seus clusters às frotas do GKE, elas criam automaticamente um pool de identidades da carga de trabalho gerenciado pelo Google que serve como raiz do seu domínio de confiança. O pool de identidades da carga de trabalho gerenciado pelo Google tem as seguintes restrições:

  • O Google gerencia totalmente o pool, então não é possível criar sub-recursos, como namespaces, identidades ou provedores de identidade.

  • O pool só pode ser usado para cargas de trabalho do GKE. Não é possível adicionar outros tipos de cargas de trabalho, como VMs do Compute Engine, ao pool.

  • Todos os clusters no pool estão sujeitos ao modelo padrão de igualdade de namespace do Kubernetes. Isso significa que todos os clusters no pool têm privilégios equivalentes. As cargas de trabalho executadas em qualquer um dos clusters no pool podem usar qualquer identidade que esteja no pool.

Configuração de vários projetos

Trusted Cloud recursos usados neste documento, como clusters do GKE, a CA raiz e as CAs subordinadas, podem existir em projetos separados. Ao se referir a esses recursos, use a flag --project para especificar o projeto correto de cada um.

Antes de começar

  1. Create or select a Trusted Cloud project.

    • Create a Trusted Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Trusted Cloud project you are creating.

    • Select the Trusted Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Trusted Cloud project name.

  2. Entenda as identidades das cargas de trabalho gerenciadas.

  3. Verifique se você tem pelo menos um cluster do GKE. Verifique se os clusters estão executando a versão 1.33.0-gke.2248000 ou mais recente.

  4. Adicione seus clusters às frotas do GKE. Se o cluster for do Autopilot, omita --enable-workload-identity. As frotas criam automaticamente um pool de identidades de cargas de trabalho gerenciado pelo Google que serve como um domínio de confiança.

    Execute o seguinte comando para ativar as frotas do GKE:

    gcloud container clusters update CLUSTER_NAME \
        --workload-pool=PROJECT_ID.svc.id.goog \
        --enable-fleet \
        --fleet-project=PROJECT_ID
    

    Substitua:

    • CLUSTER_NAME: o nome do cluster do GKE que você quer registrar na frota do GKE
    • PROJECT_ID: o ID do projeto host da frota do GKE
  5. Enable the IAM and Certificate Authority Service APIs:

    gcloud services enable cloudresourcemanager.googleapis.com iam.googleapis.com privateca.googleapis.com

  6. Configure a Google Cloud CLI para usar o projeto de faturamento e cota.

    gcloud config set billing/quota_project PROJECT_ID
    

    Substitua PROJECT_ID pelo ID do projeto da frota.

Funções exigidas

Para receber as permissões necessárias para criar identidades de cargas de trabalho gerenciadas e provisionar certificados de identidade de carga de trabalho gerenciada, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

Configurar o serviço de AC para emitir certificados para identidades de cargas de trabalho gerenciadas

Para configurar identidades gerenciadas da carga de trabalho para o GKE, primeiro configure uma autoridade certificadora (AC) e uma ou mais ACs subordinadas. Essa configuração é conhecida como uma hierarquia de CA.

É possível usar pools do serviço de CA para configurar essa hierarquia. Com essa hierarquia, o pool de CA subordinada emite os certificados de identidade da carga de trabalho X.509 para suas cargas de trabalho.

Configurar o pool de CAs raiz

Para criar o pool de ACs raiz, faça o seguinte:

Crie o pool de CAs raiz no nível Enterprise usando gcloud privateca pools create. Esse nível é destinado à emissão de certificados de longa duração e de baixo volume.

gcloud privateca pools create ROOT_CA_POOL_ID \
    --location=REGION \
    --project=CA_PROJECT_ID \
    --tier=enterprise

Substitua:

  • ROOT_CA_POOL_ID: um ID exclusivo para o pool de ACs raiz. O ID pode ter até 64 caracteres e precisa conter apenas caracteres alfanuméricos minúsculos e maiúsculos, sublinhados ou hifens. O ID do pool precisa ser exclusivo na região.

  • REGION: a região em que o pool de ACs raiz está localizado.

  • CA_PROJECT_ID: o ID do projeto em que você quer criar a CA raiz.

Para saber mais sobre pools, níveis e regiões de CA, consulte Como criar pools de CA.

Configurar a CA raiz

Crie uma CA raiz no pool de CA raiz usando gcloud privateca roots create. Talvez você precise ativar a AC raiz se essa for a única AC no pool de AC raiz.

Para criar uma CA raiz, execute o seguinte comando:

gcloud privateca roots create ROOT_CA_ID \
    --pool=ROOT_CA_POOL_ID \
    --subject="CN=ROOT_CA_CN, O=ROOT_CA_ORGANIZATION" \
    --key-algorithm="KEY_ALGORITHM" \
    --max-chain-length=1 \
    --location=REGION \
    --project=CA_PROJECT_ID \
    --auto-enable

Substitua:

  • ROOT_CA_ID: um nome exclusivo para a CA raiz. O nome da CA pode ter até 64 caracteres e precisa conter apenas caracteres alfanuméricos minúsculos e maiúsculos, sublinhados ou hifens. O nome da AC precisa ser exclusivo na região.
  • ROOT_CA_POOL_ID: o ID do pool de ACs raiz.
  • ROOT_CA_CN: o nome comum da CA raiz
  • ROOT_CA_ORGANIZATION: a organização da CA raiz.
  • KEY_ALGORITHM: o algoritmo da chave, por exemplo, ec-p256-sha256
  • REGION: a região em que o pool de ACs raiz está localizado.
  • CA_PROJECT_ID: o ID do projeto em que você criou a CA raiz.

Para mais informações sobre os campos subject da AC, consulte Assunto.

Se quiser, crie outras CAs raiz no pool de CAs raiz. Isso pode ser útil para rotação de CA raiz.

Configurar CAs subordinadas

Também é possível configurar CAs subordinadas. A configuração de CAs subordinadas pode ajudar com o seguinte:

  • Vários cenários de emissão de certificados: se você tiver vários cenários de emissão de certificados, crie uma CA subordinada para cada um deles.

  • Melhor balanceamento de carga: adicionar várias ACs subordinadas a um pool de ACs ajuda você a conseguir um melhor balanceamento de carga das solicitações de certificado.

Para criar um pool de CA subordinada e uma CA subordinada, faça o seguinte:

  1. Crie o pool de CA subordinada no nível DevOps, que se destina à emissão de certificados de alto volume e curta duração.

    gcloud privateca pools create SUBORDINATE_CA_POOL_ID \
        --location=REGION \
        --project=CA_PROJECT_ID \
        --tier=devops
    

    Substitua:

    • SUBORDINATE_CA_POOL_ID: um ID exclusivo para o pool de ACs subordinadas. O ID pode ter até 64 caracteres e precisa conter apenas caracteres alfanuméricos minúsculos e maiúsculos, sublinhados ou hifens. O ID do pool precisa ser exclusivo na região.
    • REGION: a região em que o pool de AC subordinada será criado.
    • CA_PROJECT_ID: o ID do projeto em que você criou a CA subordinada.

    Para mais informações, consulte Como criar pools de AC.

  2. Crie uma CA subordinada no pool de CA subordinada. Não altere o modo de emissão baseado em configuração padrão.

    gcloud privateca subordinates create SUBORDINATE_CA_ID \
        --pool=SUBORDINATE_CA_POOL_ID \
        --location=REGION \
        --issuer-pool=ROOT_CA_POOL_ID \
        --issuer-location=REGION \
        --subject="CN=SUBORDINATE_CA_CN, O=SUBORDINATE_CA_ORGANIZATION" \
        --key-algorithm="KEY_ALGORITHM" \
        --use-preset-profile=subordinate_mtls_pathlen_0 \
        --project=CA_PROJECT_ID \
        --auto-enable
    

    Substitua:

    • SUBORDINATE_CA_ID: um nome exclusivo para a CA subordinada. O nome pode ter até 64 caracteres e precisa conter apenas caracteres alfanuméricos minúsculos e maiúsculos, sublinhados ou hifens. O nome do pool precisa ser exclusivo na região.
    • SUBORDINATE_CA_POOL_ID: o nome do pool de CAs subordinadas.
    • REGION: a região em que o pool de ACs subordinadas está localizado.
    • ROOT_CA_POOL_ID: o ID do pool de ACs raiz.
    • REGION: a região do pool de ACs raiz.
    • SUBORDINATE_CA_CN: o nome comum da CA subordinada.
    • SUBORDINATE_CA_ORGANIZATION: o nome da organização emissora de CA subordinada.
    • KEY_ALGORITHM: o algoritmo da chave, por exemplo, ec-p256-sha256
    • CA_PROJECT_ID: o ID do projeto em que você criou a CA subordinada.

    Para mais informações sobre os campos subject da AC, consulte Assunto.

Criar um arquivo de configuração de emissão de certificado

Para vincular ACs a pools de identidades de carga de trabalho, elas precisam ter uma configuração de emissão de certificados. Se você precisar que suas cargas de trabalho sejam autenticadas em vários domínios de confiança, também poderá atualizar o pool com configurações de confiança.

Para configurar a configuração de emissão de certificado, crie um arquivo de configuração de emissão de certificado. O formato do arquivo é semelhante a este:

{
  "inlineCertificateIssuanceConfig": {
      "caPools": {
        "REGION1": "projects/CA_PROJECT_NUMBER1/locations/REGION1/caPools/SUBORDINATE_CA_POOL_ID1",
        "REGION2": "projects/CA_PROJECT_NUMBER2/locations/REGION2/caPools/SUBORDINATE_CA_POOL_ID2"
      },
      "lifetime": "DURATION",
      "rotationWindowPercentage": ROTATION_WINDOW_PERCENTAGE,
      "keyAlgorithm": "ALGORITHM"
  }
}

Substitua:

  • REGION: as regiões em que as CAs estão localizadas.

  • CA_PROJECT_NUMBER: o número do projeto em que você criou o pool de ACs subordinadas. Para receber o número do projeto do projeto CA_PROJECT_ID, execute o seguinte comando:

    gcloud projects describe CA_PROJECT_ID --format="value(projectNumber)"
    
  • SUBORDINATE_CA_POOL_ID: o nome do pool de CAs subordinadas.

  • ALGORITHM: opcional. O algoritmo de criptografia usado para gerar a chave privada. Os valores válidos são ECDSA_P256 (padrão), ECDSA_P384, RSA_2048, RSA_3072 e RSA_4096.

  • DURATION: opcional. A duração da validade do certificado folha, em segundos. O valor precisa estar entre 86400 (1 dia) e 2592000 (30 dias). Se não for especificado, o valor padrão de 86400 (1 dia) será usado. A validade real do certificado emitido também depende da CA emissora, porque isso pode restringir a vida útil do certificado emitido.

  • ROTATION_WINDOW_PERCENTAGE (opcional): a porcentagem do ciclo de vida do certificado em que uma renovação é acionada. O valor precisa estar entre 50 e 80. O padrão é 50.

Criar o arquivo de configuração de confiança

Por padrão, as cargas de trabalho no mesmo domínio de confiança podem se autenticar mutuamente usando identidades gerenciadas de carga de trabalho. Se você quiser que cargas de trabalho em domínios de confiança diferentes se autentiquem mutuamente, declare explicitamente a relação de confiança no pool de identidades de carga de trabalho. Para isso, crie um arquivo de configuração de confiança que contenha um inlineTrustConfig que forneça certificados para cada domínio.

O arquivo de configuração de confiança contém um conjunto de âncoras de confiança que a identidade gerenciada da carga de trabalho usa para validar certificados de peering. O arquivo de configuração de confiança mapeia o domínio de confiança SPIFFE para certificados de CA.

Para criar o arquivo de configuração de confiança, faça o seguinte:

  1. Faça o download dos certificados.

    gcloud privateca pools get-ca-certs ROOT_CA_POOL_ID \
        --output-file=CERTIFICATE_PATH \
        --location=REGION
    

    Substitua:

    • ROOT_CA_POOL_ID: o ID do pool de ACs raiz
    • CERTIFICATE_PATH: o caminho para a saída do certificado codificado em PEM.
    • REGION: a região do pool de ACs raiz

  2. Crie um arquivo chamado que contenha sua configuração de confiança inline, com certificados no formato PEM. O arquivo é semelhante a este:
    {
      "inlineTrustConfig": {
        "additionalTrustBundles": {
          "TRUST_DOMAIN_NAME1": {
            "trustAnchors": [
              {
                  "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL1\n-----END CERTIFICATE-----"
              },
              {
                  "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL2\n-----END CERTIFICATE-----"
              }
            ]
          },
          "TRUSTED_DOMAIN_NAME2": {
            "trustAnchors": [
              {
                  "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL3\n-----END CERTIFICATE-----"
              },
              {
                  "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL4\n-----END CERTIFICATE-----"
              }
            ]
          }
        }
      }
    }
    

    Substitua:

    • TRUST_DOMAIN_NAME: o nome do domínio de confiança, formatado da seguinte maneira:
      PROJECT_ID.svc.id.goog
      
    • CERTIFICATE_MATERIAL: um conjunto de certificados de CA formatados em PEM confiáveis para emitir certificados no domínio de confiança.

Vincular as CAs ao pool de identidades da carga de trabalho

Depois de criar a hierarquia de ACs e as configurações de emissão de certificados para cada AC, vincule as ACs ao pool de identidades da carga de trabalho. Para vincular uma AC ao pool de identidades da carga de trabalho, atualize o pool com a configuração de emissão de certificado da AC. Em seguida, verifique se o pool foi atualizado.

Atualizar o pool de identidades da carga de trabalho

Para atualizar o pool, execute o seguinte comando:

gcloud iam workload-identity-pools update TRUST_DOMAIN_NAME \
    --location="global" \
    --inline-certificate-issuance-config-file=CIC_JSON_FILE_PATH \
    --inline-trust-config-file=TC_JSON_FILE_PATH \
    --project=PROJECT_ID

Substitua:

  • TRUST_DOMAIN_NAME: o nome do domínio de confiança, formatado da seguinte maneira:

    PROJECT_ID.svc.id.goog
    
  • CIC_JSON_FILE_PATH: o caminho para o arquivo de configuração de emissão de certificado no formato JSON (cic.json) que você criou anteriormente.

  • TC_JSON_FILE_PATH: opcional. O caminho para o arquivo de configuração de confiança formatado em JSON (tc.json) que você criou anteriormente. Se as cargas de trabalho forem autenticadas em diferentes domínios de confiança, especifique esse arquivo. Caso contrário, omita --inline-trust-config.

Verificar se o pool de identidades da carga de trabalho foi atualizado

Para verificar se o pool de identidades de carga de trabalho foi atualizado com a configuração de emissão de certificado e a configuração de confiança, execute o seguinte comando:

gcloud iam workload-identity-pools describe TRUST_DOMAIN_NAME \
    --location="global" \
    --project=PROJECT_ID

Substitua TRUST_DOMAIN_NAME pelo nome do domínio de confiança que você usou para atualizar o pool de identidades de carga de trabalho anteriormente neste documento.

A resposta ao comando será assim:

inlineCertificateIssuanceConfig:
    caPools:
      REGION1: projects/PROJECT_NUMBER1/locations/REGION1/caPools/SUBORDINATE_CA_POOL_ID1,
      REGION2: projects/PROJECT_NUMBER2/locations/REGION2/caPools/SUBORDINATE_CA_POOL_ID2
    keyAlgorithm: ALGORITHM
    lifetime: DURATION
    rotationWindowPercentage: ROTATION_WINDOW_PERCENTAGE
inlineTrustConfig:
    additionalTrustBundles:
      example.com:
          trustAnchors:
          - pemCertificate: |-
            -----BEGIN CERTIFICATE-----
            CERTIFICATE_MATERIAL1
            -----END CERTIFICATE-----
          - pemCertificate: |-
            -----BEGIN CERTIFICATE-----
            CERTIFICATE_MATERIAL2
            -----END CERTIFICATE-----
      myorg.com:
          trustAnchors:
          - pemCertificate: |-
            -----BEGIN CERTIFICATE-----
            CERTIFICATE_MATERIAL3
            -----END CERTIFICATE-----
          - pemCertificate: |-
            -----BEGIN CERTIFICATE-----
            CERTIFICATE_MATERIAL4
            -----END CERTIFICATE-----
name: PROJECT_ID.svc.id.goog
state: ACTIVE

Se inlineCertificateIssuanceConfig ou inlineTrustConfig não estiverem presentes na resposta ao comando, verifique se você configurou corretamente a CLI gcloud para usar o projeto certo para faturamento e cota. Talvez seja necessário atualizar para uma versão mais recente da CLI gcloud.

Autorizar que identidades das cargas de trabalho gerenciadas solicitem certificados do pool de ACs

Depois de vincular as ACs ao pool de identidades da carga de trabalho, você precisa autorizar as identidades de carga de trabalho gerenciadas a solicitar certificados do pool de ACs. Para autorizar essas identidades, faça o seguinte:

  1. Conceda o papel do IAM de Solicitante de certificado da carga de trabalho de serviço de CA (roles/privateca.workloadCertificateRequester) em cada pool de CA subordinada ao domínio de confiança. O comando gcloud privateca pools add-iam-policy-binding a seguir autoriza o domínio de confiança a solicitar certificados das cadeias de certificados do CA Service.

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_ID \
        --location=REGION \
        --role=roles/privateca.workloadCertificateRequester \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/name/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog" \
        --project=CA_PROJECT_ID
    

    Substitua:

    • SUBORDINATE_CA_POOL_ID: o ID do pool de AC subordinada.
    • REGION: a região do pool de AC subordinada.
    • PROJECT_NUMBER: o número do projeto que contém o pool de identidades da carga de trabalho do GKE.

      Para receber PROJECT_NUMBER de PROJECT_ID, execute o seguinte comando:

      gcloud projects describe PROJECT_ID --format="value(projectNumber)"
      
    • PROJECT_ID: o ID do projeto host da frota do GKE.

    • CA_PROJECT_ID: o ID do projeto em que você criou a CA subordinada.

  2. Conceda o papel de Leitor do pool de serviços da CA (roles/privateca.poolReader) nos pools de CAs subordinadas à identidade da carga de trabalho gerenciada. Isso autoriza a identidade da carga de trabalho gerenciada a receber os certificados X.509 assinados das cadeias de certificados da AC.

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_ID \
        --location=REGION \
        --role=roles/privateca.poolReader \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/name/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog" \
        --project=CA_PROJECT_ID
    

    Substitua:

    • SUBORDINATE_CA_POOL_ID: o ID do pool de ACs subordinadas.
    • REGION: a região do pool de AC subordinada.
    • PROJECT_NUMBER: o número do projeto que contém o pool de identidades da carga de trabalho do GKE.
    • PROJECT_ID: o ID do projeto host da frota do GKE.
    • CA_PROJECT_ID: o ID do projeto em que você criou a CA subordinada.

Implantar cargas de trabalho com identidades de carga de trabalho gerenciadas

Depois de configurar os pools de AC para emitir certificados para identidades de carga de trabalho gerenciadas, você pode implantar cargas de trabalho que tenham identidades de carga de trabalho gerenciadas.

Nesta seção, mostramos como implantar uma carga de trabalho de teste com uma identidade de carga de trabalho gerenciada. Para fazer isso, implante um pod, verifique se as credenciais foram geradas e confira o certificado e o ID do SPIFFE.

Implantar um pod

Para implantar um pod de teste no cluster, faça o seguinte:

  1. Consiga as credenciais do cluster.

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CLUSTER_ZONE \
        --project=CLUSTER_PROJECT_ID
    
  2. Crie o namespace do Kubernetes.

    kubectl create namespace KUBERNETES_NAMESPACE
    
  3. Implante um PodSpec de teste.

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      namespace: KUBERNETES_NAMESPACE
      name: example-pod
    spec:
      containers:
      - name: main
        image: debian
        command: ['sleep', 'infinity']
        volumeMounts:
        - name: fleet-spiffe-credentials
          mountPath: /var/run/secrets/workload-spiffe-credentials
          readOnly: true
      nodeSelector:
        iam.gke.io/gke-metadata-server-enabled: "true"
      volumes:
      - name: fleet-spiffe-credentials
        csi:
          driver: podcertificate.gke.io
          volumeAttributes:
            signerName: spiffe.gke.io/fleet-svid
            trustDomain: fleet-project/svc.id.goog
    EOF
    

Listar as credenciais da carga de trabalho

Para listar as credenciais da carga de trabalho, execute o seguinte comando. A criação das credenciais pode levar alguns minutos.

kubectl exec -it example-pod -n KUBERNETES_NAMESPACE -- ls  /var/run/secrets/workload-spiffe-credentials

Você verá esta resposta:

ca_certificates.pem
certificates.pem
private_key.pem
trust_bundles.json

Ver o certificado

Para conferir o certificado, faça o seguinte:

  1. Exporte o certificado para um arquivo.

    kubectl exec -it example-pod --namespace=KUBERNETES_NAMESPACE -- cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -noout -text > certfile
    
  2. Confira o arquivo do certificado.

    cat certfile
    

    No certificado, no atributo X509v3 Subject Alternative Name, você encontra o ID SPIFFE, com o seguinte formato: spiffe://PROJECT_ID.svc.id.goog/ns/KUBERNETES_NAMESPACE/sa/default

    default se refere à conta de serviço padrão do Kubernetes.

Testar a autenticação de carga de trabalho para carga de trabalho

Para testar a autenticação de carga de trabalho para carga de trabalho, consulte Testar a autenticação mTLS usando Go.

O código de exemplo no repositório cria cargas de trabalho de cliente e servidor. É possível testar a autenticação mútua entre as cargas de trabalho usando os certificados gerados anteriormente neste documento.

A seguir