Habilitar la federación de identidades de cargas de trabajo en AKS y EKS

En este tema se explica cómo habilitar Workload Identity Federation para instalaciones híbridas de Apigee en las plataformas AKS y EKS.

Si la instalación se realiza en GKE, sigue las instrucciones de Habilitar Workload Identity en GKE.

Información general

La federación de identidades de carga de trabajo permite que las aplicaciones que se ejecutan fuera de Google Cloud suplanten la identidad de una cuenta de servicio de Google Cloud Platform mediante credenciales de un proveedor de identidades externo.

Usar la federación de identidades de carga de trabajo puede ayudarte a mejorar la seguridad, ya que permite que las aplicaciones usen los mecanismos de autenticación que proporciona el entorno externo y puede ayudarte a sustituir las claves de cuentas de servicio.

Para obtener una descripción general, consulta las prácticas recomendadas para usar la federación de identidades de cargas de trabajo.

Configurar la federación de identidades de cargas de trabajo

Para usar la federación de Workload Identity con Apigee hybrid, primero debes configurar tu clúster y, después, aplicar la función a tu instalación de Apigee hybrid.

Antes de empezar

En estas instrucciones se presupone que ya ha configurado su instalación de Apigee hybrid. Las cuentas de servicio de gestión de identidades y accesos y las cuentas de servicio de Kubernetes se crean durante la instalación inicial. Consulta Información general para ver un resumen de la instalación de Apigee hybrid.

En las instalaciones de AKS, asegúrate de haber habilitado el emisor de OpenID Connect (OIDC). Debes habilitar esta función para que la federación de identidades de carga de trabajo pueda acceder a los metadatos de OpenID Connect y al conjunto de claves web JSON (JWKS) del clúster.

Configura tu clúster para que use la federación de identidades de cargas de trabajo.

  1. Comprueba que la configuración gcloud actual se ha definido en el ID de tu proyecto de Google Cloud con el siguiente comando:
    gcloud config get project
  2. Si es necesario, define la configuración actual de gcloud:

    gcloud config set project PROJECT_ID
  3. Habilita la API Security Token Service:

    Comprueba que la API Security Token Service esté habilitada con el siguiente comando:

    gcloud services list --enabled --project PROJECT_ID | grep sts.googleapis.com

    Si la API no está habilitada:

    Consola

    Enable the Security Token Service API.

    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.

    Enable the API

    Línea de comandos

    Habilita la API con el siguiente comando:

    gcloud services enable sts.googleapis.com --project PROJECT_ID
  4. Crea el grupo de identidades de carga de trabajo y el proveedor.

    Roles obligatorios

    Para obtener los permisos que necesitas para configurar la federación de identidades de carga de trabajo, pide a tu administrador que te conceda los siguientes roles de gestión de identidades y accesos en el proyecto:

    Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

    También puedes conseguir los permisos necesarios a través de roles personalizados u otros roles predefinidos.

    También puedes usar el rol básico Propietario (roles/owner) de gestión de identidades y accesos, que incluye permisos para configurar la federación de identidades. No debes conceder roles básicos en un entorno de producción, pero sí puedes hacerlo en un entorno de desarrollo o de pruebas.

    Para crear un grupo de identidades de carga de trabajo y un proveedor, sigue estos pasos:

    1. Determina la URL de la entidad emisora de tu clúster de AKS:

      AKS

      az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv

      Haz los cambios siguientes:

      • NAME: el nombre del clúster.
      • RESOURCE_GROUP: el grupo de recursos del clúster.

      El comando muestra la URL de la entidad emisora. Necesitarás la URL del emisor en uno de los siguientes pasos.

      Si el comando no devuelve una URL de emisor, comprueba que hayas habilitado la función Emisor de OIDC.

      EKS

      aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
      

      Sustituye NAME por el nombre del clúster.

      El comando muestra la URL de la entidad emisora. Necesitarás la URL del emisor en uno de los siguientes pasos.

      Otros Kubernetes

      1. Conéctate a tu clúster de Kubernetes y usa `kubectl` para determinar la URL de la entidad emisora de tu clúster:
        kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
        

        Necesitarás la URL del emisor en uno de los siguientes pasos.

    2. Opcional: Si tu emisor de OIDC no es accesible públicamente, descarga el conjunto de claves web JSON (JWKS) del clúster:
      kubectl get --raw /openid/v1/jwks > cluster-jwks.json
      

      Para comprobar si tu proveedor de OIDC está disponible públicamente, deberías poder acceder a su URL con un comando CURL y recibir una respuesta 200.

    3. Crea un grupo de identidades de carga de trabajo:
      gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
                  

      Haz los cambios siguientes:

      • POOL_ID: ID único del grupo.
      • DISPLAY_NAME: (opcional) nombre del grupo.
      • DESCRIPTION: (Opcional) Descripción del grupo que elijas. Esta descripción aparece cuando concedes acceso a identidades de grupo.

      Por ejemplo:

      gcloud iam workload-identity-pools create my-wi-pool --display-name="My workload pool" --description="My workload pool description"
    4. Añade el clúster como proveedor de grupos de identidades de carga de trabajo. Elige el comando para crear el proveedor en función de si tu emisor de OIDC es accesible públicamente o no accesible públicamente:

      Acceso público

      Si tu emisor de OIDC es accesible públicamente, crea el proveedor con el siguiente comando:

      gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="google.subject=assertion.sub"

      No es accesible públicamente

      Si tu emisor de OIDC no es accesible públicamente, crea el proveedor con el siguiente comando:

        gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --jwks-file="cluster-jwks.json" \
        --attribute-mapping="google.subject=assertion.sub"

      Haz los cambios siguientes:

      • WORKLOAD_PROVIDER_ID: un ID de proveedor de grupos de identidades de carga de trabajo único que elijas.
      • POOL_ID: ID del grupo de identidades de carga de trabajo que has creado anteriormente.
      • ISSUER: usa la URL de la entidad emisora que has determinado anteriormente para el URI de la entidad emisora .

      attribute-mapping="google.subject=assertion.sub" asigna el asunto de Kubernetes al asunto de gestión de identidades y accesos.

Crear los archivos de configuración de credenciales

Para desplegar una carga de trabajo de Kubernetes que pueda acceder a los Google Cloud recursos, primero debes crear un archivo de configuración de credenciales para cada cuenta de servicio de gestión de identidades y accesos:

  1. Lista las cuentas de servicio de gestión de identidades y accesos (también llamadas "cuentas de servicio de Google") con el siguiente comando:
    gcloud iam service-accounts list --project PROJECT_ID

    Deberá crear los archivos de configuración de credenciales de las siguientes cuentas de servicio de gestión de identidades y accesos:

    Producción

    En entornos de producción:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-cassandra     apigee-cassandra@my_project_id.iam.gserviceaccount.com     False
    apigee-mart          apigee-mart@my_project_id.iam.gserviceaccount.com          False
    apigee-metrics       apigee-metrics@my_project_id.iam.gserviceaccount.com       False
    apigee-runtime       apigee-runtime@my_project_id.iam.gserviceaccount.com       False
    apigee-synchronizer  apigee-synchronizer@my_project_id.iam.gserviceaccount.com  False
    apigee-udca          apigee-udca@my_project_id.iam.gserviceaccount.com          False
    apigee-watcher       apigee-watcher@my_project_id.iam.gserviceaccount.com       False
    

    No producción

    En entornos que no sean de producción:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-non-prod      apigee-non-prod@my_project_id.iam.gserviceaccount.com      False
    
  2. Crea un archivo de configuración de credenciales para cada cuenta de servicio de IAM de la lista anterior. Necesitarás estos archivos de configuración de credenciales para configurar Apigee hybrid de forma que use la federación de identidades de cargas de trabajo:

    Código

    gcloud iam workload-identity-pools create-cred-config \
      projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID \
      --service-account=SERVICE_ACCOUNT_EMAIL \
      --credential-source-file=/var/
      --credential-source-type=text \
      --output-file=SERVICE_ACCOUNT_NAME-credential-configuration.json
      

    Ejemplo

    gcloud iam workload-identity-pools create-cred-config \
      projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider \
      --service-account=apigee-cassandra@myhybridporg.iam.gserviceaccount.com \
      --credential-source-file=/var/
      --credential-source-type=text \
      --output-file=apigee-cassandra-credential-configuration.json
      

    Donde:

    • PROJECT_NUMBER: número del proyecto que contiene el grupo de identidades de carga de trabajo. Debe ser el número de proyecto, no el ID de proyecto.
    • POOL_ID: el ID del grupo de identidades de carga de trabajo.
    • WORKLOAD_PROVIDER_ID: el ID del proveedor de grupos de identidades de carga de trabajo
    • SERVICE_ACCOUNT_EMAIL: dirección de correo de la cuenta de servicio, si has configurado tu cuenta de servicio de Kubernetes para usar la suplantación de identidad de la cuenta de servicio de gestión de identidades y accesos.

    El archivo de configuración de credenciales permite que las [bibliotecas de cliente de Cloud](/apis/docs/cloud-client-libraries), la CLI de gcloud y Terraform determinen lo siguiente:

    • Dónde obtener las credenciales externas
    • Qué grupo y proveedor de identidades de carga de trabajo se deben usar
    • Cuenta de servicio cuya identidad se va a usar

    Configurar Apigee hybrid para usar la federación de identidades de cargas de trabajo

    1. Copia o mueve cada archivo de salida (SERVICE_ACCOUNT_NAME-credential-configuration.json) a los siguientes directorios de gráficos (o a sus subdirectorios). Estos son los archivos que has creado en el paso Crear los archivos de configuración de las credenciales.

      Producción

      Cuenta de servicio Directorio de gráficos de Helm de Apigee
      apigee-cassandra apigee-datastore/
      apigee-mart apigee-org/
      apigee-metrics apigee-telemetry/
      apigee-runtime apigee-env/
      apigee-synchronizer apigee-env/
      apigee-udca apigee-org/
      apigee-env/
      apigee-watcher apigee-org/

      No producción

      Cuenta de servicio Gráfico de Helm de Apigee
      apigee-non-prod apigee-datastore/
      apigee-telemetry/
      apigee-org/
      apigee-env/
    2. Haz los siguientes cambios globales en el archivo de anulaciones de tu clúster:

      Código

      gcp:
        workloadIdentity:
          enabled: false # must be set to false to use Workload Identity Federation
        federatedWorkloadIdentity:
          enabled: true
          audience: "AUDIENCE"
          credentialSourceFile: "/var/run/service-account/token"
      

      Ejemplo

      gcp:
        workloadIdentity:
          enabled: false
        federatedWorkloadIdentity:
          enabled: true
          audience: "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider"
          credentialSourceFile: "/var/run/service-account/token"
      

      Donde AUDIENCE es la audiencia permitida del proveedor de identidades de carga de trabajo. Para encontrar el valor, busca el término audience: en cualquiera de los archivos de configuración de las credenciales. El valor de la audiencia es el mismo en cada archivo de configuración de credenciales.

      Por ejemplo, en el siguiente archivo apigee-udca-credential-configuration.json de muestra:

      {
        "universe_domain": "googleapis.com",
        "type": "external_account:,"
        "audience": "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider",
        "subject_token_type": "urn:ietf:params:oauth: token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "service
        "impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/apigee-udca@myhybridproject.iam.gserviceaccount.com:generateAccessToken",
        "credential_source": {
          "file": "/var/run/service-account/token",
          "format": {
            "type": "text"
          }
        }
      }

      El valor de la audiencia es //iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider.

    3. Configura las anulaciones de cada componente mediante la federación de identidades de cargas de trabajo. Selecciona las instrucciones para archivos de certificado, secretos de Kubernetes o Vault según corresponda a tu instalación.

      Archivo de certificado

      Sustituye el valor de serviceAccountPath por el archivo de origen de las credenciales de la cuenta de servicio de gestión de identidades y accesos correspondiente. Debe ser la ruta relativa al directorio del gráfico. Por ejemplo:

      envs:
      - name: ENVIRONMENT_NAME
        serviceAccountPaths:
          synchronizer: apigee-synchronizer-credential-configuration.json
          runtime: apigee-runtime-credential-configuration.json
          udca: apigee-udca-credential-configuration.json
      
      mart:
        serviceAccountPath: apigee-mart-credential-configuration.json
      
      connectAgent:
        serviceAccountPath: apigee-mart-credential-configuration.json
      
      metrics:
        serviceAccountPath: apigee-metrics-credential-configuration.json
      
      udca:
        serviceAccountPath: apigee-udca-credential-configuration.json
      
      watcher:
        serviceAccountPath: apigee-watcher-credential-configuration.json
      

      Secreto de K8s

      1. Crea un nuevo secreto de Kubernetes con el archivo de origen de las credenciales de cada archivo de configuración de credenciales.
        kubectl create secret -n APIGEE_NAMESPACE generic SECRET_NAME --from-file="client_secret.json=CREDENTIAL_CONFIGURATION_FILE"

        Por ejemplo:

        kubectl create secret -n apigee generic udca-workoad-identity-secret --from-file="client_secret.json=./apigee-udca-credential-configuration.json"
      2. Sustituye el valor de serviceAccountRef por el nuevo secreto. Por ejemplo:
        udca:
          serviceAccountRef: udca-workoad-identity-secret
        

      Vault

      Actualiza la clave de cuenta de servicio, SAKEY, de cada cuenta de servicio de Vault con el archivo de origen de credenciales correspondiente. El procedimiento es similar para todos los componentes. Por ejemplo, en el caso de UDCA:

      SAKEY=$(cat .apigee-udca-credential-configuration.json); kubectl -n APIGEE_NAMESPACE exec vault-0 -- vault kv patch secret/apigee/orgsakeys udca="$SAKEY"

      Consulta Storing service account keys in Hashicorp Vault para obtener más información.

    4. Aplica los cambios a cada componente afectado con el comando helm upgrade:

      Si has actualizado las claves de la cuenta de servicio de Vault, actualiza el gráfico apigee-operator.

      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      Actualiza el resto de los gráficos afectados en el siguiente orden:

      helm upgrade datastore apigee-datastore/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade telemetry apigee-telemetry/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade $ORG_NAME apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      Actualiza el gráfico apigee-env de cada entorno y sustituye $ENV_RELEASE_NAME y ENV_NAME cada vez:

      helm upgrade $ENV_RELEASE_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        --set env=$ENV_NAME \
        -f overrides.yaml
      

      Consulta la referencia de Helm de Apigee hybrid para ver una lista de componentes y sus gráficos correspondientes.

    Concede acceso a las cuentas de servicio de Kubernetes

    1. Lista las cuentas de servicio de Kubernetes con el siguiente comando:
      kubectl get sa -n APIGEE_NAMESPACE
    2. Concede a las cuentas de servicio de Kubernetes acceso para suplantar la identidad de las cuentas de servicio de gestión de identidades y accesos asociadas, tal como se muestra en la siguiente tabla. En la tabla se muestran los nombres de las cuentas de servicio de IAM de Apigee predeterminadas. Si usas nombres de cuentas de servicio personalizadas, utiliza las cuentas de servicio de IAM correspondientes:
      Cuentas de servicio de Kubernetes Cuenta de servicio de gestión de identidades y accesos
      Cuentas de servicio de Kubernetes a nivel de organización
      apigee-connect-agent-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-mart-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-metrics-apigee-telemetry apigee-metrics
      apigee-open-telemetry-collector-apigee-telemetry apigee-metrics
      apigee-udca-ORG_NAME-ORG_HASH_ID apigee-udca
      apigee-watcher-ORG_NAME-ORG_HASH_ID apigee-watcher
      Cuentas de servicio de Kubernetes a nivel de entorno
      apigee-runtime-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-runtime
      apigee-synchronizer-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-synchronizer
      Copia de seguridad y restauración de Cassandra (si está habilitada)
      apigee-cassandra-backup-sa apigee-cassandra
      apigee-cassandra-restore-sa apigee-cassandra

      Donde:

      • ORG_NAME: Los primeros 15 caracteres del nombre de tu organización.
      • ORG_HASH_ID: un ID hash único del nombre completo de tu organización.
      • ENV_NAME: los primeros 15 caracteres del nombre de tu entorno.
      • ENV_HASH_ID: un ID de hash único de los nombres de tu organización y tu entorno.

      Por ejemplo:

      • apigee-connect-agent-myhybridorg-123abcd
      • apigee-runtime-myhybridorg-prodenv-234bcde

      Concede a cada cuenta de servicio de Kubernetes acceso para suplantar la cuenta de servicio de gestión de identidades y accesos adecuada con el siguiente comando:

      gcloud iam service-accounts add-iam-policy-binding \
        IAM_SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \
          --role=roles/iam.workloadIdentityUser

      Donde:

      • IAM_SA_NAME: el nombre de la cuenta de servicio.
      • PROJECT_ID: el ID del proyecto asociado a la organización de Apigee.
      • PROJECT_NUMBER: el número de proyecto del proyecto en el que has creado el grupo de identidades de carga de trabajo.
      • POOL_ID: el ID del grupo de identidades de carga de trabajo.
      • MAPPED_SUBJECT: la cuenta de servicio de Kubernetes de la reclamación de tu token de ID que has asignado a google.subject. Por ejemplo, si has asignado google.subject=assertions.sub y tu token de ID contiene "sub": "system:serviceaccount:default:my-kubernetes-serviceaccount", MAPPED_SUBJECT es system:serviceaccount:default:my-kubernetes-serviceaccount.

    Para obtener más información sobre la federación de identidades de cargas de trabajo y las prácticas recomendadas, consulta el artículo Prácticas recomendadas para usar la federación de identidades de cargas de trabajo.