Acesse clusters particulares do Google Kubernetes Engine em pools particulares do Cloud Build usando o Identity Service para GKE


Neste tutorial, descrevemos como acessar o plano de controle de um cluster particular do Google Kubernetes Engine (GKE) usando pools particulares do Cloud Build. Com esse acesso, é possível usar o Cloud Build para implantar aplicativos e gerenciar recursos em um cluster particular do GKE. Este tutorial é destinado a administradores de plataformas, administradores de cluster e desenvolvedores. Ele pressupõe que você conheça o GKE, o Cloud Build, o OpenID Connect e a ferramenta de linha de comando gcloud.

Os pools particulares do Cloud Build e os planos de controle dos clusters do GKE são executados em redes de nuvem privada virtual (VPC) do Google. Essas redes VPC são conectadas por peering à sua própria rede VPC no Google Cloud. No entanto, o peering de rede VPC não é compatível com peering transitivo, o que pode ser uma restrição quando você usa pools particulares do Cloud Build. Neste tutorial, apresentamos uma solução que usa o Identity Service para GKE para permitir que os workers em um pool particular do Cloud Build acessem o plano de controle de um cluster particular do GKE.

Visão geral da arquitetura

O Identity Service para GKE é um proxy de autenticação para planos de controle do cluster do GKE. Ele encaminha solicitações para o servidor da API e valida tokens de ID emitidos por provedores de identidade do OpenID Connect (OIDC). Depois que o proxy valida um token de ID, ele adiciona cabeçalhos HTTP de representação de usuário à solicitação original e a encaminha para o servidor da API. O proxy é executado como uma conta de serviço do Kubernetes com permissões para representar usuários e grupos.

O serviço de identidade do proxy do GKE é executado como pods nos nós do cluster. Um serviço do Kubernetes do tipo LoadBalancer expõe o proxy fora do cluster. Se o serviço de identidade para GKE estiver ativado em um cluster particular, o instalador adicionará uma anotação ao serviço do Kubernetes para provisionar um balanceador de carga de rede de passagem interno. O proxy pode ser acessado pelo balanceador de carga por uma conexão de peering de rede VPC, como de um pool particular do Cloud Build, porque ele é executado nos nós do cluster da rede VPC.

É possível configurar o Google como um provedor de identidade do OpenID Connect no serviço de identidade para GKE porque o sistema de autenticação do OAuth 2.0 do Google está em conformidade com a especificação do OpenID Connect. Para receber tokens de ID para uma conta de serviço do Google, use o método generateIdToken da API Service Account Credentials. Os tokens de ID são emitidos e assinados pelo Google.

Juntando tudo, esta solução permite o acesso ao plano de controle particular do cluster do GKE usando o proxy do serviço de identidade para GKE. Os builds executados em um pool particular do Cloud Build se conectam ao proxy por uma conexão de peering de rede VPC. O build em execução no pool particular do Cloud Build é executado como uma conta de serviço do Google. Essa conta de serviço do Google pode receber um token de ID para autenticar no proxy da API Service Account Credentials.

O diagrama a seguir mostra a arquitetura descrita no texto anterior:

Acesse clusters particulares do GKE usando o serviço de identidade para GKE

Toda a comunicação nesta solução ocorre pelo espaço de endereço IP interno. Os workers no pool particular não precisam de conectividade pública com a Internet.

As permissões do Identity and Access Management (IAM) concedidas a contas de usuário e de serviço do Google não se aplicam quando elas são autenticadas usando o serviço de identidade para GKE. Em vez disso, use o controle de acesso baseado em papéis (RBAC, na sigla em inglês) do Kubernetes para gerenciar as permissões de cluster dessas contas.

Antes de começar

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. Instale a CLI do Google Cloud.
  3. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  4. Crie ou selecione um projeto do Google Cloud.

    • Crie um projeto do Google Cloud:

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto do Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud.

  5. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  6. Ative as APIs Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs:

    gcloud services enable cloudbuild.googleapis.com container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com
  7. Instale a CLI do Google Cloud.
  8. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  9. Crie ou selecione um projeto do Google Cloud.

    • Crie um projeto do Google Cloud:

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto do Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud.

  10. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  11. Ative as APIs Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs:

    gcloud services enable cloudbuild.googleapis.com container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com

Criar um cluster do GKE particular

  1. No Cloud Shell, crie um cluster do GKE que não tenha acesso de cliente ao endpoint público do plano de controle e que tenha o serviço de identidade para GKE instalado:

    gcloud container clusters create CLUSTER  \
      --enable-identity-service \
      --enable-ip-alias \
      --enable-master-authorized-networks \
      --enable-private-endpoint \
      --enable-private-nodes \
      --master-ipv4-cidr CONTROL_PANE_CIDR \
      --network NETWORK\
      --release-channel regular \
      --scopes cloud-platform \
      --subnetwork SUBNET \
      --tags NODE_TAGS \
      --workload-pool PROJECT_ID.svc.id.goog \
      --zone ZONE
    

    Substitua:

    • CLUSTER: o nome do cluster. Neste tutorial, use private-cluster.
    • CONTROL_PANE_CIDR: o intervalo de endereços IP do plano de controle. Ele precisa ter um prefixo /28. Neste tutorial, use 172.16.0.32/28.
    • NETWORK: a rede VPC a que o plano de controle se conecta. Neste tutorial, use default.
    • SUBNET: a sub-rede a que o plano de controle do cluster do GKE se conecta. A sub-rede precisa pertencer à rede VPC especificada por NETWORK. Neste tutorial, use default.
    • NODE_TAGS: uma lista separada por vírgulas de tags de rede para aplicar aos nós. Neste tutorial, use private-cluster-node.
    • PROJECT_ID: é seu ID do projeto no Google Cloud.
    • ZONE: a zona do cluster do GKE. Neste tutorial, use us-central1-f.

    Observe o seguinte sobre o comando:

    • A sinalização --enable-identity-service ativa o serviço de identidade para GKE no cluster. No seu próprio ambiente, é possível ativar o serviço de identidade para GKE em um cluster atual.

    • A flag --enable-private-endpoint configura o plano de controle para ser acessível apenas usando endereços IP internos.

    • A sinalização --enable-private-nodes configura os nós do cluster para ter apenas endereços IP internos.

    • As sinalizações --enable-master-authorized-networks e --enable-private-nodes só permitem o acesso ao servidor da API pelas redes privadas especificadas pela sinalização --network.

    • A sinalização --workload-pool opcional ativa a Identidade da carga de trabalho. Ele não é necessário para este tutorial.

  2. Adicione uma regra de firewall que permita que o plano de controle do cluster do GKE se conecte ao webhook de admissão de validação para recursos do ClientConfig:

    gcloud compute firewall-rules create allow-control-plane-clientconfig-webhook \
      --allow tcp:15000 \
      --network NETWORK\
      --source-ranges CONTROL_PANE_CIDR\
      --target-tags NODE_TAGS
    

    ClientConfig é um tipo de recurso personalizado (CRD, na sigla em inglês) do Kubernetes que o Identity Service para GKE usa para configurar como interagir com provedores de identidade.

Registrar o serviço de identidade para GKE como um aplicativo cliente OAuth 2.0

Nesta seção, você vai registrar o serviço de identidade do GKE como um aplicativo cliente usando o sistema de autenticação OAuth 2.0 do Google.

  1. Abra a página Credenciais no Console do Google Cloud.

    Abra a página Credenciais

  2. Clique em Criar credenciais.

  3. Selecione ID do cliente OAuth.

    Se a tela de consentimento ainda não tiver sido configurada para o projeto do Google Cloud, clique em Configurar tela de consentimento. Siga a documentação sobre como configurar a tela de consentimento. Para este tutorial, defina os seguintes valores:

    • O Tipo de usuário pode ser Interno ou Externo. Para este tutorial, selecione Interno.
    • Os valores de Nome do app, E-mail de suporte do usuário e Dados de contato do desenvolvedor são obrigatórios e podem ter qualquer valor.
    • Não é preciso adicionar escopos neste tutorial.

    Quando terminar de configurar a tela de permissão, clique em "Voltar ao painel de controle" e comece novamente a partir da etapa 1 do procedimento atual.

  4. Na lista Tipo de aplicativo, selecione Aplicativo da Web.

  5. Insira um nome no campo Nome para o ID do cliente. Neste tutorial, use Identity Service for GKE.

  6. Clique em Criar.

    Uma caixa de diálogo será exibida. Copie o valor de Seu ID de cliente. Você vai precisar dele mais adiante neste procedimento.

  7. Clique em OK para fechar a caixa de diálogo.

  8. No Cloud Shell, crie um diretório abaixo do seu diretório principal chamado cloud-build-private-pools-gke-tutorial e acesse esse diretório:

    mkdir -p ~/cloud-build-private-pools-gke-tutorial cd ~/cloud-build-private-pools-gke-tutorial

  9. No novo diretório, crie um arquivo YAML chamado client-config-patch.yaml que tenha valores que serão necessários mais tarde para corrigir o recurso do serviço de identidade para GKE ClientConfig:

    cat << EOF > client-config-patch.yaml
    spec:
      authentication:
      - name: google-oidc
        oidc:
          clientID: CLIENT_ID
          cloudConsoleRedirectURI: https://console.cloud.google.com/kubernetes/oidc
          extraParams: prompt=consent,access_type=offline
          issuerURI: https://accounts.google.com
          kubectlRedirectURI: http://localhost:10000/callback
          scopes: email
          userClaim: email
          userPrefix: '-'
    EOF
    

    Substitua CLIENT_ID pelo ID do cliente OAuth da etapa anterior.

    Observe o seguinte sobre o patch:

    • Os tokens de ID emitidos pelo sistema de autenticação OAuth 2.0 do Google contêm um identificador numérico exclusivo na declaração de sub (assunto). O uso desse identificador opaco em vinculações de papéis dificulta a identificação do assunto de uma vinculação de papel. Portanto, esse patch configura o serviço de identidade do GKE para usar a declaração de e-mail dos tokens de ID e identificar usuários, em vez de usar a subdeclaração padrão.

    • O escopo do e-mail é adicionado para que os tokens de ID emitidos incluam a declaração de e-mail.

    • Os campos cloudConsoleRedirectURI, extraParams, kubectlRedirectURI e escopos são usados quando os desenvolvedores fazem a autenticação no cluster usando o serviço de identidade para GKE. Eles não são usados quando as contas de serviço do Google são autenticadas no cluster. O campo kubectlRedirectURI é obrigatório.

    • O campo userPrefix é um prefixo para usuários que fazem a autenticação usando o provedor de identidade configurado. O valor '-' significa que não há prefixo.

    • O campo spec.authentication é uma matriz. É possível usar vários provedores de identidade do OpenID Connect com o serviço de identidade para GKE. Por exemplo, é possível usar o Google como o provedor de identidade para autenticar as contas de serviço do Google e outro para autenticar os desenvolvedores.

    Para mais informações sobre os campos dessa configuração, acesse Usar provedores de identidade externos para autenticar no GKE.

Criar uma conta de serviço do Google para configurar o serviço de identidade para GKE

  1. No Cloud Shell, crie uma conta de serviço do Google:

    gcloud iam service-accounts create ISG_GSA \
      --display-name "Configure Identity Service for GKE"
    

    Substitua ISG_GSA pelo nome que você quer usar para a conta de serviço do Google. Neste tutorial, use identity-service-for-gke.

    Atribua essa conta de serviço do Google a uma instância de VM do Compute Engine para configurar o Identity Service para GKE e o controle de acesso baseado em papéis do Kubernetes no cluster.

  2. Conceda o papel de administrador do Kubernetes Engine no projeto à conta de serviço do Google:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
      --role roles/container.admin
    

    Esse papel concede as permissões necessárias para realizar as seguintes tarefas neste tutorial:

    • Definir as configurações do serviço de identidade para GKE nos clusters do projeto.
    • Criar vinculações de papéis e vinculações de papéis do cluster no cluster.

Configurar o serviço de identidade para o GKE

Para configurar o serviço de identidade para GKE, você precisa ter acesso ao plano de controle do cluster. Neste tutorial, você cria uma instância de VM do Compute Engine para acessar o plano de controle.

Você precisa ter acesso SSH à instância de VM. Para ativar o acesso SSH autenticado e autorizado de fora da rede VPC para a instância de VM, use o encaminhamento de TCP com o Identity-Aware Proxy (IAP). Esse recurso permite o acesso SSH sem exigir que a instância de VM tenha um endereço IP público.

  1. No Cloud Shell, crie uma regra de firewall que permita o acesso SSH usando o encaminhamento de TCP do IAP para todas as instâncias de VM que tenham a tag de rede ssh-iap:

    gcloud compute firewall-rules create allow-ssh-ingress-from-iap \
      --allow tcp:22 \
      --description "Allow SSH tunneling using Identity-Aware Proxy" \
      --network NETWORK \
      --source-ranges 35.235.240.0/20 \
      --target-tags ssh-iap
    

    O intervalo de origem contém os endereços IP que o IAP usa para encaminhamento de TCP.

  2. Crie uma instância de VM do Compute Engine na mesma rede VPC que o cluster do GKE:

    gcloud compute instances create VM \
      --metadata enable-oslogin=TRUE \
      --network NETWORK \
      --no-address \
      --scopes cloud-platform,userinfo-email \
      --service-account ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
      --subnet SUBNET  \
      --tags ssh-iap \
      --zone ZONE
    

    Substitua VM pelo nome que você quer usar para a instância de VM. Neste tutorial, use identity-service-for-gke-configuration.

    Observe o seguinte sobre o comando acima:

    • A sinalização --service-account anexa a conta de serviço do Google à instância de VM.

    • O escopo cloud-platform é necessário para acessar a API Service Account Credentials.

    • O escopo userinfo-email é útil ao criar uma instância de VM para gerenciar o controle de acesso baseado em papéis do Kubernetes. Isso é opcional para este tutorial.

    • A sinalização --no-address significa que a instância de VM é criada sem um endereço IP externo.

    • O valor de metadados da instância enable-oslogin opcional ativa o Login do SO na instância de VM. O Login do SO permite gerenciar o acesso SSH às instâncias de VM usando o IAM.

  3. Copie o arquivo de patch ClientConfig na instância de VM:

    gcloud compute scp client-config-patch.yaml VM:~ --tunnel-through-iap --zone ZONE
    

    A sinalização --tunnel-through-iap instrui gcloud a encapsular a conexão por meio do IAP.

  4. Conecte-se à instância de VM usando o SSH.

    gcloud compute ssh VM --tunnel-through-iap --zone ZONE
    

    Você vai executar o restante dos comandos desta seção na sessão SSH.

  5. Instale a ferramenta de linha de comando kubectl e o binário gke-gcloud-auth-plugin na instância de VM:

    sudo apt-get install -y kubectl google-cloud-sdk-gke-gcloud-auth-plugin
    
  6. Busque as credenciais para o cluster do GKE:

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    gcloud container clusters get-credentials CLUSTER --zone ZONE
    
  7. Aplique um patch no recurso ClientConfig padrão:

    kubectl patch clientconfig default \
        --namespace kube-public \
        --patch-file client-config-patch.yaml \
        --type merge
    
  8. Extraia o campo certificateAuthorityData do recurso ClientConfig padrão com patch e armazene-o em um arquivo chamado certificateAuthorityData.pem:

    kubectl get clientconfig default \
         --namespace kube-public \
         --output jsonpath='{.spec.certificateAuthorityData}' \
         | base64 --decode > certificateAuthorityData.pem
    
  9. Extraia o campo de servidor do recurso ClientConfig padrão com patch e armazene-o em um arquivo chamado server.txt:

    kubectl get clientconfig default \
         --namespace kube-public \
         --output jsonpath='{.spec.server}' > server.txt
    
  10. Saia da sessão SSH:

    exit
    

(Opcional) Verificar a configuração do cluster

Antes de continuar, verifique se o serviço de identidade para GKE foi configurado corretamente no cluster. Verifique a configuração usando a conta de serviço do Google anexada à instância de VM para autenticar no cluster usando o serviço de identidade para GKE.

  1. No Cloud Shell, conceda o Criador de token de identidade do OpenID Connect da conta de serviço na conta de serviço do Google à própria conta de serviço:

    gcloud iam service-accounts add-iam-policy-binding \
      ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
      --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
      --role roles/iam.serviceAccountOpenIdTokenCreator
    

    Esse papel fornece a permissão iam.serviceAccounts.getOpenIdToken necessária para solicitar tokens de ID para a conta de serviço da API Service Account Credentials.

  2. Conecte-se à instância de VM usando o SSH.

    gcloud compute ssh VM --tunnel-through-iap --zone ZONE
    

    Você vai executar o restante dos comandos desta seção na sessão SSH.

  3. Solicite um token de acesso OAuth 2.0 do servidor de metadados à conta de serviço do Google anexada à instância da VM usando o ID do cliente OAuth como a declaração aud (público-alvo) solicitada:

    ACCESS_TOKEN=$(curl --silent --header "Metadata-Flavor: Google" \
    http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token \
           | python3 -c 'import json, sys; print(json.load(sys.stdin).get("access_token"))')
    

    O corpo da resposta do servidor de metadados é um documento JSON. O comando usa um script Python inline para extrair o campo access_token do corpo da resposta.

  4. Solicite um token de ID da API Service Account Credentials para a conta de serviço do Google anexada à instância de VM:

    ID_TOKEN=$(curl --silent --request POST \
        --data '{"audience": "CLIENT_ID", "includeEmail": true}' \
        --header "Authorization: Bearer $ACCESS_TOKEN" \
        --header "Content-Type: application/json; charset=utf-8" \
    "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/ISG_GSA@PROJECT_ID.iam.gserviceaccount.com:generateIdToken" \
           | python3 -c 'import json, sys; print(json.load(sys.stdin).get("token"))')
    

    Observe o seguinte sobre o comando acima:

    • O campo audience no JSON do corpo da solicitação especifica a declaração aud (público-alvo) solicitada do token de ID.
    • O token de acesso da etapa anterior é usado para autenticação na API.
  5. Veja as declarações no token de ID:

    echo $ID_TOKEN \
        | cut -d. -f2 \
        | base64 --decode --ignore-garbage 2> /dev/null \
        | python3 -m json.tool
    

    Verifique se a declaração email contém o endereço de e-mail da conta de serviço do Google.

  6. Use o token de ID para autenticar no plano de controle usando o serviço de identidade para GKE:

    kubectl get namespaces \
        --certificate-authority certificateAuthorityData.pem \
        --server $(cat server.txt) \
        --token $ID_TOKEN
    

    A saída será assim:

      Error from server (Forbidden): namespaces is forbidden: User "ISG_GSA@PROJECT_ID.iam.gserviceaccount.com" cannot list resource "namespaces" in API group "" at the cluster scope
    

    É esperado que você o receba. Embora a conta de serviço do Google tenha recebido permissões do IAM nos clusters do GKE do projeto, as permissões do IAM não se aplicam quando você faz a autenticação usando o serviço de identidade para GKE. Em vez disso, configure o acesso usando o controle de acesso baseado em papéis (RBAC) do Kubernetes.

  7. Crie uma vinculação de papel de cluster que atribua o papel de cluster view à conta de serviço do Google quando a conta de serviço for autenticada no cluster usando o provedor OpenID Connect do Google:

    kubectl create clusterrolebinding ISG_GSA-cluster-view \
        --clusterrole view \
        --user ISG_GSA@PROJECT_ID.iam.gserviceaccount.com
    

    Se você definir um valor userPrefix diferente de - no ClientConfig no seu próprio ambiente, adicione o prefixo ao valor da sinalização --user nesse comando.

  8. Acesse o cluster do GKE usando o serviço de identidade para GKE:

    kubectl get namespaces \
        --certificate-authority certificateAuthorityData.pem \
        --server $(cat server.txt) \
        --token $ID_TOKEN
    

    A saída será assim:

    NAME                      STATUS   AGE
    anthos-identity-service   Active   1h
    default                   Active   1h
    kube-node-lease           Active   1h
    kube-public               Active   1h
    kube-system               Active   1h
    
  9. Saia da sessão SSH:

    exit
    

Criar um contexto para a ferramenta kubectl

O comando kubectl pode usar um arquivo kubeconfig (em inglês) para configurar o acesso a clusters. Um arquivo kubeconfig contém um ou mais contextos. Cada contexto tem um nome e, opcionalmente, inclui informações de conectividade do cluster, credenciais usadas para autenticar no cluster e um namespace padrão.

Nesta seção, você vai criar um arquivo kubeconfig que tenha um contexto. O contexto inclui detalhes de conectividade do proxy do Identity Service para GKE do cluster. Nenhuma credencial de usuário é adicionada ao arquivo kubeconfig.

  1. No Cloud Shell, copie os arquivos que contêm os dados da autoridade de certificação e o URL do servidor da instância de VM para o diretório atual:

    gcloud compute scp VM:~/certificateAuthorityData.pem VM:~/server.txt . \
        --tunnel-through-iap --zone ZONE
    
  2. Crie um contexto e uma configuração de cluster que você vai usar mais tarde para se conectar ao cluster do GKE pelo Cloud Build:

    kubectl config set-context private-cluster \
        --cluster private-cluster \
        --kubeconfig kubeconfig
    

    A sinalização --kubeconfig cria o contexto e a configuração do cluster em um novo arquivo chamado kubeconfig no diretório atual.

    Esse comando usa o nome do cluster do GKE como o nome da configuração do cluster para o contexto. No seu ambiente, é possível usar um nome de configuração de cluster diferente no contexto.

  3. Defina o campo certificateAuthorityData na configuração do cluster:

    kubectl config set-cluster private-cluster \
        --certificate-authority certificateAuthorityData.pem \
        --embed-certs \
        --kubeconfig kubeconfig
    
  4. Defina o campo server na configuração do cluster:

    kubectl config set-cluster private-cluster \
        --kubeconfig kubeconfig \
        --server $(cat server.txt)
    

Criar uma conta de serviço do Google para o Cloud Build

  1. No Cloud Shell, crie uma conta de serviço do Google para executar builds no pool particular do Cloud Build:

    gcloud iam service-accounts create CB_GSA \
      --description "Runs builds on Cloud Build private pools" \
      --display-name "Cloud Build private pool"
    

    Substitua CB_GSA pelo nome que você quer usar para a conta de serviço do Google. Neste tutorial, use cloud-build-private-pool.

  2. Conceda o papel de conta de serviço do Cloud Build no projeto à conta de serviço do Google:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/cloudbuild.builds.builder
    

    Esse papel fornece as permissões padrão da conta de serviço do Cloud Build gerenciada pelo Google.

  3. Conceda o Criador de token de identidade do OpenID Connect da conta de serviço na conta de serviço do Google à própria conta de serviço:

    gcloud iam service-accounts add-iam-policy-binding \
        CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.serviceAccountOpenIdTokenCreator
    

    Esse papel fornece a permissão iam.serviceAccounts.getOpenIdToken necessária para solicitar tokens de ID para a conta de serviço da API Service Account Credentials.

  4. Conecte-se à instância de VM usando o SSH.

    gcloud compute ssh VM --tunnel-through-iap --zone ZONE
    

    Você vai executar o restante dos comandos desta seção na sessão SSH.

  5. Na sessão SSH, crie uma vinculação de papel de cluster do Kubernetes que conceda o papel de cluster cluster-admin à conta de serviço do Google quando a conta de serviço for autenticada no cluster usando o provedor OpenID Connect do Google:

    kubectl create clusterrolebinding CB_GSA-cluster-admin \
        --clusterrole cluster-admin \
        --user CB_GSA@PROJECT_ID.iam.gserviceaccount.com
    

    O papel de cluster cluster-admin concede permissões abrangentes em todo o cluster. No seu ambiente, é possível usar um papel de cluster que conceda apenas as permissões necessárias para as tarefas executadas pelo Cloud Build. Também é possível usar vinculações de papéis para conceder permissões somente a namespaces específicos.

    Se você definir um userPrefix no ClientConfig no seu próprio ambiente, será preciso adicionar esse prefixo ao valor da sinalização --user nesse comando.

  6. Saia da sessão SSH:

    exit
    

Criar um pool particular do Cloud Build

  1. No Cloud Shell, aloque um intervalo de endereços IP na rede VPC para a conexão com o pool particular:

    gcloud compute addresses create RESERVED_RANGE_NAME \
    --addresses RESERVED_RANGE_START_IP\
        --description "Cloud Build private pool reserved range" \
        --global \
        --network NETWORK \
        --prefix-length RESERVED_RANGE_PREFIX_LENGTH \
        --purpose VPC_PEERING
    

    Substitua:

    • RESERVED_RANGE_NAME: o nome do intervalo de endereços IP alocado que hospeda o pool particular do Cloud Build. Neste tutorial, use cloud-build-private-pool.
    • RESERVED_RANGE_START_IP: o primeiro endereço IP do intervalo de endereços IP alocado. Neste tutorial, use 192.168.12.0.
    • RESERVED_RANGE_PREFIX_LENGTH: o tamanho do prefixo (máscara de sub-rede) do intervalo de endereços IP alocado. O comprimento do prefixo precisa ser /23 ou um número menor, por exemplo, /22 ou /21. Um número menor significa um intervalo de endereços maior. Neste tutorial, use 23 e não insira a / (barra).
  2. Crie uma regra de firewall para permitir o tráfego de entrada do intervalo de endereços IP reservado para outros recursos na rede VPC:

    gcloud compute firewall-rules create allow-private-pools-ingress \
        --allow all \
        --network NETWORK \
        --source-ranges RESERVED_RANGE_START_IP/RESERVED_RANGE_PREFIX_LENGTH
    
  3. Crie uma conexão de serviço particular para conectar sua rede VPC ao serviço Service Networking:

    gcloud services vpc-peerings connect \
        --network NETWORK \
        --ranges RESERVED_RANGE_NAME \
        --service servicenetworking.googleapis.com
    

    Os pools particulares do Cloud Build executam workers usando a rede de serviços. A conexão de serviço particular permite que sua rede VPC se comunique com o pool privado no intervalo alocado de endereços IP internos usando uma conexão de peering de rede VPC.

    A criação da conexão de serviço particular pode levar alguns minutos.

    Se você usa uma VPC compartilhada no seu ambiente, confira Configurar seu ambiente para conferir outras etapas de criação da conexão de serviço particular.

  4. Crie um pool particular do Cloud Build em uma rede VPC de propriedade do Google que faça peering com sua rede VPC:

    gcloud builds worker-pools create PRIVATE_POOL_NAME \
       --no-public-egress \
       --peered-network projects/PROJECT_ID/global/networks/NETWORK \
       --region REGION
    

    Substitua:

    • PRIVATE_POOL_NAME: o nome do pool particular. Neste tutorial, use private-pool.
    • REGION: a região a ser usada no pool particular. Neste tutorial, use us-central1.

    A sinalização --no-public-egress significa que os workers no pool particular não têm endereços IP públicos. No seu ambiente, remova essa sinalização se quiser que os workers no pool particular tenham conectividade com a Internet usando endereços IP públicos.

    Para informações sobre outras opções de configuração, como tipo de máquina e tamanho do disco para os workers no pool particular, consulte Criar e gerenciar pools particulares.

Verificar a solução

Nesta seção, você verifica a solução executando um build no pool particular do Cloud Build. A versão acessa o cluster particular do GKE.

  1. No Cloud Shell, crie um bucket do Cloud Storage para armazenar registros de build do Cloud Build:

    gsutil mb -l REGION gs://PROJECT_ID-build-logs
    
  2. Crie um arquivo de configuração de build para o Cloud Build:

    cat << "EOF" > cloudbuild.yaml
    steps:
    - id: list-services
      name: gcr.io/google.com/cloudsdktool/google-cloud-cli
      entrypoint: bash
      args:
      - -eEuo
      - pipefail
      - -c
      - |-
        kubectl config use-context $_KUBECTL_CONTEXT
    
        ACCESS_TOKEN=$$(curl --silent \
            --header "Metadata-Flavor: Google" \
            http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token \
            | python3 -c 'import json, sys; print(json.load(sys.stdin).get("access_token"))')
    
        ID_TOKEN=$$(curl --silent --request POST \
            --data '{"audience": "CLIENT_ID", "includeEmail": true}' \
            --header "Authorization: Bearer $$ACCESS_TOKEN" \
            --header "Content-Type: application/json; charset=utf-8" \
            "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$_SERVICE_ACCOUNT:generateIdToken" \
            | python3 -c 'import json, sys; print(json.load(sys.stdin).get("token"))')
    
        kubectl get services --namespace $_NAMESPACE --token $$ID_TOKEN
    
    logsBucket: gs://PROJECT_ID-build-logs
    
    options:
      env:
      - KUBECONFIG=/workspace/$_KUBECONFIG
    
    substitutions:
      _KUBECONFIG: kubeconfig
      _KUBECTL_CONTEXT: private-cluster
      _NAMESPACE: default
    
    serviceAccount: projects/$PROJECT_ID/serviceAccounts/$_SERVICE_ACCOUNT
    EOF
    

    A etapa no arquivo de configuração do build faz o seguinte:

    1. Alterna para o contexto kubectl que é especificado pela substituição _KUBECTL_CONTEXT. O valor de substituição padrão é private-cluster.

    2. Recupera um token de acesso do servidor de metadados. O token de acesso é emitido para a conta de serviço do Google que executa o build.

    3. Gera um token de ID usando a API Service Account Credentials. A solicitação para gerar o token de ID é autenticada com o token de acesso. A declaração aud (público-alvo) solicitada do token de ID é o ID do cliente OAuth 2.0 especificado pela substituição _CLIENT_ID.

    4. Lista os serviços do Kubernetes no namespace especificado pela substituição _NAMESPACE. O valor de substituição padrão é default. A solicitação é autenticada com o token de ID gerado no comando anterior.

    Observe o seguinte sobre o arquivo de configuração do build:

    • O caractere $ é o prefixo para substituições. $$ é usado para expansão de parâmetro bash e substituição de comando.

    • As substituições _KUBECONFIG e _KUBECTL_CONTEXT permitem que arquivos kubeconfig diferentes e contextos distintos sejam especificados ao executar um build. Essas substituições permitem gerenciar várias configurações de cluster usando um único arquivo kubeconfig com vários contextos ou vários arquivos kubeconfig.

    • A substituição _SERVICE_ACCOUNT não tem um valor padrão. Forneça um valor para essa substituição ao executar um build.

    • O bloco options define a variável de ambiente KUBECONFIG para todas as etapas do build.

    • A etapa de criação usa a imagem do builder gcr.io/google.com/cloudsdktool/google-cloud-cli. Essa é uma imagem de contêiner grande e leva algum tempo para extraí-la do registro para o worker do pool particular. Para reduzir o tempo necessário para extrair a imagem do builder, crie uma imagem personalizada que contenha apenas as ferramentas necessárias para a etapa de build, como curl, kubectl e Python.

    Para saber mais sobre scripts de shell inline em arquivos de configuração do build, consulte Como executar scripts bash.

  3. Execute um build usando o arquivo de configuração e os arquivos do diretório atual:

    gcloud builds submit \
        --config cloudbuild.yaml \
        --region REGION \
        --substitutions _SERVICE_ACCOUNT=CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --worker-pool projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_NAME
    

    O comando faz upload de todos os arquivos que estão no diretório atual para o Cloud Storage para uso do Cloud Build. A etapa de build usa o arquivo kubeconfig para se conectar ao cluster do GKE.

    Próximo ao final da saída, aparecem linhas semelhantes a estas:

    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP   2h
    

    Esta saída mostra que o worker do pool particular se conectou ao plano de controle do cluster usando o proxy de autenticação do serviço de identidade para GKE.

Solução de problemas

Se não for possível se conectar à instância de VM usando SSH, adicione a sinalização --troubleshoot para ajudar a descobrir a causa dos problemas de conectividade:

gcloud compute ssh VM --tunnel-through-iap --zone ZONE --troubleshoot

Se você receber a mensagem Error from server (NotFound): clientconfigs.authentication.gke.io "default" not found ao corrigir o ClientConfig padrão no cluster do GKE, verifique se criou a regra de firewall conforme descrito na seção Como criar um cluster particular do GKE. Verifique se ela existe:

gcloud compute firewall-rules describe allow-control-plane-clientconfig-webhook

Se não for possível autenticar o serviço de identidade para o proxy do GKE, procure erros nos registros dos pods na implantação gke-oidc-service:

gcloud compute ssh VM --tunnel-through-iap --zone ZONE --command \
    'kubectl logs deployment/gke-oidc-service \
         --namespace anthos-identity-service --all-containers'

Se você tiver outros problemas neste tutorial, recomendamos que consulte estes documentos:

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Excluir o projeto

    Exclua um projeto do Google Cloud:

    gcloud projects delete PROJECT_ID

Excluir os recursos

Se você quiser manter o projeto usado neste tutorial, exclua os recursos individuais:

  1. No Cloud Shell, exclua o pool particular do Cloud Build:

    gcloud builds worker-pools delete PRIVATE_POOL_NAME --region REGION --quiet
    
  2. Exclua a conexão de serviço particular com a rede de serviços:

    gcloud services vpc-peerings delete --network NETWORK \
      --service servicenetworking.googleapis.com --quiet --async
    
  3. Exclua o intervalo de endereços IP alocado aos pools particulares do Cloud Build:

    gcloud compute addresses delete RESERVED_RANGE_NAME --global --quiet
    
  4. Exclua o bucket do Cloud Storage e todo o conteúdo dele:

    gsutil rm -r gs://PROJECT_ID-build-logs
    
  5. Exclua o cluster do GKE:

    gcloud container clusters delete CLUSTER --zone ZONE --quiet --async
    
  6. Exclua a instância de VM do Compute Engine:

    gcloud compute instances delete VM --zone ZONE --quiet
    
  7. Exclua as regras de firewall:

    gcloud compute firewall-rules delete allow-private-pools-ingress --quiet
    
    gcloud compute firewall-rules delete allow-ssh-ingress-from-iap --quiet
    
    gcloud compute firewall-rules delete allow-control-plane-clientconfig-webhook --quiet
    
  8. Remova as vinculações de papéis do IAM:

    gcloud projects remove-iam-policy-binding PROJECT_ID \
        --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/cloudbuild.builds.builder
    
    gcloud projects remove-iam-policy-binding PROJECT_ID \
        --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/container.admin
    
    gcloud iam service-accounts remove-iam-policy-binding \
        CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.serviceAccountOpenIdTokenCreator
    
    gcloud iam service-accounts remove-iam-policy-binding \
        ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.serviceAccountOpenIdTokenCreator
    
  9. Exclua as contas de serviço do Google:

    gcloud iam service-accounts delete CB_GSA@PROJECT_ID.iam.gserviceaccount.com \
       --quiet
    
    gcloud iam service-accounts delete ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \
       --quiet
    

Excluir o ID do cliente OAuth 2.0

  1. Acesse a página Credenciais no console do Google Cloud:

    Abra a página Credenciais

  2. Selecione seu projeto na lista do seletor de projetos.

  3. Na tabela de IDs do cliente OAuth 2.0, encontre a linha do Identity Service para GKE e clique no ícone Excluir cliente OAuth.

  4. Na caixa de diálogo, clique em Excluir.

A seguir