Información general técnica - Amazon EKS

Información general técnica

En 2014, AWS Identity and Access Management añadió compatibilidad con identidades federadas mediante OpenID Connect (OIDC). Esta característica le permite autenticar llamadas a la API AWS con proveedores de identidad compatibles y recibir un token web JSON (JWT) de OIDC válido. Puede transferir este token a la operación de API AWS STS AssumeRoleWithWebIdentity y recibir credenciales temporales del rol de IAM. Puede utilizar estas credenciales para interactuar con cualquier servicio de AWS, como Amazon S3 y DynamoDB.

Kubernetes tiene cuentas de servicio de uso largo como su propio sistema de identidad interno. Los pods pueden autenticarse con el servidor de la API de Kubernetes mediante un token montado automáticamente (que era un JWT no OIDC) que solo el servidor de la API de Kubernetes podía validar. Estos tokens de cuenta de servicio heredados no caducan y rotar la clave de firma es un proceso difícil. En la versión 1.12 de Kubernetes, se añadió compatibilidad con una nueva característica ProjectedServiceAccountToken, que es un token web JSON de OIDC que también contiene la identidad de la cuenta de servicio y admite un público configurable.

Ahora, Amazon EKS aloja un punto de enlace de detección de OIDC público por clúster que contiene las claves de firma para los tokens web JSON ProjectedServiceAccountToken a fin de que los sistemas externos como IAM puedan validar y aceptar los tokens de OIDC que emite Kubernetes.

Configurar el rol de IAM

En IAM, cree un rol de IAM con una relación de confianza que se asigne al proveedor de OIDC del clúster, al espacio de nombres de la cuenta de servicio y (opcionalmente) el nombre de la cuenta de servicio y, a continuación, asocie la política de IAM que desea asociar a la cuenta de servicio. Puede agregar varias entradas en las condiciones StringEquals y StringLike siguientes para utilizar varias cuentas de servicio o espacios de nombres con el rol.

  • Para limitar un rol a una cuenta de servicio específica:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/<OIDC_PROVIDER>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "<OIDC_PROVIDER>:sub": "system:serviceaccount:<SERVICE_ACCOUNT_NAMESPACE>:<SERVICE_ACCOUNT_NAME>" } } } ] }
  • Para definir el ámbito de un rol a un espacio de nombres completo (para utilizar el espacio de nombres como límite):

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/<OIDC_PROVIDER>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "<OIDC_PROVIDER>:sub": "system:serviceaccount:<SERVICE_ACCOUNT_NAMESPACE>:*" } } } ] }

Configuración de cuenta de servicio

En Kubernetes, se define el rol de IAM que se debe asociar a una cuenta de servicio en el clúster al agregar la anotación eks.amazonaws.com/role-arn a la cuenta de servicio.

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>

Configuración de pods

El Webhook de identidad de pod de Amazon EKS del clúster controla los pods que se encuentran asociados a cuentas de servicio con esta anotación y les aplica las siguientes variables de entorno.

AWS_ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME> AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
nota

El clúster no necesita utilizar el enlace web de mutación para configurar las variables de entorno y los montajes de archivos de token; puede optar por configurar pods para agregar estas variables de entorno manualmente.

Las versiones compatibles del SDK AWS buscan primero estas variables de entorno en el proveedor de la cadena de credenciales. Las credenciales del rol se utilizan para los pods que cumplen estos criterios.

nota

Cuando un pod utiliza credenciales de AWS de un rol de IAM asociado a una cuenta de servicio, la AWS CLI u otros SDK de los contenedores de ese pod utilizan las credenciales proporcionadas por dicho rol. El pod todavía tiene acceso a las credenciales proporcionadas al Rol de IAM de nodo de Amazon EKS, a menos que restrinja el acceso a esas credenciales. Para obtener más información, consulte Restringir el acceso a las credenciales de perfil de instancia de Amazon EC2 y IMDS.

De forma predeterminada, solo los contenedores que se ejecutan como root tienen los permisos del sistema de archivos adecuados para leer el archivo de token de identidad web. Puede proporcionar estos permisos haciendo que sus contenedores se ejecuten como root o proporcionando el siguiente contexto de seguridad para los contenedores de su manifiesto. El ID de fsGroup es arbitrario y puede elegir cualquier ID de grupo válido. Para obtener más información acerca de las implicaciones de establecer un contexto de seguridad para sus pods, consulte Configure a Security Context for a Pod or Container en la documentación de Kubernetes.

nota

No es necesario proporcionar este contexto de seguridad para clústeres 1.19 o posteriores.

apiVersion: apps/v1 kind: Deployment metadata: name: <my-app> spec: template: metadata: labels: app: <my-app> spec: serviceAccountName: <my-app> containers: - name: <my-app> image: <my-app>:latest securityContext: fsGroup: <1337> ...

El kubelet solicita y almacena el token en nombre del pod. De forma predeterminada, el kubelet actualiza el token si tiene más de 80 por ciento de su TTL total, o si el token tiene más de 24 horas. Puede modificar la duración del vencimiento de cualquier cuenta, excepto la cuenta de servicio predeterminada, con la configuración en la especificación del pod. Para obtener más información, consulte Proyección del volumen del token de la cuenta de servicio en la documentación de Kubernetes.

Permisos de IAM entre cuentas

Puede configurar permisos de IAM entre cuentas mediante la creación de un proveedor de identidad a partir del clúster de otra cuenta o mediante operaciones AssumeRole encadenadas. En los siguientes ejemplos, la cuenta A posee un clúster de Amazon EKS que admite roles de IAM para las cuentas de servicio. Los pods que se ejecutan en ese clúster deben asumir permisos de IAM de la cuenta B.

ejemplo : crear un proveedor de identidad a partir del clúster de otra cuenta

En este ejemplo, la cuenta A proporcionaría a la cuenta B la URL del emisor OIDC de su clúster. La cuenta B sigue las instrucciones de Crear un proveedor de OIDC de IAM para su clúster y Crear un rol y una política de IAM para su cuenta de servicio utilizando la URL del emisor OIDC del clúster de la cuenta A. A continuación, un administrador del clúster comenta la cuenta de servicio en el clúster de la cuenta A para utilizar el rol de la cuenta B.

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_B_ID>:role/<IAM_ROLE_NAME>

ejemplo : Uso de operaciones AssumeRole encadenadas

En este ejemplo, la cuenta B crea una política de IAM con los permisos que debe otorgar a los pods del clúster de la cuenta A. La cuenta B adjunta dicha política a un rol de IAM con una relación de confianza que concede permisos de AssumeRole a la cuenta A (111111111111), tal y como se muestra a continuación.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }

La cuenta A crea un rol con una política de confianza que obtiene las credenciales del proveedor de identidad creado con la URL del emisor OIDC del clúster, tal y como se muestra a continuación.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111111111111:oidc-provider/oidc.eks.<region-code>.amazonaws.com/id/EXAMPLEC061A78C479E31025A21AC4CDE191335D05820BE5CE" }, "Action": "sts:AssumeRoleWithWebIdentity" } ] }

La cuenta A asocia una política a ese rol con los siguientes permisos para asumir el rol que ha creado la cuenta B.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::222222222222:role/account-b-role" } ] }

El código de aplicación para que los pods asuman el rol de la cuenta B utiliza dos perfiles: account_b_role y account_a_role. El perfil account_b_role utiliza el perfil account_a_role como origen. Para el AWS CLI, el archivo ~/.aws/config tendría un aspecto similar al del siguiente ejemplo.

[profile account_b_role] source_profile = account_a_role role_arn=arn:aws:iam::222222222222:role/account-b-role [profile account_a_role] web_identity_token_file = /var/run/secrets/eks.amazonaws.com/serviceaccount/token role_arn=arn:aws:iam::111111111111:role/account-a-role

Para especificar perfiles encadenados para otros SDK AWS, consulte su documentación.