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

8 minuto de leitura
0

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

Descrição breve

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 perfil do IAM corretas
  • Verifique se você especificou corretamente o serviceAccountName no 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 AWS China, verifique a variável de ambiente AWS_DEFAULT_REGION

Resolução

Verifique se já existe um provedor de IAM OIDC para seu cluster

Se um provedor já existir, você receberá um erro semelhante à seguinte mensagem:

"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" (WebIdentityErr: falha ao recuperar credenciais\ncausada por: InvalidIdentityToken: nenhum provedor de OpenIDConnect encontrado em sua conta para https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\tcódigo de status: 400)

1.    Verifique o URL do provedor de OIDC do seu cluster:

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

Veja o seguinte exemplo de saída:

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

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

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

Veja o seguinte exemplo de saída:

"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, então será necessário criar um provedor de OIDC do IAM.

Verifique se seu perfil 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 guia Trust Relationships (Relações 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"
        }
      }
    }
  ]
}

Para verificar as relações de confiança, execute o seguinte comando com o nome do seu perfil na AWS Command Line Interface (AWS CLI):

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

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

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

Veja o seguinte exemplo de saída:

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

Veja o seguinte exemplo de saída:

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 (no site do Kubernetes).

Verifique se a conta de serviço tem as anotações de perfil 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. Substitua YOUR_NAMESPACE pelo seu namespace do Kubernetes.

Veja o seguinte exemplo de saída:

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

Veja o seguinte exemplo de saída:

serviceAccountName: irsa

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

Procure por AWS_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

Veja o seguinte exemplo de saída:

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 a aplicação 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 usuário 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.

Veja o seguinte exemplo de comando:

$ kubectl rollout restart deploy nginx

Veja o seguinte exemplo de saída:

deployment.apps/nginx restarted

Para implantações de daemonsets ou statefulsets, é possível usar o seguinte comando:

$ kubectl rollout restart deploy DEPLOYMENT_NAME

Se você criou apenas um pod, exclua e recrie o pod.

Veja o exemplo de comando a seguir para excluir o pod:

$ kubectl delete pod POD_NAME

Veja o exemplo de comando a seguir para recriar o pod:

$ kubectl apply -f SPEC_FILE

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

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

Veja o seguinte exemplo de saída:

{
  "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 Obter a impressão digital de um provedor de identidade do OpenID Connect.

Para a região da AWS China, 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"
...

AWS OFICIAL
AWS OFICIALAtualizada há 2 anos