¿Cómo soluciono los problemas de un proveedor de OIDC e IRSA en Amazon EKS?

Última actualización: 15/11/2021

Mis pods no pueden usar los permisos del rol de IAM con el token de cuenta de Amazon Elastic Kubernetes Service (Amazon EKS).

Descripción corta

Para solucionar problemas con el proveedor de OpenID Connect (OIDC) y los roles de IAM para cuentas de servicio (IRSA) en Amazon EKS, complete los pasos en una de las siguientes secciones:

  • Verifique si tiene un proveedor de OIDC de IAM existente para el clúster
  • Verifique si el rol de IAM tiene una política de IAM necesaria adjunta con los permisos requeridos
  • Compruebe que las relaciones de confianza del rol de IAM estén configuradas correctamente
  • Verifique si ha creado una cuenta de servicio
  • Compruebe que la cuenta de servicio tenga las anotaciones de rol de IAM correctas
  • Compruebe que ha especificado correctamente el serviceAccountName en el pod
  • Verifique las variables de entorno y los permisos
  • Compruebe que la aplicación utilice un SDK de AWS compatible
  • Verifique el usuario y el grupo del pod
  • Volver a crear pods
  • Compruebe que la audiencia sea correcta
  • Compruebe que haya configurado la huella digital correcta
  • Para la región de China de AWS, verifique la variable de entorno AWS_DEFAULT_REGION

Resolución

Verifique si tiene un proveedor de OIDC de IAM existente para el clúster

Si ya existe un proveedor, recibirá un error.

Por ejemplo:

WebIdentityErr: failed to retrieve credentials\ncaused by: InvalidIdentityToken: No OpenIDConnect provider found in your account 
for https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\tstatus code: 400

1.    Verifique la URL del proveedor de OIDC del clúster:

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

Salida de ejemplo:

https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E

2.    Incluya los proveedores de OIDC de IAM en la cuenta. Sustituya EXAMPLED539D4633E53DE1B716D3041E (incluir < >) con el valor devuelto por el comando anterior:

aws iam list-open-id-connect-providers | grep EXAMPLED539D4633E53DE1B716D3041E

Salida de ejemplo:

"Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"

Si el comando anterior devuelve una salida, entonces ya tiene un proveedor para el clúster. Si el comando no devuelve una salida, debe crear un proveedor de OIDC de IAM. Consulte Crear un proveedor de OIDC de IAM para el clúster.

Verifique si el rol de IAM tiene una política de IAM necesaria adjunta con los permisos requeridos

1.    Abra la consola de IAM.

2.    En el panel de navegación, elija Roles (Roles).

3.    Elija el rol que desea comprobar.

4.    En la pestaña Permissions (Permisos), compruebe si este rol tiene adjunta la política requerida.

Compruebe que las relaciones de confianza del rol de IAM estén configuradas correctamente

Con la consola de administración de AWS:

1.    Abra la consola de IAM.

2.    En el panel de navegación, elija Roles (Roles).

3.    Elija el rol que desea verificar.

4.    Elija la pestaña Trust Relationships (Relaciones de confianza) para comprobar que el formato de su política coincida con el formato de la siguiente política JSON:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME",
          "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

Con la AWS CLI:

Para comprobar las relaciones de confianza, ejecute el siguiente comando con el nombre de su rol:

$ aws iam get-role --role-name EKS-IRSA

Nota: Sustituya EKS-IRSA por el nombre de su rol de IAM.

En el JSON de salida, busque la sección AssumeRolePolicyDocument.

Salida de ejemplo:

{
    "Role": {
        "Path": "/",
        "RoleName": "EKS-IRSA",
        "RoleId": "AROAQ55NEXAMPLELOEISVX",
        "Arn": "arn:aws:iam::ACCOUNT_ID:role/EKS-IRSA",
        "CreateDate": "2021-04-22T06:39:21+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
                    },
                    "Action": "sts:AssumeRoleWithWebIdentity",
                    "Condition": {
                        "StringEquals": {
                            "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com",
                            "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME"
                        }
                    }
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
            "LastUsedDate": "2021-04-22T07:01:15+00:00",
            "Region": "AWS_REGION"
        }
    }
}

Nota: Verifique que ha especificado la región de AWS, el nombre de la cuenta de servicio de Kubernetes y el espacio de nombres de Kubernetes correctos.

Verifique si ha creado una cuenta de servicio

Use el siguiente comando:

$ kubectl get sa -n YOUR_NAMESPACE

Nota: Sustituya YOUR_NAMESPACE por su espacio de nombres de Kubernetes.

Salida de ejemplo:

NAME      SECRETS   AGE
default   1         28d
irsa      1         66m

Si no tiene una cuenta de servicio, consulte Configurar cuentas de servicio para pods .

Compruebe que la cuenta de servicio tenga las anotaciones de rol de IAM correctas

Use el siguiente comando:

$ kubectl describe sa irsa -n YOUR_NAMESPACE

Nota: Sustituya irsa por el nombre de su cuenta de servicio de Kubernetes. Sustituya YOUR_NAMESPACE por su espacio de nombres de Kubernetes.

Salida de ejemplo:

Name:                irsa
Namespace:           default
Labels:              none
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
Image pull secrets:  none
Mountable secrets:   irsa-token-v5rtc
Tokens:              irsa-token-v5rtc
Events:              none

Compruebe que ha especificado correctamente el serviceAccountName en el pod

Use el siguiente comando:

$ kubectl get pod POD_NAME  -o yaml -n YOUR_NAMESPACE| grep -i serviceAccountName:

Nota: Sustituya POD_NAME y YOUR_NAMESPACE por su pod y espacio de nombres de Kubernetes.

Salida de ejemplo:

serviceAccountName: irsa

Verifique las variables de entorno y los permisos

Busque AWS_IAM_ROLE_ARN y AWS_WEB_IDENTITY_TOKEN_FILE en las variables de entorno del pod:

$ kubectl -n YOUR_NAMESPACE exec -it POD_NAME -- env | grep AWS

Salida de ejemplo:

AWS_REGION=ap-southeast-2
AWS_ROLE_ARN=arn:aws:iam::111122223333:role/EKS-IRSA
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
AWS_DEFAULT_REGION=ap-southeast-2

Compruebe que la aplicación utilice un SDK de AWS compatible

La versión del SDK debe ser superior o igual a los siguientes valores:

Java (Version 2) — 2.10.11
Java — 1.11.704
Go — 1.23.13
Python (Boto3) — 1.9.220
Python (botocore) — 1.12.200
AWS CLI — 1.16.232
Node — 3.15.0
Ruby — 2.11.345
C++ — 1.7.174
.NET — 3.3.659.1
PHP — 3.110.7

Para verificar la versión más reciente del SDK compatible, consulte Uso de un SDK de AWS compatible.

Verifique el usuario y el grupo del pod

Use el siguiente comando:

$ kubectl exec -it POD_NAME -- id
uid=0(root) gid=0(root) groups=0(root)

Nota: De forma predeterminada, solo los contenedores que se ejecutan como raíz tienen los permisos del sistema de archivos adecuados para leer el archivo de token de identidad web.

Si los contenedores no se ejecutan como raíz, puede recibir los siguientes errores:

Error: PermissionError: [Errno 13] Permission denied: ‘/var/run/secrets/eks.amazonaws.com/serviceaccount/token

O bien:

WebIdentityErr: failed fetching WebIdentity token: \ncaused by: WebIdentityErr: unable to read file at /var/run/secrets/eks.amazonaws.com/serviceaccount/token\ncaused by: open /var/run/secrets/eks.amazonaws.com/serviceaccount/token: permission denied

Para proporcionar los permisos del sistema de archivos adecuados, asegúrese de que los contenedores se ejecuten como raíz. Para los clústeres 1.18 o inferiores, proporcione el siguiente contexto de seguridad para los contenedores del manifiesto:

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
...

Nota: El ID de fsGroup es arbitrario. Puede elegir cualquier ID de grupo válido. La configuración del contexto de seguridad anterior no es necesaria para los clústeres 1.19 o posteriores.

Volver a crear pods

Si creó los pods antes de aplicar los IRSA, vuelva a crearlos.

Comando de ejemplo:

$ kubectl rollout restart deploy nginx

Salida de ejemplo:

deployment.apps/nginx restarted

Para implementaciones de daemonsets o statefulsets, puede usar el siguiente comando:

$ kubectl rollout reiniciar implementación DEPLOYMENT_NAME

Si ha creado solo un pod, debe eliminarlo y volver a crearlo.

Comando de ejemplo para eliminar:

$ kubectl delete pod POD_NAME

Comando de ejemplo para volver a crear:

$ kubectl apply -f SPEC_FILE

Nota: Sustituya SPEC_FILE por la ruta del archivo de manifiesto de Kubernetes y el nombre del archivo.

Compruebe que la audiencia sea correcta

Si creó el proveedor de OIDC con una audiencia incorrecta, recibirá el siguiente error:

Error - An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Incorrect token audience

Verifique el proveedor de identidades de IAM del clúster. Su ClientIDList es sts.amazonaws.com:

$ aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E

Salida de ejemplo:

{
    "Url": "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E",
    "ClientIDList": [
        "sts.amazonaws.com"
    ],
    "ThumbprintList": [
        "9e99a48a9960b14926bb7f3b02e22da2b0ab7280"
    ],
    "CreateDate": "2021-01-21T04:29:09.788000+00:00",
    "Tags": []
}

Compruebe que haya configurado la huella digital correcta

Si la huella digital configurada en el OIDC de IAM no es correcta, puede recibir el siguiente error:

failed to retrieve credentials caused by: InvalidIdentityToken: OpenIDConnect provider's HTTPS certificate doesn't match configured thumbprint

Para configurar automáticamente la huella digital correcta, use eksctl o la consola de administración de AWS para crear el proveedor de identidades de IAM. Para conocer otras formas de obtener una huella digital, consulte Obtener la huella digital para un proveedor de identidades de OpenID Connect.

Para la región de China de AWS, verifique la variable de entorno AWS_DEFAULT_REGION

Si usa IRSA para un pod o daemonset que se implementa en un clúster de la región de China de AWS, establezca la variable de entorno AWS_DEFAULT_REGION en la especificación del pod. Si no lo hace, el pod o el daemonset pueden recibir el siguiente error:

An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid

Use el siguiente ejemplo para agregar la variable de entorno AWS_DEFAULT_REGION a la especificación de pod o daemonset:

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
        env:
        - name: AWS_DEFAULT_REGION
          value: "AWS_REGION"
...

¿Le resultó útil este artículo?


¿Necesita asistencia técnica o con la facturación?