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


En este instructivo, 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 implementar aplicaciones y administrar recursos en un clúster de GKE privado. Este instructivo está dirigido a los administradores de plataformas, los administradores de clústeres y los desarrolladores. Se supone que estás familiarizado con GKE, Cloud Build, OpenID Connect y la herramienta de línea de comandos de gcloud.

Los grupos privados de Cloud Build y los planos de control del clúster de GKE se ejecutan en redes de nube privada virtual (VPC) que son propiedad de Google. Estas redes de VPC intercambian tráfico con tu propia red de VPC en Google Cloud. Sin embargo, el intercambio de tráfico entre redes de VPC no admite el intercambio de tráfico transitivo, que puede ser una restricción cuando usas grupos privados de Cloud Build. En este instructivo, se presenta una solución que usa Identity Service para GKE con el fin de permitir que los trabajadores de un grupo privado de Cloud Build accedan al plano de control de un clúster de GKE privado.

Descripción general de la arquitectura

Identity Service para GKE es un proxy de autenticación para los planos de control del clúster de GKE. Utiliza proxies las solicitudes al servidor de la API y valida los tokens de ID que emiten los proveedores de identidad de OpenID Connect (OIDC). Cuando el proxy valida correctamente un token de Id., agrega encabezados HTTP sobre suplantación de identidad del 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 actuar en nombre de usuarios y grupos.

El servicio de identidad para el proxy de 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 el servicio de identidad para GKE está habilitado en un clúster privado, el instalador agrega una anotación al servicio de Kubernetes a fin de aprovisionar un balanceador de cargas de red de transferencia interno. Se puede acceder al proxy a través del balanceador de cargas a través de una conexión de intercambio de tráfico entre redes de VPC, como un grupo privado de Cloud Build, ya que el proxy se ejecuta en los nodos del clúster de tu red de VPC.

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

En resumen, esta solución permite el acceso al plano de control del clúster de GKE privado mediante el proxy de Identity Service para 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 intercambio de tráfico entre 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 de Service Account Credentials.

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

Accede a clústeres de GKE privados con Identity Service para GKE

En esta solución, toda la comunicació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 Identity and Access Management (IAM) que se otorgan a las cuentas de usuario y las cuentas de servicio de Google no se aplican cuando estas se autentican con Identity Service para GKE. En su lugar, usa el control de acceso basado en roles (RBAC) de Kubernetes para administrar los permisos del clúster para estas cuentas.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. Instala Google Cloud CLI.
  3. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  4. Crea o selecciona un proyecto de Google Cloud.

    • Crea un proyecto de Google Cloud:

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el proyecto de Google Cloud que estás creando.

    • Selecciona el proyecto de Google Cloud que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre del proyecto de Google Cloud.

  5. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  6. Habilita las APIs de 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. Instala Google Cloud CLI.
  8. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  9. Crea o selecciona un proyecto de Google Cloud.

    • Crea un proyecto de Google Cloud:

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el proyecto de Google Cloud que estás creando.

    • Selecciona el proyecto de Google Cloud que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre del proyecto de Google Cloud.

  10. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  11. Habilita las APIs de 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

Crea un clúster de GKE privado

  1. En Cloud Shell, crea un clúster de GKE que no tenga acceso de cliente al extremo público del plano de control y que tenga instalado Identity Service for 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_PANE_CIDR \
      --network NETWORK\
      --release-channel regular \
      --scopes cloud-platform \
      --subnetwork SUBNET \
      --tags NODE_TAGS \
      --workload-pool PROJECT_ID.svc.id.goog \
      --zone ZONE
    

    Reemplaza lo siguiente:

    • CLUSTER: el nombre del clúster En este instructivo, usa private-cluster
    • CONTROL_PANE_CIDR: Es el rango de direcciones IP del plano de control. Debe tener un prefijo /28. Para este instructivo, puedes usar 172.16.0.32/28.
    • NETWORK: Es la red de VPC a la que se conecta el plano de control. En este instructivo, usa default
    • SUBNET: Es 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 que especifica NETWORK. En este instructivo, usa default.
    • NODE_TAGS: Es una lista separada por comas de etiquetas de red que se aplicarán a los nodos. En este instructivo, usa private-cluster-node.
    • PROJECT_ID: Es el ID de tu proyecto de Google Cloud.
    • ZONE: Es la zona del clúster de GKE. En este instructivo, usa us-central1-f.

    Ten en cuenta lo siguiente sobre el comando:

    • La marca --enable-identity-service habilita el servicio de identidad para GKE en el clúster. En tu propio entorno, puedes habilitar Identity Service para GKE en un clúster existente.

    • La marca --enable-private-endpoint configura el plano de control para que sea accesible solo 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 el acceso al servidor de la API solo desde las redes privadas especificadas por la marca --network.

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

  2. Agrega una regla de firewall que permita que el plano de control del clúster de GKE se conecte al webhook de admisión de validación para los 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
    

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

Registra el servicio de identidad para GKE como una aplicación cliente de OAuth 2.0

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

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

    Abre la página Credenciales.

  2. Haz clic en Crear credenciales.

  3. Selecciona ID de cliente de OAuth.

    Si aún no se configuró la pantalla de consentimiento para el proyecto de Google Cloud, haz clic en Configurar pantalla de consentimiento. Sigue la documentación sobre cómo configurar la pantalla de consentimiento. Para este instructivo, configura los siguientes valores:

    • El tipo de usuario puede ser Interno o Externo. Para este instructivo, puedes seleccionar Interno.
    • Los valores para Nombre de la app, Correo electrónico de asistencia del usuario e Información de contacto del desarrollador son obligatorios y pueden tener cualquier valor.
    • No necesitas agregar ningún permiso para este instructivo.

    Cuando hayas terminado de configurar la pantalla de consentimiento, haz clic en Volver al panel y, luego, vuelve a comenzar desde el paso 1 del procedimiento actual.

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

  5. En el campo Nombre, ingresa un nombre para el ID de cliente. En este instructivo, 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 debajo de tu directorio principal llamado cloud-build-private-pools-gke-tutorial y, luego, ve a ese directorio:

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

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

    Reemplaza 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 de sub (sujeto). El uso de este identificador opaco en las vinculaciones de roles dificulta la identificación del sujeto de una vinculación de rol. Por lo tanto, este parche configura el servicio de identidad para que GKE use la reclamación de correo electrónico de los tokens de ID a fin de identificar usuarios, en lugar de usar la reclamación secundaria predeterminada.

    • El alcance del correo electrónico se agrega para que los tokens de ID emitidos incluyan la reclamación por correo electrónico.

    • Los campos cloudConsoleRedirectURI, extraParams, kubectlRedirectURI y permisos se usan cuando los desarrolladores se autentican en el clúster con Identity Service para 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 con el proveedor de identidad configurado. El valor '-' significa que no hay prefijos.

    • El campo spec.authentication es un array. Puedes usar varios proveedores de identidad de OpenID Connect con Identity Service para GKE. Por ejemplo, puedes usar Google como el proveedor de identidad para autenticar las cuentas de servicio de Google y un proveedor de identidad diferente para autenticar a los desarrolladores.

    Si deseas obtener más información sobre los campos de esta configuración, consulta Usa proveedores de identidad externos para autenticar en GKE.

Crea una cuenta de servicio de Google a fin de configurar Identity Service para 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"
    

    Reemplaza ISG_GSA por el nombre que deseas usar para la cuenta de servicio de Google. En este instructivo, usa identity-service-for-gke

    Debes asignar esta cuenta de servicio de Google a una instancia de VM de Compute Engine a fin de configurar Identity Service para el control de acceso basado en roles de Kubernetes y GKE en el clúster.

  2. Otorga la función de administrador de Kubernetes Engine en el proyecto a la cuenta de servicio de Google:

    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 de este instructivo:

    • Establece la configuración del servicio de identidad para GKE en los clústeres del proyecto.
    • Crear vinculaciones de roles y vinculaciones de roles del clúster en el clúster

Configura Identity Service para GKE

Si quieres configurar Identity Service para GKE, debes tener acceso al plano de control del clúster. En este instructivo, 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, usa la redirección de TCP con Identity-Aware Proxy (IAP). Esta función habilita el acceso SSH sin necesidad de que la instancia de VM tenga una dirección IP pública.

  1. En Cloud Shell, crea una regla de firewall 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 rango de origen contiene las direcciones IP que IAP usa para el reenvío de TCP.

  2. Crea una instancia de VM de Compute Engine en la misma red de 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
    

    Reemplaza VM por el nombre que deseas usar para la instancia de VM. En este instructivo, usa identity-service-for-gke-configuration

    Ten en cuenta lo siguiente sobre el comando anterior:

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

    • El permiso cloud-platform es obligatorio para acceder a la API de credenciales de la cuenta de servicio.

    • El permiso userinfo-email es útil cuando se crea una instancia de VM para administrar el control de acceso basado en roles de Kubernetes. Es opcional para este instructivo.

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

    • El valor de metadatos de la instancia enable-oslogin opcional habilita el Acceso al SO en la instancia de VM. El Acceso al SO permite la administración del acceso SSH a instancias de VM con la IAM.

  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 le indica a gcloud que haga un túnel 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 de SSH.

  5. Instala la herramienta de línea de comandos de kubectl y el objeto 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 con parche y almacénalo 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 con parche y almacénalo en un archivo llamado server.txt:

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

    exit
    

Verifica la configuración del clúster (opcional)

Antes de continuar, puedes verificar que Identity Service para GKE se configuró correctamente en el clúster. Verifica la configuración con la cuenta de servicio de Google adjunta a la instancia de VM para autenticarte en el clúster mediante Identity Service for GKE.

  1. En Cloud Shell, otorga a la cuenta de servicio OpenID Connect Identity Token Creator de la cuenta de servicio de Google a la 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
    

    Esta función proporciona el permiso iam.serviceAccounts.getOpenIdToken que se necesita a fin de solicitar tokens de ID para la cuenta de servicio desde la API de 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 de SSH.

  3. Solicita un token de acceso de OAuth 2.0 del servidor de metadatos para la cuenta de servicio de Google conectada a la instancia de VM. Para ello, usa el ID de cliente de OAuth como la reclamación solicitada de aud (público):

    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 intercalada para extraer el campo access_token del cuerpo de la respuesta.

  4. Solicita un token de ID a la API de Service Account Credentials para la cuenta de servicio de Google que está conectada 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 en el cuerpo JSON de la solicitud especifica la reclamación aud (público) solicitada del token de ID.
    • El token de acceso del paso anterior se usa para autenticarse en la API.
  5. Ve las reclamaciones en el 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 electrónico de la cuenta de servicio de Google.

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

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

    El resultado se ve de la manera 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
    

    Se espera que surja este error. Aunque a la cuenta de servicio de Google se le otorgaron permisos de IAM en los clústeres de GKE del proyecto, los permisos de IAM no se aplican cuando realizas la autenticación con Identity Service para GKE. En su lugar, debes configurar el acceso mediante el control de acceso basado en roles (RBAC) de Kubernetes.

  7. Crea una vinculación de rol de clúster que otorgue 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 de OpenID Connect de Google:

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

    Si configuras un valor userPrefix distinto de - en ClientConfig en tu propio entorno, agrega el prefijo al valor de la marca --user en este comando.

  8. Accede al clúster de GKE con Identity Service para GKE:

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

    El resultado se ve de la manera 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. Sal de la sesión de SSH:

    exit
    

Crea un contexto para la herramienta de kubectl

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

En esta sección, crearás un archivo kubeconfig que tiene un contexto. El contexto incluye detalles de conectividad del proxy de Identity Service para GKE de tu clúster. No agregues ninguna credencial de usuario al archivo kubeconfig.

  1. En Cloud Shell, copia los archivos que contienen los datos de la autoridad certificadora y la URL del servidor de la instancia de VM al directorio actual:

    gcloud compute scp VM:~/certificateAuthorityData.pem VM:~/server.txt . \
        --tunnel-through-iap --zone ZONE
    
  2. Crea un contexto y una configuración del 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 nuevo llamado kubeconfig en el directorio actual.

    Este comando usa el nombre del clúster de GKE como el nombre de la configuración del clúster para el contexto. En su propio entorno, puede usar un nombre de configuración de clúster diferente en el contexto.

  3. Establece 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. Establece el campo server en la configuración del clúster:

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

Crea 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"
    

    Reemplaza CB_GSA por el nombre que deseas usar para la cuenta de servicio de Google. En este instructivo, usa cloud-build-private-pool

  2. Otorga 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 administrada por Google.

  3. Otorga el Creador de tokens de identidad de OpenID Connect para cuentas de servicio en la cuenta de servicio de Google a la cuenta de servicio en sí:

    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
    

    Esta función proporciona el permiso iam.serviceAccounts.getOpenIdToken que se necesita a fin de solicitar tokens de ID para la cuenta de servicio desde la API de 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 de SSH.

  5. En la sesión SSH, crea una vinculación de rol de clúster de Kubernetes que otorgue 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 de 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 otorga amplios permisos en todo el clúster. En tu propio entorno, puedes usar un rol de clúster que proporcione solo los permisos necesarios para las tareas que realiza Cloud Build. También puedes usar las vinculaciones de roles para otorgar permisos solo a espacios de nombres específicos.

    Si configuras un userPrefix en ClientConfig en tu propio entorno, debes agregar ese prefijo al valor de la marca --user en este comando.

  6. Sal de la sesión de SSH:

    exit
    

Crea un grupo privado de Cloud Build

  1. En Cloud Shell, asigna un rango 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
    

    Reemplaza lo siguiente:

    • RESERVED_RANGE_NAME: Es el nombre del rango de direcciones IP asignadas que aloja el grupo privado de Cloud Build. En este instructivo, usa cloud-build-private-pool
    • RESERVED_RANGE_START_IP: Es la primera dirección IP del rango de direcciones IP asignado. En este instructivo, usa 192.168.12.0
    • RESERVED_RANGE_PREFIX_LENGTH: Es la longitud del prefijo (máscara de subred) del rango de direcciones IP asignado. La longitud del prefijo debe ser /23 o un número inferior, por ejemplo, /22 o /21. Cuanto más bajo sea el número, mayor será el rango de direcciones. Para este instructivo, usa 23 y no ingreses la / (barra) inicial.
  2. Crea una regla de firewall para permitir el tráfico entrante desde el rango de direcciones IP reservadas hacia otros recursos en 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 privada a los servicios para conectar tu red de VPC al servicio de 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 con Service Networking. La conexión privada a servicios permite que tu red de VPC se comunique con el grupo privado en el rango asignado de direcciones IP internas mediante una conexión de intercambio de tráfico entre redes de VPC.

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

    Si usas una VPC compartida en tu propio entorno, consulta Configura tu entorno a fin de obtener información sobre los pasos adicionales para crear la conexión privada a servicios.

  4. Crea un grupo privado de Cloud Build en una red de VPC de Google que realice el intercambio de tráfico 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
    

    Reemplaza lo siguiente:

    • PRIVATE_POOL_NAME: Es el nombre del grupo privado. En este instructivo, usa private-pool
    • REGION: Es la región que se usará para el grupo privado. En este instructivo, usa 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 deseas que los trabajadores del grupo privado tengan conectividad a Internet mediante direcciones IP públicas.

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

Verifica la solución

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

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

    gsutil mb -l REGION gs://PROJECT_ID-build-logs
    
  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 que especifica la sustitución _KUBECTL_CONTEXT. El valor de sustitución predeterminado es private-cluster.

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

    3. Genera un token de ID mediante la API de Service Account Credentials. La solicitud para generar el token de ID se autentica mediante el token de acceso. La reclamación aud (público) solicitada del token de ID es el ID de cliente de OAuth 2.0 especificado por la sustitución _CLIENT_ID.

    4. Enumera los servicios de Kubernetes en el espacio de nombres especificado con la sustitución _NAMESPACE. El valor de sustitución predeterminado es default. La solicitud se autentica con el token de ID que se generó en el comando anterior.

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

    • El carácter $ es el prefijo para sustituciones. $$ se usa para la expansión del parámetro Bash y la sustitución de comandos.

    • Las sustituciones _KUBECONFIG y _KUBECTL_CONTEXT habilitan diferentes archivos kubeconfig y contextos diferentes que se deben especificar cuando ejecutas una compilación. Estas sustituciones te permiten administrar varias configuraciones de clústeres mediante un solo archivo kubeconfig con varios contextos o varios archivos kubeconfig.

    • La sustitución _SERVICE_ACCOUNT no tiene un valor predeterminado. Debes proporcionar un valor para esta sustitución cuando ejecutas una compilación.

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

    • El paso de compilación usa la imagen del compilador de gcr.io/google.com/cloudsdktool/google-cloud-cli. Esta es una imagen de contenedor grande y toma un tiempo extraerla del registro y pasarla al trabajador de grupo privado. Para reducir el tiempo que lleva extraer la imagen del compilador, puedes crear una imagen de 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 intercaladas en los archivos de configuración de la compilación, consulta Ejecuta secuencias de comandos de Bash.

  3. Ejecuta una compilación usando 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 que se encuentran en el directorio actual a Cloud Storage para que los use Cloud Build. En el paso de compilación, se 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 conectó al plano de control del clúster mediante el proxy de autenticación de Identity Service para GKE.

Soluciona problemas

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

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

Si recibes el mensaje Error from server (NotFound): clientconfigs.authentication.gke.io "default" not found cuando aplicas el parche al ClientConfig predeterminado en el clúster de GKE, asegúrate de haber creado la regla de firewall como se describe en la sección Crea un clúster de GKE privado. Verifica que la regla de firewall exista:

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

Si no puedes autenticarte en el proxy de Identity Service para GKE, busca errores en los registros de los Pods en 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 instructivo, te recomendamos que revises estos documentos:

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

    Borra un proyecto de Google Cloud:

    gcloud projects delete PROJECT_ID

Borra recursos

Si quieres conservar el proyecto que usaste en este instructivo, borra los recursos individuales:

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

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

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

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

    gsutil rm -r gs://PROJECT_ID-build-logs
    
  5. Borra el clúster de GKE:

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

    gcloud compute instances delete VM --zone ZONE --quiet
    
  7. Borra las reglas 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. Quita las vinculaciones de rol de 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. Borra 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
    

Borra el ID de cliente de OAuth 2.0

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

    Abre la página Credenciales.

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

  3. En la tabla de ID de cliente de OAuth 2.0, busca la fila de Identity Service para GKE y, luego, haz clic en el ícono de Borrar cliente de OAuth.

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

¿Qué sigue?