Como soluciono problemas de um provedor OIDC e de IRSA no Amazon EKS?

Data da última atualização: 15/11/2021

Meus pods não podem usar as permissões de função do IAM com o token de conta do Amazon Elastic Kubernetes Service (Amazon EKS).

Breve descrição

Para solucionar problemas com o provedor OpenID Connect (OIDC) e as funções do IAM para contas de serviço (IRSA) no Amazon EKS, conclua as etapas em uma das seguintes seções:

  • Verifique se você tem um provedor de IAM OIDC existente para seu cluster
  • Verifique se sua função do IAM tem uma política do IAM necessária anexada com as permissões exigidas
  • Verifique se as relações de confiança da função do IAM estão definidas corretamente
  • Verifique se você criou uma conta de serviço
  • Verifique se a conta de serviço tem as anotações de função do IAM corretas
  • Verifique se você especificou corretamente o serviceAccountName no seu pod
  • Verifique as variáveis e as permissões de ambiente
  • Verifique se o aplicativo usa um AWS SDK compatível
  • Verifique o usuário e o grupo do pod
  • Recriar pods
  • Verifique se o público está correto
  • Verifique se você configurou a impressão digital correta
  • Para a região da China da AWS, verifique a variável de ambiente AWS_DEFAULT_REGION

Resolução

Verifique se você tem um provedor de IAM OIDC existente para seu cluster

Se um provedor já existir, você receberá um erro.

Por exemplo:

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 o URL do provedor OIDC do seu cluster:

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

Saída de exemplo:

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

2.    Liste os provedores do IAM OIDC em sua conta. Substitua EXAMPLED539D4633E53DE1B716D3041E (incluir< >) pelo valor retornado do comando anterior:

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

Saída de exemplo:

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

Se o comando anterior retornar uma saída, você já tem um provedor para o cluster. Se o comando não retornar uma saída, você deverá criar um provedor OIDC do IAM. Veja, Criar um provedor OIDC do IAM para o cluster.

Verifique se sua função do IAM tem uma política do IAM necessária anexada com as permissões exigidas

1.    Abra o console do IAM.

2.    No painel de navegação, escolha Funções.

3.    Escolha a função que você deseja verificar.

4.    Na guia Permissões, verifique se essa função tem a política necessária anexada.

Verifique se as relações de confiança da função do IAM estão definidas corretamente

Com o Console de Gerenciamento da AWS:

1.    Abra o console do IAM.

2.    No painel de navegação, escolha Funções.

3.    Escolha a função que você deseja verificar.

4.    Escolha a aba Relação de confiança para verificar se o formato da política corresponde ao formato da seguinte 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"
        }
      }
    }
  ]
}

Com a AWS CLI:

Para verificar as relações de confiança, execute o seguinte comando com o nome da função:

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

Observação: substitua o EKS-IRSA pelo nome da função do IAM.

Na saída JSON, procure a seção AssumeRolePolicyDocument.

Saída de exemplo:

{
    "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"
        }
    }
}

Observação: verifique se você especificou a região da AWS, o nome da conta de serviço do Kubernetes e o namespace do Kubernetes corretos.

Verifique se você criou uma conta de serviço

Execute o seguinte comando:

$ kubectl get sa -n YOUR_NAMESPACE

Observação: Substitua YOUR_NAMESPACE pelo seu namespace do Kubernetes.

Saída de exemplo:

NAME      SECRETS   AGE
default   1         28d
irsa      1         66m

Se você não tiver uma conta de serviço, consulte Configurar contas de serviço para pods .

Verifique se a conta de serviço tem as anotações de função do IAM corretas

Execute o seguinte comando:

$ kubectl describe sa irsa -n YOUR_NAMESPACE

Observação: substitua o irsa pelo nome da sua conta de serviço do Kubernetes. SubstituaYOUR_NAMESPACE pelo seu namespace do Kubernetes.

Saída de exemplo:

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

Verifique se você especificou corretamente o serviceAccountName no seu pod

Execute o seguinte comando:

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

Observação: substitua POD_NAME e YOUR_NAMESPACE pelo pod e namespace do Kubernetes.

Saída de exemplo:

serviceAccountName: irsa

Verifique as variáveis e as permissões de ambiente

Procure por AWS_IAM_ROLE_ARN e AWS_WEB_IDENTITY_TOKEN_FILE nas variáveis de ambiente do pod:

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

Saída de exemplo:

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

Verifique se o aplicativo usa um AWS SDK compatível

A versão do SDK deve ser maior ou igual aos seguintes 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 a versão mais recente do SDK compatível, consulte Usando um AWS SDK compatível.

Verifique o usuário e o grupo do pod

Execute o seguinte comando:

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

Observação: por padrão, somente os contêineres executados como raiz têm as permissões adequadas do sistema de arquivos para ler o arquivo de token de identidade da Web.

Se os contêineres não estiverem sendo executados como raiz, você poderá receber os seguintes erros:

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

Ou:

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 fornecer as permissões corretas do sistema de arquivos, certifique-se de que seus contêineres sejam executados como raiz. Para clusters 1.18 ou inferiores, forneça o seguinte contexto de segurança para os contêineres em seu manifesto:

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

Observação: O ID dofsGroup é arbitrário. Você pode escolher qualquer ID de grupo válido. A configuração de contexto de segurança anterior não é necessária para clusters 1.19 ou posterior.

Recriar pods

Se você criou pods antes de aplicar o IRSA, recrie os pods.

Exemplo de comando:

$ kubectl rollout restart deploy nginx

Saída de exemplo:

deployment.apps/nginx restarted

Para implantações de daemonsets ou statefulsets, você pode usar o seguinte comando:

$ kubectl rollout restart implantar DEPLOYMENT_NAME

Se você criou apenas um pod, deve excluir o pod e recriá-lo.

Exemplo de comando para deletar:

$ kubectl delete pod POD_NAME

Exemplo de comando para recriar:

$ kubectl apply -f SPEC_FILE

Observação: substituaSPEC_FILE pelo caminho do arquivo de manifesto do Kubernetes e pelo nome do arquivo.

Verifique se o público está correto

Se você criou o provedor OIDC com o público incorreto, receberá o seguinte erro:

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

Verifique o provedor de identidade do IAM para o seu cluster. Sua ClientIDList é 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

Saída de exemplo:

{
    "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": []
}

Verifique se você configurou a impressão digital correta

Se a impressão digital configurada no IAM OIDC não estiver correta, você poderá receber o seguinte erro:

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

Para configurar automaticamente a impressão digital correta, use eksctl ou o Console de Gerenciamento da AWS para criar o provedor de identidade do IAM. Para outras formas de obter uma impressão digital, consulte Obtendo a impressão digital de um provedor de identidade do OpenID Connect.

Para a região da China da AWS, verifique a variável de ambiente AWS_DEFAULT_REGION

Se você usar o IRSA para um pod ou daemonset implantado em um cluster na região da China da AWS, defina a variável de ambiente AWS_DEFAULT_REGION na especificação do pod. Caso contrário, o pod ou daemonset pode receber o seguinte erro:

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

Use o exemplo a seguir para adicionar a variável de ambiente AWS_DEFAULT_REGION à sua especificação de pod ou 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"
...

Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?