Usa Workload Identity con Google Cloud

En esta guía, se describe cómo configurar Identity Workload en GKE en AWS para controlar el acceso de las cargas de trabajo a los recursos de GCP. Se incluye un ejemplo de cómo acceder a los recursos de Google Cloud desde tu clúster mediante el uso de la identidad.

Si deseas obtener información sobre el uso de Workload Identity con cuentas de IAM de AWS para controlar el acceso a los recursos de AWS, consulta Usa Workload Identity con AWS.

Descripción general

Workload Identity usa permisos de Google Cloud IAM para controlar el acceso a los recursos de Google Cloud. Con Workload Identity, puedes asignar diferentes funciones de IAM a cada carga de trabajo. Este control detallado de los permisos te permite seguir el principio de privilegio mínimo. Sin Workload Identity, debes asignar roles de Google Cloud IAM a los nodos de GKE en AWS, lo que les otorga a todas las cargas de trabajo de esos nodos los mismos permisos que al nodo.

Requisitos previos

  • Crea un clúster de usuario con la versión 1.20 de Kubernetes o una posterior.

  • Si tu VPC de AWS usa un proxy o firewall, incluye las siguientes URL en la lista de entidades permitidas:

    • securetoken.googleapis.com
    • iamcredentials.googleapis.com
    • sts.googleapis.com
  • Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu clúster de usuario.

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    Reemplaza CLUSTER_NAME por el nombre de tu clúster de usuario.

  • Habilita los cuatro servicios nuevos necesarios para esta función con los siguientes comandos:

    gcloud services enable securetoken.googleapis.com
    gcloud services enable iam.googleapis.com
    gcloud services enable iamcredentials.googleapis.com
    gcloud services enable sts.googleapis.com
    

Redacta el grupo de WI y los nombres de los proveedores

Cada proyecto de Google Cloud crea de forma automática un grupo de Workload Identity administrado con un nombre en el formato PROJECT_ID.svc.id.goog. De manera similar, Google Cloud crea un proveedor de identidad cuyo nombre sigue el patrón https://gkehub.googleapis.com/projects/PROJECT_ID/locations/global/memberships/MEMBERSHIP_ID. Para obtener más información sobre los grupos de Workload Identity, consulta Componentes habilitados para la flota. Redacta estos nombres desde el ID del proyecto y el ID de la membresía como se muestra aquí:

export PROJECT_ID=USER_PROJECT_NAME
export CLUSTER_MEMBERSHIP_ID=PROJECT_MEMBERSHIP_NAME
export IDP="https://gkehub.googleapis.com/projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_MEMBERSHIP_ID}"
export WI_POOL="${PROJECT_ID}.svc.id.goog"

Reemplaza lo siguiente:

  • USER_PROJECT_NAME por el nombre de proyecto elegido por el usuario
  • PROJECT_MEMBERSHIP_NAME por el nombre de membresía del clúster

Crea una vinculación de política de IAM

Crea una vinculación de política para permitir que una cuenta de servicio de Kubernetes (KSA) actúe en nombre de una cuenta de servicio de Google Cloud (GSA).

export K8S_NAMESPACE=KUBERNETES_NAMESPACE
export KSA_NAME=KUBERNETES_SA_NAME
export GCP_SA_EMAIL="WORKLOAD_IDENTITY_TEST@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:$WI_POOL[$K8S_NAMESPACE/$KSA_NAME]" $GCP_SA_EMAIL

Reemplaza lo siguiente:

  • KUBERNETES_NAMESPACE por el espacio de nombres de Kubernetes en el que se define la cuenta de servicio de Kubernetes.
  • WORKLOAD_IDENTITY_TEST por el nombre de la carga de trabajo que elijas
  • KUBERNETES_SA_NAME por el nombre de la cuenta de servicio de Kubernetes adjunta a la aplicación

Crea un mapa de configuración del SDK

Ejecuta la siguiente secuencia de comandos de shell para almacenar los detalles de identidad de la carga de trabajo en un ConfigMap. Cuando un Pod activa el ConfigMap, Google Cloud CLI puede leer los detalles de identidad de la carga de trabajo.

cat << EOF > cfmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  namespace: ${K8S_NAMESPACE}
  name: my-cloudsdk-config
data:
  config: |
    {
      "type": "external_account",
      "audience": "identitynamespace:${WI_POOL}:${IDP}",
      "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SA_EMAIL}:generateAccessToken",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "token_url": "https://sts.googleapis.com/v1/token",
      "credential_source": {
        "file": "/var/run/secrets/tokens/gcp-ksa/token"
      }
    }
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f cfmap.yaml

Crea una cuenta de servicio de Kubernetes

Crea una KSA en el clúster de usuario con el mismo nombre y espacio de nombres que se usó en la vinculación de IAM.

cat << EOF > k8s-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ${KSA_NAME}
  namespace: ${K8S_NAMESPACE}
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f k8s-service-account.yaml

Crea un Pod

A continuación, crea un Pod con la proyección de tokens de la cuenta de servicio y el ConfigMap creado anteriormente.

  1. Crea el archivo YAML de Pod de muestra.

    cat << EOF > sample-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      namespace: ${K8S_NAMESPACE}
    spec:
      serviceAccountName: ${KSA_NAME}
      containers:
      - command:
        - /bin/bash
        - -c
        - while :; do echo '.'; sleep 500 ; done
        image: google/cloud-sdk
        name: cloud-sdk
        env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: ${WI_POOL}
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
               - key: "config"
                 path: "google-application-credentials.json"
    EOF
    
  2. Aplica el YAML del Pod a tu clúster.

    env HTTPS_PROXY=http://localhost:8118 \
     kubectl apply -f sample-pod.yaml
    

Usa Workload Identity de Google Cloud

Versiones del SDK compatibles

Si quieres usar la función de Workload Identity de Google Cloud, debes compilar el código con un SDK que lo admita. Para obtener una lista de las versiones de SDK que admiten Workload Identity de Google Cloud, consulta Workload Identity de la flota.

Código de muestra con Workload Identity

En esta sección, se incluye un código de Python de muestra que usa Workload Identity de Google Cloud. En la cuenta de servicio de este ejemplo, se usa una identidad con privilegios de “administrador de Cloud Storage” para enumerar todos los buckets de Cloud Storage del proyecto de Google Cloud.

  1. Ejecuta una shell dentro del Pod.

    env HTTPS_PROXY=http://localhost:8118 \
    kubectl exec -it sample-pod -- bash
    
  2. Ejecuta una secuencia de comandos para enumerar los buckets de almacenamiento del proyecto.

    # execute these commands inside the Pod
    pip install --upgrade google-cloud-storage
    
    cat << EOF > sample-list-bucket.py
    from google.cloud import storage
    storage_client = storage.Client()
    buckets = storage_client.list_buckets()
    
    for bucket in buckets:
      print(bucket.name)
    EOF
    
    env GOOGLE_CLOUD_PROJECT=USER_PROJECT_NAME \
     python3 sample-list-bucket.py
    

    Reemplaza USER_PROJECT_NAME con el proyecto de Google Cloud.

Más información