Acessar 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 plataforma, administradores de cluster e desenvolvedores. Ele pressupõe que você tenha familiaridade com o GKE, o Cloud Build, o OpenID Connect e o gcloud ferramenta de linha de comando.

Os pools particulares do Cloud Build e os planos de controle de cluster do GKE são executados em redes de nuvem privada virtual (VPC) do Google. Essas redes VPC fazem peering com sua própria rede VPC no Google Cloud. No entanto, o peering de rede VPC não oferece suporte ao 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 de um pool particular do Cloud Build acessem o plano de controle de um cluster particular do GKE.

Informações gerais da arquitetura

O Identity Service para GKE é um proxy de autenticação para planos de controle do cluster do GKE. Ele faz o proxy de solicitações para o servidor de API e valida os tokens de ID emitidos pelos 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 os 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 Identity Service para o 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 o 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 interna. 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 Identity Service para GKE porque o sistema de autenticação OAuth 2.0 do Google está em conformidade com a especificação do OpenID Connect. Para conseguir tokens de ID de 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, essa solução permite acesso ao plano de controle do cluster particular do GKE usando o serviço de identidade para o proxy do GKE. Os builds executados em um pool privado 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 se autenticar no proxy da API Service Account Credentials.

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

Acessar clusters particulares do GKE usando o Identity Service para GKE

Toda a comunicação na solução ocorre no espaço do endereço IP interno. Os workers do pool privado 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 fazem a autenticação usando o Identity Service 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 do cluster para essas 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, criar um cluster do GKE sem cliente acesso ao endpoint público do plano de controle e que tenha o Identity Service 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 Identity Service para GKE no cluster. No seu ambiente, é possível ativar o Identity Service para GKE em um cluster atual.

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

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

    • As sinalizações --enable-master-authorized-networks e --enable-private-nodes Permitir o acesso ao servidor da API apenas das redes privadas especificadas pela flag --network.

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

  2. Adicionar uma regra de firewall que permita ao cluster do GKE controlar para se conectar ao webhook de admissão de validação dos recursos de 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
    

    O 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 o GKE como um aplicativo cliente OAuth 2.0

Nesta seção, você vai registrar o Identity Service para 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:

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

    Quando terminar de configurar a tela de consentimento, clique em "Voltar ao painel" e comece novamente da etapa 1 do procedimento atual.

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

  5. No campo Nome, insira um nome para o ID do cliente. Para este 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 ou o procedimento anterior.

  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 o 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 que serão necessários mais tarde para corrigir o Identity Service para o recurso ClientConfig do GKE:

    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 Identity Service para GKE para usar a declaração de e-mail dos tokens de ID para identificar usuários em vez de usar a sub-reivindicação padrão.

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

    • Os campos cloudConsoleRedirectURI, extraParams, kubectlRedirectURI e escopos são usados quando os desenvolvedores fazem a autenticação no cluster usando o Identity Service para GKE. Elas não são usadas 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 com 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 Identity Service 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, consulte Usar provedores de identidade externos para se autenticar no GKE.

Criar uma conta de serviço do Google para configurar o Identity Service 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.

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

  2. Conceda ao papel Administrador do Kubernetes Engine no projeto para a 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 fornece as permissões necessárias para realizar as seguintes tarefas neste tutorial:

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

Configurar o serviço de identidade para o GKE

Para configurar o Identity Service para GKE, você precisa ter acesso ao plano de controle do cluster. Neste tutorial, você vai criar 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 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 Encaminhamento de TCP do IAP para qualquer instância de VM que tenha 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 o encaminhamento de TCP.

  2. Crie uma instância de VM do Compute Engine na mesma rede VPC que a 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 conta de serviço API 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 flag --no-address significa que a instância de VM foi criada sem um endereço IP externo.

    • O valor opcional de metadados da instância enable-oslogin 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 para a instância de VM:

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

    A flag --tunnel-through-iap instrui o gcloud a encapsular a conexão. pelo IAP.

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

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

    Execute o restante dos comandos nesta 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 do cluster do GKE:

    export USE_GKE_GCLOUD_AUTH_PLUGIN=True
    gcloud container clusters get-credentials CLUSTER --zone ZONE
    
  7. Corrija o 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 "server" do recurso ClientConfig padrão que recebeu 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 Identity Service para GKE foi configurado corretamente no cluster. Você verifica a configuração usando a conta de serviço do Google anexada à instância de VM para autenticar no cluster usando o Identity Service para GKE.

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

    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 concede a permissão iam.serviceAccounts.getOpenIdToken, que é necessária para solicitar tokens de ID da conta de serviço à API Service Account Credentials.

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

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

    Execute o restante dos comandos nesta seção na sessão SSH.

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

    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 in-line 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 reivindicação aud (público-alvo) solicitada do token de ID.
    • O token de acesso da etapa anterior é usado para autenticação na API.
  5. Confira 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 Identity Service 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 no 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, você configura o acesso usando o controle de acesso baseado em papéis (RBAC) do Kubernetes.

  7. Crie uma vinculação de papel de cluster que conceda o papel de cluster view à conta de serviço do Google quando ela 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 ambiente, adicione o prefixo ao valor da sinalização --user nesse comando.

  8. Acesse o cluster do GKE usando o Identity Service 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 para configurar o acesso aos 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 autenticação no cluster e um namespace padrão.

Nesta seção, você vai criar um arquivo kubeconfig que tem um contexto. O contexto inclui detalhes de conectividade do Identity Service para o proxy do 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 depois para se conectar ao cluster do GKE pelo Cloud Build:

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

    A flag --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, use 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 privado 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 da 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 ao criador do 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 concede a permissão iam.serviceAccounts.getOpenIdToken, que é necessária para solicitar tokens de ID da conta de serviço à API Service Account Credentials.

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

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

    Execute o restante dos comandos nesta seção na sessão SSH.

  5. Na sessão SSH, crie uma vinculação de papel do cluster do Kubernetes que conceda o papel de cluster cluster-admin à conta de serviço do Google quando ela 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 forneça apenas as permissões necessárias para as tarefas que o Cloud Build executa. 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 ambiente, será necessário adicionar esse prefixo ao valor da sinalização --user nesse comando.

  6. Saia da sessão SSH:

    exit
    

Criar um pool privado do Cloud Build

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

    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. Para este tutorial, use 23 e não insira a / (barra) à esquerda.
  2. Crie uma regra de firewall para permitir o tráfego de entrada do intervalo de endereços IP reservados para outros recursos na sua 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 do 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 o Service Networking. A conexão de serviço particular permite que a 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, consulte Configurar seu ambiente para saber mais sobre outras etapas para criar a conexão de serviço particular.

  4. Crie um pool privado do Cloud Build em uma rede VPC 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 privado. Neste tutorial, use private-pool.
    • REGION: a região a ser usada para o 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 privado 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ê vai verificar a solução executando um build no pool privado do Cloud Build. O build acessa o cluster particular do GKE.

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

    gcloud storage buckets create gs://PROJECT_ID-build-logs --location=REGION
    
  2. Crie um arquivo de configuração do 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. Muda para o contexto kubectl 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 usando o token de acesso. A reivindicaçã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 usando o token de ID que foi gerado no comando anterior.

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

    • O caractere $ é o prefixo de 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 diferentes 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 usando vários arquivos kubeconfig.

    • A substituição _SERVICE_ACCOUNT não tem um valor padrão. É necessário fornecer um valor para essa substituição ao executar um build.

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

    • A etapa de build usa a imagem do builder gcr.io/google.com/cloudsdktool/google-cloud-cli. Essa é uma imagem de contêiner grande, e pode levar algum tempo para extraí-la do registro para o worker do pool privado. Para reduzir o tempo necessário para extrair a imagem do builder, crie uma imagem personalizada com 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, serão exibidas 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 privado 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 você não conseguir 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 você 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 Identity Service 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ê encontrar outros problemas neste tutorial, recomendamos consultar estes documentos:

Limpeza

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.

Exclua 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 privado do Cloud Build:

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

    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:

    gcloud storage rm gs://PROJECT_ID-build-logs --recursive
    
  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 Serviço de identidade para o GKE e clique no ícone Excluir cliente OAuth.

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

A seguir