El 6 de abril, se lanzó una nueva versión de los clústeres de Anthos en AWS (GKE en AWS). Consulta las notas de la versión para obtener más información.

Crear un clúster de usuario con Workload Identity

Workload Identity te permite vincular cuentas de servicio de Kubernetes a cuentas de IAM de AWS con permisos específicos. En este tema, se muestra cómo habilitar Workload Identity para tus cargas de trabajo de los clústeres de Anthos en AWS (GKE en AWS).

Descripción general

Workload Identity usa permisos de IAM de AWS para bloquear el acceso no deseado a los recursos de la nube. 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 funciones de IAM de AWS a tus nodos de clústeres de Anthos en AWS. Todas las cargas de trabajo en esos nodos tienen acceso completo a los permisos del nodo.

Para habilitar Workload Identity en tu clúster, debes completar los siguientes pasos: Los pasos se separan con las siguientes personas que los completan:

Administrador del clúster

  1. Crea un bucket de Cloud Storage para almacenar datos de descubrimiento de OIDC.
  2. Crea un clúster de usuario que tenga habilitado Workload Identity.
  3. Crea un webhook en tu clúster que aplique credenciales de Workload Identity a los Pods en la creación. Si no quieres usar el webhook, puedes configurar las variables de entorno de forma manual.
  4. Configura el proveedor de OIDC de AWS.
  5. Crea políticas y funciones de IAM para AWS.
Administrador o desarrollador de clústeres
  1. Crea cuentas de servicio de Kubernetes y vincula las políticas de AWS.
Desarrollador
  1. Aplica credenciales a tus pods.

Requisitos previos

Para completar los pasos de este documento, debes tener la siguiente configuración:

  • Un servicio de administración de los clúster de Anthos en AWS
  • Clústeres de usuario que ejecutan una versión de Kubernetes superior a 1.17.9.
  • Los siguientes permisos y herramientas.

Permisos

Para crear un clúster con Workload Identity habilitado, necesitas los siguientes permisos:

Google Cloud

  • Crea un bucket de Cloud Storage legible de forma pública con el acceso uniforme a nivel de bucket habilitado.
  • Otorga permisos de lectura y escritura de management-sa@PROJECT_NAME.iam.gserviceaccount.com al bucket.

AWS

  • Crear un proveedor de OIDC de AWS
  • Crea funciones de IAM de AWS

Herramientas

En tu máquina local, te recomendamos tener la herramienta de jq instalada.

Crea el bucket de descubrimiento de OIDC

Esta sección está destinada a los administradores de clústeres.

Tu clúster de usuario debe almacenar los datos de descubrimiento de OIDC en un bucket de Cloud Storage de acceso público. El bucket incluye la configuración de descubrimiento de OIDC y claves públicas. AWS usa el contenido para autenticar solicitudes de tus clústeres de usuario.

Tu bucket debe tener los siguientes atributos:

Si no tienes un bucket con estos atributos, crea uno con los siguientes comandos de gsutil:

BUCKET=BUCKET_NAME
gsutil mb -b on gs://${BUCKET}
gsutil iam ch allUsers:objectViewer gs://${BUCKET}

Reemplaza BUCKET_NAME con el nombre de tu bucket nuevo.

Otorga permisos de cuenta de servicio de administración

La cuenta de servicio de Identity and Access Management para el servicio de administración de los clústeres de Anthos en AWS necesita permisos para leer y escribir objetos en este bucket. Otorga los permisos de tu cuenta de servicio de administración con el siguiente comando de gsutil.

MANAGEMENT_SA=management-sa@PROJECT_NAME.iam.gserviceaccount.com
gsutil iam ch serviceAccount:${MANAGEMENT_SA}:admin gs://${BUCKET}

Reemplaza PROJECT_NAME por el nombre del proyecto.

Crear un clúster de usuario

Esta sección está destinada a los administradores de clústeres.

Crea un clúster de usuario con Workload Identity habilitado

Crea un clúster de usuario que contenga detalles sobre tu bucket de descubrimiento de OIDC. Establece esta información en el campo spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket de AWSCluster.

En este ejemplo, se crea un clúster de forma manual de las CRD de AWSCluster y AWSNodePool.

  1. Cambia al directorio con la configuración de los clústeres de Anthos en AWS. Creaste este directorio cuando instalaste el servicio de administración.

    cd anthos-aws

  2. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  3. Abre un editor de texto y copia la siguiente definición de AWSCluster en un archivo llamado custom-cluster.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSCluster
    metadata:
      name: CLUSTER_NAME
    spec:
      region: AWS_REGION
      networking:
        vpcID: VPC_ID
        podAddressCIDRBlocks: POD_ADDRESS_CIDR_BLOCKS
        serviceAddressCIDRBlocks: SERVICE_ADDRESS_CIDR_BLOCKS
        ServiceLoadBalancerSubnetIDs: SERVICE_LOAD_BALANCER_SUBNETS
      controlPlane:
        version:  CLUSTER_VERSION # Latest version is 1.19.9-gke.900
        instanceType: AWS_INSTANCE_TYPE
        keyName: SSH_KEY_NAME
        subnetIDs:
        - CONTROL_PLANE_SUBNET_IDS
        securityGroupIDs:
        - CONTROL_PLANE_SECURITY_GROUPS
        iamInstanceProfile: CONTROL_PLANE_IAM_ROLE
        rootVolume:
          sizeGiB: ROOT_VOLUME_SIZE
          volumeType: ROOT_VOLUME_TYPE # Optional
          iops: ROOT_VOLUME_IOPS # Optional
          kmsKeyARN: ROOT_VOLUME_KEY # Optional
        etcd:
          mainVolume:
            sizeGiB: ETCD_VOLUME_SIZE
            volumeType: ETCD_VOLUME_TYPE # Optional
            iops: ETCD_VOLUME_IOPS # Optional
            kmsKeyARN: ETCD_VOLUME_KEY # Optional
        databaseEncryption:
          kmsKeyARN: ARN_OF_KMS_KEY
        hub: # Optional
          membershipName: ANTHOS_CONNECT_NAME
        workloadIdentity: # Optional
          oidcDiscoveryGCSBucket: WORKLOAD_IDENTITY_BUCKET
    

    Reemplaza lo siguiente:

    • CLUSTER_NAME: El nombre de tu clúster.
    • AWS_REGION: La región de AWS en la que se ejecuta tu clúster.

    • VPC_ID: El ID de la VPC en la que se ejecuta tu clúster.

    • POD_ADDRESS_CIDR_BLOCKS: El rango CIDR de las direcciones IPv4 que usan los pods del clúster. . El rango debe estar dentro del rango de direcciones CIDR de tu VPC, pero no debe ser parte de una subred. Por ejemplo, 10.2.0.0/16

    • SERVICE_ADDRESS_CIDR_BLOCKS: El rango de direcciones IPv4 que usan los Services del clúster. . El rango debe estar dentro del rango de direcciones CIDR de VPC, pero no debe ser parte de una subred. Por ejemplo, 10.1.0.0/16

    • SERVICE_LOAD_BALANCER_SUBNETS: los ID de la subred en la que los clústeres de Anthos en AWS pueden crear balanceadores de cargas públicos o privados.

    • CLUSTER_VERSION: una versión de Kubernetes compatible con los clústeres de Anthos en AWS. La versión más reciente es 1.19.9-gke.900.

    • AWS_INSTANCE_TYPE: Un tipo de instancia EC2 compatible.

    • SSH_KEY_NAME: Un par de claves de EC2 de AWS.

    • CONTROL_PLANE_SUBNET_IDS: Los ID de subred de los AZ en los que se ejecutan las instancias del plano de control.

    • CONTROL_PLANE_SECURITY_GROUPS: Es un securityGroupID creado durante la instalación del servicio de administración. Si deseas personalizar esto, agrega cualquier securityGroupID requerido para conectarte al plano de control.

    • CONTROL_PLANE_IAM_PROFILE: El nombre del perfil de la instancia de EC2 de AWS asignado para controlar las réplicas del plano.

    • ROOT_VOLUME_SIZE: El tamaño, en gibibytes (GiB), de los volúmenes raíz del plano de control.

    • ROOT_VOLUME_TYPE por el tipo de volumen de EBS. Por ejemplo, gp3.

    • ROOT_VOLUME_IOPS por la cantidad de operaciones de E/S aprovisionadas por segundo (IOPS) para el volumen. Solo es válido cuando volumeType es GP3. Para obtener más información, consulta Volúmenes de uso general SSD (gp3).

    • ROOT_VOLUME_KEY por el nombre de recurso de Amazon de la clave de AWS KMS que encripta los volúmenes raíz de la instancia del plano de control.

    • ETCD_VOLUME_SIZE: el tamaño de los volúmenes que usa etcd.

    • ETCD_VOLUME_TYPE por el tipo de volumen de EBS. Por ejemplo, gp3.

    • ETCD_VOLUME_IOPS por la cantidad de operaciones de E/S aprovisionadas por segundo (IOPS) para el volumen. Solo es válido cuando volumeType es gp3. Para obtener más información, consulta Volúmenes de uso general SSD (gp3).

    • ETCD_VOLUME_KEY por el nombre de recurso de Amazon de la clave de AWS KMS que encripta los volúmenes de datos etcd del plano de control.

    • ARN_OF_KMS_KEY: La clave de KMS de AWS que se usa para encriptar los Secrets del clúster.

    • ANTHOS_CONNECT_NAME: El nombre de la membresía de Connect que se usa para registrar tu clúster. El nombre de la membresía debe ser único. Por ejemplo, projects/YOUR_PROJECT/locations/global/memberships/CLUSTER_NAME, en el que YOUR_PROJECT es tu proyecto de Google Cloud y CLUSTER_NAME es un nombre único en tu proyecto. Este campo es opcional.

    • WORKLOAD_IDENTITY_BUCKET: El nombre del bucket de Cloud Storage que contiene la información de descubrimiento de Workload Identity. Este campo es opcional.

  4. Crea uno o más AWSNodePools para tu clúster. Abre un editor de texto y copia la siguiente definición de AWSCluster en un archivo llamado custom-nodepools.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSNodePool
    metadata:
      name: NODE_POOL_NAME
    spec:
      clusterName: AWSCLUSTER_NAME
      version:  CLUSTER_VERSION # latest version is 1.19.9-gke.900
      region: AWS_REGION
      subnetID: AWS_SUBNET_ID
      minNodeCount: MINIMUM_NODE_COUNT
      maxNodeCount: MAXIMUM_NODE_COUNT
      maxPodsPerNode: MAXIMUM_PODS_PER_NODE_COUNT
      instanceType: AWS_NODE_TYPE
      keyName: KMS_KEY_PAIR_NAME
      iamInstanceProfile: NODE_IAM_PROFILE
      rootVolume:
        sizeGiB: ROOT_VOLUME_SIZE
        volumeType: VOLUME_TYPE # Optional
        iops: IOPS # Optional
        kmsKeyARN: NODE_VOLUME_KEY # Optional
    

    Reemplaza lo siguiente:

    • NODE_POOL_NAME: Un nombre único para tu AWSNodePool.
    • AWSCLUSTER_NAME: Es el nombre de tu AWSCluster. Por ejemplo, staging-cluster
    • CLUSTER_VERSION: es una versión compatible de Kubernetes de los clústeres de Anthos en AWS.
    • AWS_REGION: La misma región de AWS que tu AWSCluster.
    • AWS_SUBNET_ID: Una subred de AWS en la misma región que tu AWSCluster.
    • MINIMUM_NODE_COUNT: Es la cantidad mínima de trabajadores en el grupo de nodos. Consulta Escala clústeres de usuario para obtener más información.
    • MAXIMUM_NODE_COUNT: La cantidad máxima de nodos en el grupo de nodos.
    • MAXIMUM_PODS_PER_NODE_COUNT: la cantidad máxima de pods que los clústeres de Anthos en AWS pueden asignar a un nodo.
    • AWS_NODE_TYPE: Es un tipo de instancia de EC2 en AWS.
    • KMS_KEY_PAIR_NAME: Es el par de claves de AWS KMS asignado a cada trabajador del grupo de nodos.
    • NODE_IAM_PROFILE: Es el nombre del perfil de la instancia de AWS EC2 asignado a los nodos del grupo.
    • ROOT_VOLUME_SIZE: El tamaño, en gibibytes (GiB), de los volúmenes raíz del plano de control.
    • VOLUME_TYPE: el tipo de volumen de EBS de AWS del nodo. Por ejemplo, gp3.
    • IOPS: la cantidad de operaciones de E/S aprovisionadas por segundo (IOPS) para el volumen Solo es válido cuando volumeType es gp3.
    • NODE_VOLUME_KEY: el ARN de la clave de AWS KMS que se usa para encriptar el volumen. Si deseas obtener más información, consulta Usa una CMK administrada por el cliente para encriptar volúmenes.
  5. Aplica los manifiestos a tu servicio de administración.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl apply -f custom-cluster.yaml
    env HTTP_PROXY=http://localhost:8118 \
      kubectl apply -f custom-nodepools.yaml
    

Crea un kubeconfig

Mientras se inicia el clúster de usuario, puedes crear un contexto kubeconfig para el clúster de usuario nuevo. Usas el contexto para autenticarte en un usuario o clúster de administración.

  1. Usa anthos-gke aws clusters get-credentials a fin de generar un kubeconfig para el clúster de usuario en ~/.kube/config.

    env HTTP_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    

    Reemplaza CLUSTER_NAME por el nombre del clúster. Por ejemplo, cluster-0

  2. Usa kubectl para autenticarte en el clúster de usuario nuevo.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl cluster-info
    

    Si el clúster está listo, el resultado incluye las URL de los componentes de Kubernetes dentro del clúster.

Visualiza el estado del clúster

El servicio de administración aprovisiona recursos de AWS cuando aplicas un AWSCluster o AWSNodePool.

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Para enumerar los clústeres, usa kubectl get AWSClusters.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl get AWSClusters
    

El resultado incluye el nombre, el estado, la antigüedad, la versión y el extremo de cada clúster.

Por ejemplo, el siguiente resultado incluye solo un AWSCluster llamado cluster-0:

NAME        STATE          AGE     VERSION         ENDPOINT
cluster-0   Provisioning   2m41s   1.19.9-gke.900   gke-xyz.elb.us-east-1.amazonaws.com

Consulta los eventos de tu clúster

Para ver los eventos de Kubernetes recientes de tu clúster de usuario, usa kubectl get events.

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Ejecuta kubectl get events.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl get events
    

El resultado incluye información, advertencias y errores relacionados con el servicio de administración.

Crea el webhook de identidad de la carga de trabajo o configura variables de entorno

Esta sección está destinada a los administradores de clústeres.

Para proporcionar credenciales de Workload Identity a tus cargas de trabajo sin configuración adicional, puedes crear un webhook en tus clústeres de usuario de manera opcional. Este webhook intercepta las solicitudes de creación de pods y establece la siguiente información de IAM de AWS como variables de entorno:

  • AWS_ROLE_ARN: Es el Amazon Resource Name (ARN) de la función de IAM.
  • aws-iam-token: Es el token que se intercambia para las credenciales de IAM de AWS.
  • AWS_WEB_IDENTITY_TOKEN_FILE: Es la ruta de acceso en la que se almacena el token.

Con estas variables, la interfaz de línea de comandos o el SDK de AWS que se ejecutan dentro del Pod pueden acceder a los recursos otorgados a la función de AWS.

Crear el webhook es opcional. Si decides no crearlo, debes configurar las variables de entorno que se mencionaron antes en el Pod. Para obtener más información sobre cómo no usar un webhook, consulta Aplica credenciales sin el webhook.

Crea archivos YAML para el webhook

Para implementar el webhook, realiza los siguientes pasos:

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Obtén el nombre del clúster de usuario con kubectl:

    env HTTP_PROXY=http://localhost:8118 \
      kubectl get awscluster
    

    kubectl enumera todos tus clústeres de usuario. Elige el clúster de usuario que creaste con Workload Identity habilitado.

  3. Establece el nombre del clúster en una variable de entorno.

    CLUSTER_NAME=CLUSTER_NAME
    

    Reemplaza CLUSTER_NAME por el nombre del clúster. Por ejemplo, cluster-0

  4. Configura variables de entorno para el espacio de nombres y la imagen del Pod de Workload Identity.

    IDENTITY_IMAGE=gcr.io/gke-multi-cloud-release/amazon-eks-pod-identity-webhook:release-0.2.2-gke.0
    
    WEBHOOK_NAMESPACE=workload-identity-webhook
    
  5. Para generar el manifiesto YAML de webhook en un archivo llamado aws-webhook.yaml, realiza los siguientes pasos.

    env HTTP_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials ${CLUSTER_NAME}
    
    CLUSTER_CA=$(env HTTP_PROXY=http://localhost:8118 \
      kubectl config view --raw -o json  | jq -r '.clusters[] | select(.name == "'$(kubectl config current-context)'") | .cluster."certificate-authority-data"')
    
    cat << EOF > aws-webhook.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    rules:
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['create']
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['get', 'update', 'patch']
        resourceNames:
          - pod-identity-webhook
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pod-identity-webhook
    rules:
      - apiGroups: ['']
        resources: ['serviceaccounts']
        verbs: ['get', 'watch',  'list']
      - apiGroups:  ['certificates.k8s.io']
        resources: ['certificatesigningrequests']
        verbs:  ['create', 'get', 'list', 'watch']
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: pod-identity-webhook
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: pod-identity-webhook
      template:
        metadata:
          labels:
            app: pod-identity-webhook
        spec:
          serviceAccountName: pod-identity-webhook
          containers:
            - name: pod-identity-webhook
              image: ${IDENTITY_IMAGE}
              imagePullPolicy: Always
              command:
                - /webhook
                - --in-cluster
                - --namespace=${WEBHOOK_NAMESPACE}
                - --service-name=pod-identity-webhook
                - --tls-secret=pod-identity-webhook
                - --annotation-prefix=eks.amazonaws.com
                - --token-audience=sts.amazonaws.com
                - --logtostderr
              volumeMounts:
                - name: webhook-certs
                  mountPath: /var/run/app/certs
                  readOnly: false
          volumes:
            - name: webhook-certs
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
      annotations:
        prometheus.io/port: '443'
        prometheus.io/scheme: https
        prometheus.io/scrape: 'true'
    spec:
      ports:
        - port: 443
          targetPort: 443
      selector:
        app: pod-identity-webhook
    ---
    apiVersion: admissionregistration.k8s.io/v1beta1
    kind: MutatingWebhookConfiguration
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    webhooks:
      - name: pod-identity-webhook.amazonaws.com
        failurePolicy: Ignore
        clientConfig:
          service:
            name: pod-identity-webhook
            namespace: ${WEBHOOK_NAMESPACE}
            path: /mutate
          caBundle: ${CLUSTER_CA}
        rules:
          - operations: ['CREATE']
            apiGroups: ['']
            apiVersions: ['v1']
            resources: ['pods']
    EOF
    

    El contenido de aws-webhook.yaml está listo para aplicarse a tu clúster.

Aplica el webhook a tu clúster de usuario

Para aplicar el webhook a tu clúster de usuarios, realiza los siguientes pasos:

  1. Aplica el archivo aws-webhook.yaml en tu clúster de usuario.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl apply -f aws-webhook.yaml
    
  2. Cuando aplicas el manifiesto, el Pod webhook genera solicitudes de firma de certificados de Kubernetes (CSR). Aprueba todas las solicitudes de system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook con kubectl certificate approve.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl certificate approve $(env HTTP_PROXY=http://localhost:8118 \ &&\
      kubectl get csr -o \
        jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook\")].metadata.name}")
    
  3. Verifica que no haya ningún CSR pendiente no aprobado.

    Usa kubectl get csr para verificar que todos los CSR del solicitante system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook estén aprobados:

    env HTTP_PROXY=http://localhost:8118 \
      kubectl get csr
    

    Respuesta:

    NAME        AGE   REQUESTOR                                            CONDITION
    csr-mxrt8   10s   system:serviceaccount:default:pod-identity-webhook   Approved,Issued
    

Configura el proveedor de OIDC de AWS

Esta sección está destinada a los administradores de clústeres.

Para crear un proveedor de OIDC en AWS, AWS requiere una autoridad certificada intermedia (CA) o una huella digital del certificado de servidor. Tus credenciales de detección de OIDC se almacenan en storage.googleapis.com, con un certificado firmado por una CA intermedia llamada GTS CA 1O1. Esta CA vence el 15/12/2021 a las 00:00:42 UTC. La huella digital SHA-1 de tu CA intermedia GTS CA 1O1 es dfe2070c79e7ff36a925ffa327ffe3deecf8f9c2.

Para registrar tu bucket de descubrimiento de OIDC como proveedor de OIDC con AWS, sigue estos pasos:

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Guarda la URL del emisor de OIDC, la ruta de acceso del host del emisor y la huella digital de Cloud Storage en las variables de entorno.

    ISSUER_URL=$(env HTTP_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.workloadIdentityInfo.issuerURL}')
    ISSUER_HOSTPATH=${ISSUER_URL#"https://"}
    CA_THUMBPRINT=dfe2070c79e7ff36a925ffa327ffe3deecf8f9c2
    
  3. Usa la herramienta de línea de comandos de aws para crear un proveedor de OIDC en AWS.

    aws iam create-open-id-connect-provider \
      --url ${ISSUER_URL} \
      --thumbprint-list ${CA_THUMBPRINT} \
      --client-id-list sts.amazonaws.com
    

Actualiza la huella digital

Si Google rota la CA para storage.googleapis.com, ejecuta los siguientes comandos:

  1. Busca la huella digital del certificado actualizada, dfe2070c79e7ff36a925ffa327ffe3deecf8f9c2.

  2. Actualiza la huella digital con el comando aws. bash aws iam update-open-id-connect-provider-thumbprint

Crea funciones y políticas de IAM de AWS

Esta sección está destinada a los administradores de clústeres.

Crea una función IAM de AWS para vincularla a una cuenta de servicio de Kubernetes. La función de IAM tiene permisos para sts:AssumeRoleWithWebIdentity.

Para crear la función, realiza los siguientes pasos:

  1. Busca o crea una política de IAM de AWS que otorgue los permisos necesarios para las cargas de trabajo.

    Necesitas la política de IAM de AWS para el Amazon Resource Name (ARN). Por ejemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.

  2. Configura variables de entorno con la información de autenticación.

    KSA_NAME=KUBERNETES_SERVICE_ACCOUNT
    WORKLOAD_NAMESPACE=WORKLOAD_IDENTITY_NAMESPACE
    
    AWS_ROLE_NAME=AWS_ROLE_NAME
    AWS_POLICY=EXISTING_AWS_POLICY
    

    Reemplaza lo siguiente:

    • KUBERNETES_SERVICE_ACCOUNT: Es el nombre de la cuenta de servicio de Kubernetes nueva.
    • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.
    • AWS_ROLE_NAME: Es el nombre de una nueva función de AWS para tus cargas de trabajo.
    • EXISTING_AWS_POLICY: Es el nombre del recurso de Amazon (ARN) de una política de IAM de AWS existente, por ejemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
  3. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  4. Crea una política de IAM de AWS que permita al clúster de usuario asumir credenciales de seguridad temporales con el servicio de tokens de seguridad de AWS:

    CLUSTER_ID=$(env HTTP_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    # Get the ID Provider ARN
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    # Create AWS role and policy
    cat > irp-trust-policy.json << EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "${PROVIDER_ARN}"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${ISSUER_HOSTPATH}:sub": "system:serviceaccount:${WORKLOAD_NAMESPACE}:${KSA_NAME}"
            }
          }
        }
      ]
    }
    EOF
    
  5. Para crear una función de IAM de AWS con esta política y adjuntarle la política existente, realiza los siguientes comandos:

    aws iam create-role \
      --role-name ${AWS_ROLE_NAME} \
      --assume-role-policy-document file://irp-trust-policy.json
    aws iam update-assume-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-document file://irp-trust-policy.json
    aws iam attach-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-arn ${AWS_POLICY}
    

    La herramienta de línea de comandos de aws confirma que la política está conectada a tu función.

Crea cuentas de servicio de Kubernetes para cargas de trabajo

Esta sección está destinada a desarrolladores o administradores de clústeres.

Para crear cuentas de servicio de Kubernetes vinculadas a la función de IAM de AWS que se especificó antes, realiza los siguientes pasos:

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu clúster de usuario.

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

  2. Crea la cuenta de servicio de Kubernetes mediante la ejecución de los siguientes comandos:

    S3_ROLE_ARN=$(aws iam get-role \
      --role-name AWS_ROLE_NAME \
      --query Role.Arn --output text)
    
    cat << EOF  > k8s-service-account.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ${KSA_NAME}
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    EOF
    
    env HTTP_PROXY=http://localhost:8118 \
    kubectl apply -f k8s-service-account.yaml
    
    env HTTP_PROXY=http://localhost:8118 \
    kubectl annotate sa --namespace ${WORKLOAD_NAMESPACE} ${KSA_NAME} eks.amazonaws.com/role-arn=${S3_ROLE_ARN}
    

    Reemplaza lo siguiente:

    • AWS_ROLE_NAME: Es el nombre de la función de IAM de AWS que se aplica a tus cargas de trabajo.
    • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.

Aplica credenciales a tus pods

Esta sección está destinada a los desarrolladores.

En esta sección, se da por hecho que implementaste el webhook de Workload Identity. Si no has implementado el webhook, ve directamente a la sección sobre cómo aplicar credenciales sin el webhook.

Aplica credenciales con el webhook

En esta sección, se describe cómo configurar los Pods para leer las credenciales que ofrece el webhook.

Agrega la cuenta de servicio al Pod

Para usar Workload Identity con una carga de trabajo, agrega la cuenta de servicio de Kubernetes a los siguientes campos:

  • Para una implementación: spec.template.spec.serviceAccountName
  • Para un Pod: spec.serviceAccount

En el siguiente manifiesto de Pod, se inicia una imagen de CentOS básica y contiene el campo spec.serviceAccount.

apiVersion: v1
kind: Pod
metadata:
  name: sample-centos-pod
  namespace: WORKLOAD_IDENTITY_NAMESPACE
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    image: centos:7
    name: centos
  serviceAccount: KUBERNETES_SERVICE_ACCOUNT

Reemplaza lo siguiente:

  • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.
  • KUBERNETES_SERVICE_ACCOUNT: Es el nombre de la cuenta de servicio de Kubernetes que creaste antes.

Verifica si los Pods tienen configuradas las variables de entorno

A fin de verificar si los Pods tienen configuradas las variables de entorno, ejecuta el siguiente comando para obtener la información del Pod:

kubectl get pod --namespace WORKLOAD_IDENTITY_NAMESPACE POD_NAME -o yaml

Reemplaza lo siguiente:

  • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.
  • POD_NAME: Es el nombre del pod que se va a comprobar.

El resultado contiene los valores de las variables de entorno en spec.containers.command.env y el punto de activación para el token de IAM de AWS. A continuación, se muestra un ejemplo del manifiesto de un pod.

apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    env:
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::1234567890:role/my-example-workload-role-1
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    image: centos:7
    imagePullPolicy: IfNotPresent
    name: centos
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: my-k8s-serviceaccount-token-d4nz4
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  serviceAccount: my-k8s-serviceaccount
  serviceAccountName: my-k8s-serviceaccount
  volumes:
  - name: aws-iam-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
  - name: my-k8s-serviceaccount-token-d4nz4
    secret:
      defaultMode: 420
      secretName: my-k8s-serviceaccount-token-d4nz4
   ...
status:
  ...

Aplica credenciales sin el webhook

Si no implementas el webhook de Workload Identity, debes hacer lo siguiente:

Crea un Pod con credenciales para Workload Identity

A fin de crear un Pod que incluya las credenciales necesarias para Workload Identity, realiza los siguientes pasos:

  1. Copia el siguiente manifiesto del Pod en un archivo llamado sample-pod-no-webhook.yaml. La configuración inicia una imagen de CentOS básica con las credenciales necesarias.

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-centos-pod-no-webhook
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    spec:
      containers:
      - command:
        - /bin/bash
        - -ec
        - while :; do echo '.'; sleep 500 ; done
        image: centos:7
        name: centos
        env:
        - name: AWS_ROLE_ARN
          value: IAM_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        volumeMounts:
        - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
      serviceAccount: KUBERNETES_SERVICE_ACCOUNT
    

    Reemplaza lo siguiente:

    • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.
    • IAM_ROLE_ARN: Es el ARN de la función de IAM otorgada al Pod. Por ejemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
    • KUBERNETES_SERVICE_ACCOUNT: Es el nombre de la cuenta de servicio de Kubernetes que creaste antes.
  2. Aplica el manifiesto de Pod a tu clúster con kubectl:

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

Comprueba si los Pods pueden acceder a los recursos de AWS

En el siguiente procedimiento, se describe cómo comprobar si el Pod recibió las credenciales necesarias para que funcione Workload Identity.

Para completar los pasos, debes contar con lo siguiente:

  • Acceso de shell bash al contenedor, la mayoría de las imágenes de producción no tienen disponible una shell. En el siguiente ejemplo, se muestra cómo usar el Pod especificado en la sección anterior para acceder a AWS S3.

  • Tu Pod necesita tener acceso saliente a Internet para descargar la interfaz de línea de comandos de AWS.

Para verificar si el Pod puede acceder a un bucket de S3, realiza los siguientes pasos:

  1. Usa kubectl exec para iniciar una shell Bash interactiva en el Pod sample-centos-pod-no-webhook:

    env HTTP_PROXY=http://localhost:8118 \
    kubectl exec -it --namespace ${WORKLOAD_NAMESPACE} sample-centos-pod-no-webhook -- bash
    

    Tu terminal abre la shell Bash en el Pod.

  2. Usa pip para instalar la interfaz de línea de comandos de AWS:

    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python get-pip.py
    pip install awscli --upgrade
    
  3. Verifica los permisos y las credenciales de IAM de AWS con la herramienta de aws:

    aws sts assume-role-with-web-identity \
     --role-arn IAM_ROLE_ARN \
     --role-session-name mh9test \
     --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token \
     --duration-seconds 1000
    

    Reemplaza IAM_ROLE_ARN con el ARN de la función de IAM otorgada al Pod. Por ejemplo, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

    La herramienta de aws imprime información de credenciales similar a la que se muestra a continuación:

    {
        "AssumedRoleUser": {
            "AssumedRoleId": "AROAR2ZZZLEXVSDCDJ37N:mh9test",
            "Arn": "arn:aws:sts::126285863215:assumed-role/my-example-workload-role-1/mh9test"
        },
        "Audience": "sts.amazonaws.com",
        "Provider": "arn:aws:iam::126285863215:oidc-provider/storage.googleapis.com/gke-issuer-cec6c353",
        "SubjectFromWebIdentityToken": "system:serviceaccount:default:my-s3-reader-ksa",
        "Credentials": {
            "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
            "SessionToken": "MY_TOKEN",
            "Expiration": "2020-08-14T22:46:36Z",
            "AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
        }
    }
    

    Si ves el siguiente mensaje, verifica que el bucket sea de acceso público: An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements

Realiza una limpieza

En esta sección, se muestra cómo quitar los recursos que creaste antes en este documento.

Limpia la cuenta de servicio y su función de IAM asociada

Para borrar la cuenta de servicio y su función de IAM asociada, realiza los siguientes pasos:

  1. Limpia la cuenta de servicio:

    kubectl delete sa KUBERNETES_SERVICE_ACCOUNT --namespace WORKLOAD_IDENTITY_NAMESPACE
    

    Reemplaza lo siguiente:

    • KUBERNETES_SERVICE_ACCOUNT: Es el nombre de la cuenta de servicio de Kubernetes nueva.
    • WORKLOAD_IDENTITY_NAMESPACE: Es el nombre del espacio de nombres donde se ejecutan las cargas de trabajo.
  2. Limpia la función de IAM de AWS. Elige una de las siguientes opciones:

    • Borra la función IAM de AWS con la consola de AWS.

    • Borra la función con la herramienta de línea de comandos de AWS mediante los siguientes comandos:

      aws iam  detach-role-policy \
        --role-name=${AWS_ROLE_NAME} \
        --policy-arn=${AWS_POLICY}
      aws iam delete-role --role-name=${AWS_ROLE_NAME}
      

Borra tu clúster de usuario

Para borrar tu clúster de usuario, sigue los pasos que aparecen en Desinstala los clústeres de Anthos en AWS.

Limpia el proveedor de OIDC de AWS

Después de que se borre el clúster del usuario, anula el registro y borra el proveedor de OIDC en AWS mediante el siguiente comando shell bash o la consola de AWS.

  1. Desde tu directorio de anthos-aws, usa anthos-gke para cambiar el contexto a tu servicio administrado.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Borra la función con la herramienta de línea de comandos de AWS mediante los siguientes comandos:

    CLUSTER_ID=$(env HTTP_PROXY=http://localhost:8118 \
    kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    aws iam delete-open-id-connect-provider \
        --open-id-connect-provider-arn=${PROVIDER_ARN}
    

    Recibirás una confirmación de que se borró el proveedor de OIDC de AWS.

¿Qué sigue?