Acceder a clústeres privados de Google Kubernetes Engine desde grupos privados de Cloud Build mediante Identity Service para GKE


En este tutorial se describe cómo acceder al plano de control de un clúster privado de Google Kubernetes Engine (GKE) mediante grupos privados de Cloud Build. Este acceso te permite usar Cloud Build para desplegar aplicaciones y gestionar recursos en un clúster privado de GKE. Este tutorial está dirigido a administradores de plataformas, administradores de clústeres y desarrolladores. Se presupone que conoces GKE, Cloud Build, OpenID Connect y la herramienta de línea de comandos gcloud.

Los grupos privados de Cloud Build y los planos de control de clústeres de GKE se ejecutan en redes de nube privada virtual (VPC) propiedad de Google. Estas redes de VPC están emparejadas con tu red de VPC en Google Cloud. Sin embargo, el emparejamiento entre redes de VPC no admite el emparejamiento transitivo, lo que puede ser una restricción cuando se usan grupos privados de Cloud Build. En este tutorial se presenta una solución que usa Identity Service for GKE para permitir que los trabajadores de un grupo privado de Cloud Build accedan al plano de control de un clúster de GKE privado.

Información general sobre la arquitectura

Identity Service for GKE es un proxy de autenticación para los planos de control de clústeres de GKE. Envía solicitudes proxy al servidor de la API y valida los tokens de ID emitidos por proveedores de identidades OpenID Connect (OIDC). Una vez que el proxy valida correctamente un token de ID, añade encabezados HTTP de suplantación de identidad de usuario a la solicitud original y la reenvía al servidor de la API. El proxy se ejecuta como una cuenta de servicio de Kubernetes que tiene permisos para suplantar a usuarios y grupos.

El proxy de Identity Service for GKE se ejecuta como pods en los nodos del clúster. Un servicio de Kubernetes de tipo LoadBalancer expone el proxy fuera del clúster. Si Identity Service for GKE está habilitado en un clúster privado, el instalador añade una anotación al servicio de Kubernetes para aprovisionar un balanceador de carga de red interno de tipo pasarela. Se puede acceder al proxy a través del balanceador de carga mediante una conexión de emparejamiento entre redes VPC, como desde un grupo privado de Cloud Build, ya que el proxy se ejecuta en los nodos del clúster de tu red VPC.

Puedes configurar Google como proveedor de identidades de OpenID Connect en Identity Service para GKE porque el sistema de autenticación OAuth 2.0 de Google cumple la especificación de OpenID Connect. Para obtener tokens de ID de una cuenta de servicio de Google, puedes usar el método generateIdToken de la API de credenciales de cuentas de servicio. Google emite y firma los tokens de ID.

En conjunto, esta solución permite acceder al plano de control del clúster de GKE privado mediante el proxy de Identity Service for GKE. Las compilaciones que se ejecutan en un grupo privado de Cloud Build se conectan al proxy a través de una conexión de emparejamiento de redes de VPC. La compilación que se ejecuta en el grupo privado de Cloud Build se ejecuta como una cuenta de servicio de Google. Esta cuenta de servicio de Google puede obtener un token de ID para autenticarse en el proxy desde la API Service Account Credentials.

En el siguiente diagrama se muestra la arquitectura que se describe en el texto anterior:

Acceder a clústeres privados de GKE mediante Identity Service for GKE

Toda la comunicación de esta solución se realiza a través del espacio de direcciones IP internas. Los trabajadores del grupo privado no necesitan conectividad a Internet pública.

Los permisos de gestión de identidades y accesos (IAM) que se conceden a las cuentas de usuario y a las cuentas de servicio de Google no se aplican cuando se autentican mediante el servicio de identidad de GKE. En su lugar, puedes usar el control de acceso basado en roles (RBAC) de Kubernetes para gestionar los permisos de clúster de estas cuentas.

Antes de empezar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs APIs:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable cloudbuild.googleapis.com container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs APIs:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable cloudbuild.googleapis.com container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com
  14. Crear un clúster privado de GKE

    1. En Cloud Shell, crea un clúster de GKE que no tenga acceso de cliente al endpoint público del plano de control y que tenga instalado Identity Service para GKE:

      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_PLANE_CIDR \
        --network NETWORK\
        --release-channel regular \
        --scopes cloud-platform \
        --subnetwork SUBNET \
        --tags NODE_TAGS \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
      

      Haz los cambios siguientes:

      • CLUSTER: el nombre del clúster. En este tutorial, usaremos private-cluster.
      • CONTROL_PLANE_CIDR: el intervalo de direcciones IP del plano de control. Debe tener el prefijo /28. En este tutorial, puedes usar 172.16.0.32/28.
      • NETWORK: la red de VPC a la que se conecta el plano de control. En este tutorial, usaremos default.
      • SUBNET: la subred a la que se conecta el plano de control del clúster de GKE. La subred debe pertenecer a la red de VPC especificada por NETWORK. En este tutorial, usaremos default.
      • NODE_TAGS: lista de etiquetas de red separadas por comas que se aplicarán a los nodos. En este tutorial, usaremos private-cluster-node.
      • PROJECT_ID: tu ID de proyecto Google Cloud .
      • ZONE: la zona del clúster de GKE. En este tutorial, usaremos us-central1-f.

      Ten en cuenta lo siguiente sobre el comando:

      • La marca --enable-identity-service habilita Identity Service for GKE en el clúster. En tu propio entorno, puedes habilitar Identity Service para GKE en un clúster que ya tengas.

      • La marca --enable-private-endpoint configura el plano de control para que solo se pueda acceder a él mediante direcciones IP internas.

      • La marca --enable-private-nodes configura los nodos del clúster para que solo tengan direcciones IP internas.

      • Las marcas --enable-master-authorized-networks y --enable-private-nodes permiten acceder al servidor de la API solo desde las redes privadas especificadas por la marca --network.

      • La marca --workload-pool opcional habilita Workload Identity Federation para GKE. No es necesario para este tutorial.

    2. Añade una regla de cortafuegos que permita que el plano de control del clúster de GKE se conecte al webhook de admisión de validación de los recursos ClientConfig:

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

      ClientConfig es un tipo de recurso personalizado de Kubernetes (CRD) que Identity Service for GKE usa para configurar cómo interactuar con los proveedores de identidades.

    Registrar Identity Service for GKE como aplicación cliente de OAuth 2.0

    En esta sección, registrarás el servicio de identidad para GKE como aplicación cliente mediante el sistema de autenticación OAuth 2.0 de Google.

    1. Abre la página Credenciales en la Google Cloud consola.

      Abre la página Credenciales.

    2. Haz clic en Crear credenciales.

    3. Selecciona ID de cliente de OAuth.

      Si la pantalla de consentimiento aún no se ha configurado en el proyecto de Google Cloud, haz clic en Configurar pantalla de consentimiento. Sigue las instrucciones de la documentación sobre cómo configurar la pantalla de consentimiento. En este tutorial, defina los siguientes valores:

      • En Tipo de usuario, puedes seleccionar Interno o Externo. En este tutorial, puedes seleccionar Interno.
      • Los valores de Nombre de la aplicación, Correo de asistencia para usuarios e Información de contacto del desarrollador son obligatorios y pueden ser de cualquier tipo.
      • No es necesario que añadas ningún ámbito en este tutorial.

      Cuando hayas terminado de configurar la pantalla de consentimiento, haz clic en Back to dashboard (Volver al panel de control) y, a continuación, vuelve a empezar desde el paso 1 del procedimiento actual.

    4. En la lista Tipo de aplicación, selecciona Aplicación web.

    5. En el campo Nombre, introduce un nombre para el ID de cliente. En este tutorial, usa Identity Service for GKE.

    6. Haz clic en Crear.

      Aparecerá un cuadro de diálogo. Copia el valor de Tu ID de cliente, ya que lo necesitarás más adelante en este procedimiento.

    7. Haz clic en Aceptar para cerrar el cuadro de diálogo.

    8. En Cloud Shell, crea un directorio en tu directorio principal llamado cloud-build-private-pools-gke-tutorial y, a continuación, ve a ese directorio:

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

    9. En el nuevo directorio, crea un archivo YAML llamado client-config-patch.yaml que tenga los valores que necesites más adelante para parchear el recurso ClientConfig de Identity Service para 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
      

      Sustituye CLIENT_ID por el ID de cliente de OAuth del paso anterior.

      Ten en cuenta lo siguiente sobre el parche:

      • Los tokens de ID emitidos por el sistema de autenticación OAuth 2.0 de Google contienen un identificador numérico único en la reclamación sub (sujeto). Si se usa este identificador opaco en las vinculaciones de roles, resulta difícil identificar el asunto de una vinculación de roles. Por lo tanto, este parche configura el servicio de identidad para GKE de forma que utilice la reclamación de correo de los tokens de ID para identificar a los usuarios en lugar de usar la reclamación sub predeterminada.

      • El ámbito de correo se añade para que los tokens de ID emitidos incluyan la reclamación de correo.

      • Los campos cloudConsoleRedirectURI, extraParams, kubectlRedirectURI y scopes se usan cuando los desarrolladores se autentican en el clúster mediante el servicio de identidad de GKE. No se usan cuando las cuentas de servicio de Google se autentican en el clúster. El campo kubectlRedirectURI es obligatorio.

      • El campo userPrefix es un prefijo para los usuarios que se autentican mediante el proveedor de identidades configurado. El valor '-' significa que no hay prefijo.

      • El campo spec.authentication es una matriz. Puedes usar varios proveedores de identidades OpenID Connect con Identity Service for GKE. Por ejemplo, puedes usar Google como proveedor de identidades para autenticar cuentas de servicio de Google y otro proveedor de identidades para autenticar desarrolladores.

      Para obtener más información sobre los campos de esta configuración, consulta Usar proveedores de identidades externos para autenticar en GKE.

    Crear una cuenta de servicio de Google para configurar Identity Service for GKE

    1. En Cloud Shell, crea una cuenta de servicio de Google:

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

      Sustituye ISG_GSA por el nombre que quieras usar para la cuenta de servicio de Google. En este tutorial, usaremos identity-service-for-gke.

      Asigna esta cuenta de servicio de Google a una instancia de VM de Compute Engine para configurar el servicio de identidad de GKE y el control de acceso basado en roles de Kubernetes en el clúster.

    2. Asigna el rol Administrador de Kubernetes Engine a la cuenta de servicio de Google en el proyecto:

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

      Este rol proporciona los permisos necesarios para realizar las siguientes tareas en este tutorial:

      • Configura los ajustes de Identity Service para GKE en los clústeres del proyecto.
      • Crea enlaces de rol y enlaces de rol de clúster en el clúster.

    Configurar Identity Service for GKE

    Para configurar Identity Service para GKE, debes tener acceso al plano de control del clúster. En este tutorial, crearás una instancia de VM de Compute Engine para acceder al plano de control.

    Necesitas acceso SSH a la instancia de VM. Para habilitar el acceso SSH autenticado y autorizado desde fuera de la red de VPC a la instancia de VM, utiliza el reenvío de TCP con Identity-Aware Proxy (IAP). Esta función permite el acceso SSH sin que la instancia de VM tenga una dirección IP pública.

    1. En Cloud Shell, crea una regla de cortafuegos que permita el acceso SSH mediante el reenvío de TCP de IAP a cualquier instancia de VM que tenga la etiqueta de red 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
      

      El intervalo de origen contiene las direcciones IP que usa IAP para el reenvío de TCP.

    2. Crea una instancia de VM de Compute Engine en la misma red VPC que el clúster de 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
      

      Sustituye VM por el nombre que quieras usar para la instancia de VM. En este tutorial, usaremos identity-service-for-gke-configuration.

      Ten en cuenta lo siguiente sobre el comando anterior:

      • La marca --service-account asocia la cuenta de servicio de Google a la instancia de VM.

      • El permiso cloud-platform es obligatorio para acceder a la API Service Account Credentials.

      • El ámbito userinfo-email es útil al crear una instancia de VM para gestionar el control de acceso basado en roles de Kubernetes. Es opcional en este tutorial.

      • La marca --no-address significa que la instancia de VM se ha creado sin una dirección IP externa.

      • El valor de metadatos de instancia opcional enable-oslogin habilita Inicio de sesión con SO en la instancia de VM. OS Login permite gestionar el acceso SSH a las instancias de VM mediante la gestión de identidades y accesos.

    3. Copia el archivo de parche ClientConfig en la instancia de VM:

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

      La marca --tunnel-through-iap indica a gcloud que debe crear un túnel para la conexión a través de IAP.

    4. Conéctate a la instancia de VM mediante SSH:

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

      Ejecuta el resto de los comandos de esta sección desde la sesión SSH.

    5. Instala la herramienta de línea de comandos kubectl y el binario gke-gcloud-auth-plugin en la instancia de VM:

      sudo apt-get install -y kubectl google-cloud-sdk-gke-gcloud-auth-plugin
      
    6. Obtén las credenciales del clúster de GKE:

      export USE_GKE_GCLOUD_AUTH_PLUGIN=True
      gcloud container clusters get-credentials CLUSTER --zone ZONE
      
    7. Aplica un parche al recurso ClientConfig predeterminado:

      kubectl patch clientconfig default \
          --namespace kube-public \
          --patch-file client-config-patch.yaml \
          --type merge
      
    8. Extrae el campo certificateAuthorityData del recurso ClientConfig predeterminado parcheado y guárdalo en un archivo llamado certificateAuthorityData.pem:

      kubectl get clientconfig default \
           --namespace kube-public \
           --output jsonpath='{.spec.certificateAuthorityData}' \
           | base64 --decode > certificateAuthorityData.pem
      
    9. Extrae el campo del servidor del recurso ClientConfig predeterminado parcheado y guárdalo en un archivo llamado server.txt:

      kubectl get clientconfig default \
           --namespace kube-public \
           --output jsonpath='{.spec.server}' > server.txt
      
    10. Cierra la sesión SSH:

      exit
      

    (Opcional) Verificar la configuración del clúster

    Antes de continuar, puedes verificar que Identity Service for GKE se haya configurado correctamente en el clúster. Para verificar la configuración, usa la cuenta de servicio de Google asociada a la instancia de VM para autenticarte en el clúster mediante Identity Service for GKE.

    1. En Cloud Shell, asigna el rol Creador de tokens de identidad OpenID Connect de cuenta de servicio de la cuenta de servicio de Google a la propia cuenta de servicio:

      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
      

      Este rol proporciona el permiso iam.serviceAccounts.getOpenIdToken, que es necesario para solicitar tokens de ID de la cuenta de servicio a la API Service Account Credentials.

    2. Conéctate a la instancia de VM mediante SSH:

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

      Ejecuta el resto de los comandos de esta sección desde la sesión SSH.

    3. Solicita un token de acceso de OAuth 2.0 al servidor de metadatos de la cuenta de servicio de Google que esté asociada a la instancia de VM. Para ello, usa el ID de cliente de OAuth como la reclamación aud (audiencia) 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"))')
      

      El cuerpo de la respuesta del servidor de metadatos es un documento JSON. El comando usa una secuencia de comandos de Python insertada para extraer el campo access_token del cuerpo de la respuesta.

    4. Solicita un token de ID a la API Service Account Credentials para la cuenta de servicio de Google que esté asociada a la instancia 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"))')
      

      Ten en cuenta lo siguiente sobre el comando anterior:

      • El campo audience del JSON del cuerpo de la solicitud especifica la reclamación aud (audiencia) solicitada del token de ID.
      • El token de acceso del paso anterior se usa para autenticar la API.
    5. Consulta las reclamaciones del token de ID:

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

      Verifica que la reclamación email contenga la dirección de correo de la cuenta de servicio de Google.

    6. Usa el token de ID para autenticarte en el plano de control mediante Identity Service for GKE:

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

      La salida es similar a la siguiente:

        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
      

      Este error es el esperado. Aunque se hayan concedido permisos de gestión de identidades y accesos a la cuenta de servicio de Google en los clústeres de GKE del proyecto, estos permisos no se aplican cuando te autenticas mediante Identity Service para GKE. En su lugar, puedes configurar el acceso mediante el control de acceso basado en roles (RBAC) de Kubernetes.

    7. Crea un enlace de rol de clúster que conceda el rol de clúster view a la cuenta de servicio de Google cuando la cuenta de servicio se autentique en el clúster mediante el proveedor OpenID Connect de Google:

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

      Si asignas un valor de userPrefix distinto de - en ClientConfig en tu propio entorno, añade el prefijo al valor de la marca --user en este comando.

    8. Accede al clúster de GKE mediante Identity Service for GKE:

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

      La salida es similar a la siguiente:

      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. Cierra la sesión SSH:

      exit
      

    Crear un contexto para la herramienta kubectl

    El comando kubectl puede usar un archivo kubeconfig para configurar el acceso a los clústeres. Un archivo kubeconfig contiene uno o varios contextos. Cada contexto tiene un nombre y, opcionalmente, incluye información de conectividad del clúster, credenciales que se usan para autenticar el clúster y un espacio de nombres predeterminado.

    En esta sección, creará un archivo kubeconfig que tenga un contexto. El contexto incluye los detalles de conectividad del proxy del servicio de identidad para GKE de tu clúster. No añades ninguna credencial de usuario al archivo kubeconfig.

    1. En Cloud Shell, copia los archivos que contienen los datos de la autoridad de certificación y la URL del servidor de la instancia de VM en el directorio actual:

      gcloud compute scp VM:~/certificateAuthorityData.pem VM:~/server.txt . \
          --tunnel-through-iap --zone ZONE
      
    2. Crea un contexto y una configuración de clúster que usarás más adelante para conectarte al clúster de GKE desde Cloud Build:

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

      La marca --kubeconfig crea el contexto y la configuración del clúster en un archivo llamado kubeconfig en el directorio actual.

      Este comando usa el nombre del clúster de GKE como nombre de configuración del clúster para el contexto. En tu propio entorno, puedes usar otro nombre de configuración de clúster en el contexto.

    3. Defina el campo certificateAuthorityData en la configuración del clúster:

      kubectl config set-cluster private-cluster \
          --certificate-authority certificateAuthorityData.pem \
          --embed-certs \
          --kubeconfig kubeconfig
      
    4. Defina el campo server en la configuración del clúster:

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

    Crear una cuenta de servicio de Google para Cloud Build

    1. En Cloud Shell, crea una cuenta de servicio de Google para ejecutar compilaciones en el grupo privado de Cloud Build:

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

      Sustituye CB_GSA por el nombre que quieras usar para la cuenta de servicio de Google. En este tutorial, usaremos cloud-build-private-pool.

    2. Asigna el rol de cuenta de servicio de Cloud Build en el proyecto a la cuenta de servicio de Google:

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

      Este rol proporciona los permisos predeterminados de la cuenta de servicio de Cloud Build gestionada por Google.

    3. Asigna el rol Creador de tokens de identidad OpenID Connect de cuenta de servicio a la cuenta de servicio de Google:

      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
      

      Este rol proporciona el permiso iam.serviceAccounts.getOpenIdToken, que es necesario para solicitar tokens de ID de la cuenta de servicio a la API Service Account Credentials.

    4. Conéctate a la instancia de VM mediante SSH:

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

      Ejecuta el resto de los comandos de esta sección desde la sesión SSH.

    5. En la sesión SSH, crea un enlace de rol de clúster de Kubernetes que conceda el rol de clúster cluster-admin a la cuenta de servicio de Google cuando la cuenta de servicio se autentique en el clúster mediante el proveedor OpenID Connect de Google:

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

      El rol de clúster cluster-admin concede permisos amplios en todo el clúster. En tu propio entorno, puedes usar un rol de clúster que solo proporcione los permisos necesarios para las tareas que realiza Cloud Build. También puedes usar enlaces de rol para conceder permisos solo a espacios de nombres específicos.

      Si define un userPrefix en ClientConfig en su propio entorno, debe añadir ese prefijo al valor de la marca --user en este comando.

    6. Cierra la sesión SSH:

      exit
      

    Crear un grupo privado de Cloud Build

    1. En Cloud Shell, asigna un intervalo de direcciones IP en tu red de VPC para la conexión con el grupo 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
      

      Haz los cambios siguientes:

      • RESERVED_RANGE_NAME: el nombre del intervalo de direcciones IP asignado que aloja el grupo privado de Cloud Build. En este tutorial, usaremos cloud-build-private-pool.
      • RESERVED_RANGE_START_IP: la primera dirección IP del intervalo de direcciones IP asignado. En este tutorial, usaremos 192.168.12.0.
      • RESERVED_RANGE_PREFIX_LENGTH: la longitud del prefijo (máscara de subred) del intervalo de direcciones IP asignado. La longitud del prefijo debe ser /23 o un número inferior, como /22 o /21. Un número más bajo significa un intervalo de direcciones más amplio. En este tutorial, usa 23 y no introduzcas la / (barra) inicial.
    2. Crea una regla de cortafuegos para permitir el tráfico entrante desde el intervalo de direcciones IP reservado a otros recursos de tu red de 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. Crea una conexión de servicio privada para conectar tu red de VPC al servicio Service Networking:

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

      Los grupos privados de Cloud Build ejecutan trabajadores mediante Service Networking. La conexión de servicio privada permite que tu red VPC se comunique con el grupo privado en el intervalo asignado de direcciones IP internas mediante una conexión de emparejamiento entre redes VPC.

      La creación de la conexión de servicio privada puede tardar unos minutos.

      Si utilizas una VPC compartida en tu entorno, consulta Configurar el entorno para obtener información sobre los pasos adicionales que debes seguir para crear la conexión de servicio privada.

    4. Crea un grupo privado de Cloud Build en una red de VPC propiedad de Google que esté emparejada con tu red de VPC:

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

      Haz los cambios siguientes:

      • PRIVATE_POOL_NAME: el nombre de la piscina privada. En este tutorial, usaremos private-pool.
      • REGION: la región que se va a usar en el grupo privado. En este tutorial, usaremos us-central1.

      La marca --no-public-egress significa que los trabajadores del grupo privado no tienen direcciones IP públicas. En tu propio entorno, puedes quitar esta marca si quieres que los trabajadores del grupo privado tengan conectividad a Internet mediante direcciones IP públicas.

      Para obtener información sobre otras opciones de configuración, como el tipo de máquina y el tamaño del disco de los trabajadores del grupo privado, consulta Crear y gestionar grupos privados.

    Verificar la solución

    En esta sección, verificará la solución ejecutando una compilación en el grupo privado de Cloud Build. La compilación accede al clúster privado de GKE.

    1. En Cloud Shell, crea un segmento de Cloud Storage para almacenar los registros de compilación de Cloud Build:

      gcloud storage buckets create gs://PROJECT_ID-build-logs --location=REGION
      
    2. Crea un archivo de configuración de compilación para 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
      

      El paso del archivo de configuración de compilación hace lo siguiente:

      1. Cambia al contexto kubectl especificado por la sustitución _KUBECTL_CONTEXT. El valor de sustitución predeterminado es private-cluster.

      2. Obtiene un token de acceso del servidor de metadatos. El token de acceso se emite a la cuenta de servicio de Google que ejecuta la compilación.

      3. Genera un token de ID mediante la API de credenciales de cuentas de servicio. La solicitud para generar el token de ID se autentica mediante el token de acceso. La reclamación aud (audiencia) solicitada del token de ID es el ID de cliente de OAuth 2.0 especificado por la sustitución _CLIENT_ID.

      4. Lista los servicios de Kubernetes del espacio de nombres especificado por la sustitución _NAMESPACE. El valor de sustitución predeterminado es default. La solicitud se autentica mediante el token de ID que se ha generado en el comando anterior.

      Ten en cuenta lo siguiente sobre el archivo de configuración de compilación:

      • El carácter $ es el prefijo de las sustituciones. $$ se usa para la expansión de parámetros bash y la sustitución de comandos.

      • Las sustituciones _KUBECONFIG y _KUBECTL_CONTEXT permiten especificar diferentes archivos kubeconfig y contextos al ejecutar una compilación. Estas sustituciones te permiten gestionar varias configuraciones de clústeres usando un solo archivo kubeconfig con varios contextos o usando varios archivos kubeconfig.

      • La sustitución _SERVICE_ACCOUNT no tiene ningún valor predeterminado. Debes proporcionar un valor para esta sustitución al ejecutar una compilación.

      • El bloque options define la variable de entorno KUBECONFIG para todos los pasos de la compilación.

      • El paso de compilación usa la imagen de compilación gcr.io/google.com/cloudsdktool/google-cloud-cli. Se trata de una imagen de contenedor grande, por lo que se tarda un tiempo en extraerla del registro al trabajador del grupo privado. Para reducir el tiempo que se tarda en extraer la imagen del compilador, puedes crear una imagen del compilador personalizada que contenga solo las herramientas necesarias para el paso de compilación, como curl, kubectl y Python.

      Para obtener más información sobre las secuencias de comandos de shell insertadas en archivos de configuración de compilación, consulta Ejecutar secuencias de comandos de bash.

    3. Ejecuta una compilación con el archivo de configuración de compilación y los archivos del directorio actual:

      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
      

      El comando sube todos los archivos del directorio actual a Cloud Storage para que los use Cloud Build. El paso de compilación usa el archivo kubeconfig para conectarse al clúster de GKE.

      Cerca del final del resultado, verás líneas similares a las siguientes:

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

      En este resultado se muestra que el trabajador del grupo privado se ha conectado al plano de control del clúster mediante el proxy de autenticación de Identity Service for GKE.

    Solución de problemas

    Si no puedes conectarte a la instancia de VM mediante SSH, añade la marca --troubleshoot para descubrir la causa de los problemas de conectividad:

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

    Si recibe el mensaje Error from server (NotFound): clientconfigs.authentication.gke.io "default" not found al parchear el ClientConfig predeterminado en el clúster de GKE, asegúrese de haber creado la regla de firewall tal como se describe en la sección Crear un clúster privado de GKE. Verifica que la regla de cortafuegos exista:

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

    Si no puedes autenticarte en el proxy de Identity Service for GKE, busca errores en los registros de los pods de la implementación 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'
    

    Si tienes otros problemas con este tutorial, te recomendamos que consultes estos documentos:

    Limpieza

    Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

    Eliminar el proyecto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Eliminar los recursos

    Si quieres conservar el proyecto que has usado en este tutorial, elimina los recursos:

    1. En Cloud Shell, elimina el grupo privado de Cloud Build:

      gcloud builds worker-pools delete PRIVATE_POOL_NAME --region REGION --quiet
      
    2. Elimina la conexión de servicio privada a Service Networking:

      gcloud services vpc-peerings delete --network NETWORK \
        --service servicenetworking.googleapis.com --quiet --async
      
    3. Elimina el intervalo de direcciones IP asignado a los grupos privados de Cloud Build:

      gcloud compute addresses delete RESERVED_RANGE_NAME --global --quiet
      
    4. Elimina el segmento de Cloud Storage y todo su contenido:

      gcloud storage rm gs://PROJECT_ID-build-logs --recursive
      
    5. Elimina el clúster de GKE:

      gcloud container clusters delete CLUSTER --zone ZONE --quiet --async
      
    6. Elimina la instancia de VM de Compute Engine:

      gcloud compute instances delete VM --zone ZONE --quiet
      
    7. Elimina las reglas de cortafuegos:

      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. Quita las vinculaciones de roles de gestión de identidades y accesos:

      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. Elimina las cuentas de servicio de 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
      

    Eliminar el ID de cliente de OAuth 2.0

    1. Ve a la página Credenciales de la Google Cloud consola:

      Abre la página Credenciales.

    2. Selecciona tu proyecto en la lista del selector de proyectos.

    3. En la tabla IDs de cliente de OAuth 2.0, busca la fila de Servicio de identidad para GKE y, a continuación, haz clic en el icono Eliminar cliente de OAuth.

    4. En el cuadro de diálogo, haz clic en Eliminar.

    Siguientes pasos