Amazon EKS에서 OIDC 공급자 및 IRSA 문제를 해결하려면 어떻게 해야 하나요?

7분 분량
0

내 포드는 Amazon Elastic Kubernetes Service(Amazon EKS) 계정 토큰과 함께 AWS Identity and Access Management(IAM) 역할 권한을 사용할 수 없습니다.

간략한 설명

Amazon EKS에서 OpenID Connect(OIDC) 공급자 및 서비스 계정에 대한 IAM 역할(IRSA)과 관련된 문제를 해결하려면 다음 섹션 중 하나의 단계를 완료합니다.

  • 클러스터에 대한 기존 IAM OIDC 공급자가 있는지 확인
  • IAM 역할에 필요한 권한이 있는 필요한 IAM 정책이 연결되어 있는지 확인
  • IAM 역할 신뢰 관계가 올바르게 설정되었는지 확인
  • 서비스 계정을 생성했는지 확인
  • 서비스 계정에 올바른 IAM 역할 주석이 있는지 확인
  • 포드에서 serviceAccountName을 올바르게 지정했는지 확인
  • 환경 변수 및 권한 확인
  • 애플리케이션이 지원되는 AWS SDK를 사용하는지 확인
  • 포드 사용자 및 그룹 확인
  • 포드 재생성
  • 대상이 올바른지 확인
  • 지문을 올바르게 구성했는지 확인
  • AWS 중국 리전의 경우 AWS_DEFAULT_REGION 환경 변수 확인

해결 방법

클러스터에 대한 기존 IAM OIDC 공급자가 있는지 확인

공급자가 이미 있는 경우 다음 메시지와 유사한 오류가 표시됩니다.

"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: 보안 인증 정보 가져오기 실패\n원인: InvalidIdentityToken: 계정에 https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E에 대한 OpenIDConnect 공급자가 없음\n\t상태 코드: 400)"

1.    클러스터의 OIDC 공급자 URL을 확인합니다.

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

다음 출력 예를 참조하세요.

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

2.    계정의 IAM OIDC 공급자를 나열합니다. EXAMPLED539D4633E53DE1B716D3041E(< > 포함)을 이전 명령에서 반환된 값으로 바꿉니다.

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

다음 출력 예를 참조하세요.

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

앞의 명령이 출력을 반환하는 경우 클러스터에 대한 공급자가 이미 있는 것입니다. 명령이 출력을 반환하지 않으면 IAM OIDC 공급자를 생성해야 합니다.

IAM 역할에 필요한 권한이 있는 필요한 IAM 정책이 연결되어 있는지 확인

1.    IAM 콘솔을 엽니다.

2.    탐색 창에서 [Roles]를 선택합니다.

3.    확인하려는 역할을 선택합니다.

4.    권한 탭에서 이 역할에 필요한 정책이 연결되어 있는지 확인합니다.

IAM 역할 신뢰 관계가 올바르게 설정되었는지 확인

AWS 관리 콘솔을 사용하는 경우:

1.    IAM 콘솔을 엽니다.

2.    탐색 창에서 [Roles]를 선택합니다.

3.    확인하려는 역할을 선택합니다.

4.    Trust Relationships(신뢰 관계) 탭을 선택하여 정책의 형식이 다음 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"
        }
      }
    }
  ]
}

신뢰 관계를 확인하려면 AWS Command Line Interface(AWS CLI)에서 사용자의 역할 이름을 사용하여 다음 명령을 실행합니다.

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

참고: EKS-IRSA를 IAM 역할 이름으로 바꿉니다.

출력 JSON에서 AssumeRolePolicyDocument 섹션을 찾습니다.

다음 출력 예를 참조하세요.

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

참고: 올바른 AWS 리전, Kubernetes 서비스 계정 이름 및 Kubernetes 네임스페이스를 지정했는지 확인하세요.

서비스 계정을 생성했는지 확인

다음 명령을 사용합니다.

$ kubectl get sa -n YOUR_NAMESPACE

참고: YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

다음 출력 예를 참조하세요.

NAME      SECRETS   AGE
default   1         28d
irsa      1         66m

서비스 계정이 없는 경우, Configure service accounts for pods(포드에 대한 서비스 계정 구성)(Kubernetes 웹 사이트)를 참조하세요.

서비스 계정에 올바른 IAM 역할 주석이 있는지 확인

다음 명령을 사용합니다.

$ kubectl describe sa irsa -n YOUR_NAMESPACE

참고: IRSA를 Kubernetes 서비스 계정 이름으로 바꿉니다. YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

다음 출력 예를 참조하세요.

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

포드에서 serviceAccountName을 올바르게 지정했는지 확인

다음 명령을 사용합니다.

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

참고: POD_NAMEYOUR_NAMESPACE를 Kubernetes 포드 및 네임스페이스로 바꿉니다.

다음 출력 예를 참조하세요.

serviceAccountName: irsa

환경 변수 및 권한 확인

포드의 환경 변수에서 AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILE을 찾습니다.

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

다음 출력 예를 참조하세요.

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

애플리케이션이 지원되는 AWS SDK를 사용하는지 확인

SDK 버전은 다음 값보다 크거나 같아야 합니다.

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

지원되는 최신 SDK 버전을 확인하려면 지원되는 AWS SDK 사용을 참조하세요.

포드 사용자 및 그룹 확인

다음 명령을 사용합니다.

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

참고: 기본적으로 루트로 실행되는 컨테이너에만 웹 자격 증명 토큰 파일을 읽을 수 있는 적절한 파일 시스템 권한이 있습니다.

컨테이너가 루트로 실행되지 않는 경우 다음과 같은 오류가 발생할 수 있습니다.

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

-또는-

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

적절한 파일 시스템 권한을 제공하려면 컨테이너가 루트로 실행되는지 확인합니다. 클러스터 1.18 이하의 경우 매니페스트의 컨테이너에 대해 다음 보안 컨텍스트를 제공합니다.

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

참고: fsGroup ID는 임의적입니다. 유효한 그룹 ID를 선택할 수 있습니다. 클러스터 1.19 이상에서는 이전 보안 컨텍스트 설정이 필요하지 않습니다.

포드 재생성

IRSA를 적용하기 전에 포드를 생성한 경우 포드를 다시 생성합니다.

다음 명령 예를 참조하세요.

$ kubectl rollout restart deploy nginx

다음 출력 예를 참조하세요.

deployment.apps/nginx restarted

daemonsets 또는 statefulsets 배포의 경우 다음 명령을 사용할 수 있습니다.

$ kubectl rollout restart deploy DEPLOYMENT_NAME

포드를 하나만 생성한 경우 포드를 삭제하고 다시 생성해야 합니다.

포드를 삭제하려면 다음 명령 예를 참조하세요.

$ kubectl delete pod POD_NAME

포드를 다시 생성하려면 다음 명령 예를 참조하세요.

$ kubectl apply -f SPEC_FILE

참고: SPEC_FILE을 Kubernetes 매니페스트 파일 경로 및 파일 이름으로 바꿉니다.

대상이 올바른지 확인

잘못된 대상을 사용하여 OIDC 공급자를 만든 경우 다음과 같은 오류가 발생합니다.

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

클러스터의 IAM 자격 증명 공급자를 확인합니다. ClientIDListsts.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

다음 출력 예를 참조하세요.

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

지문을 올바르게 구성했는지 확인

IAM OIDC에 구성된 지문이 올바르지 않으면 다음과 같은 오류가 발생할 수 있습니다.

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

올바른 지문을 자동으로 구성하려면 eksctl 또는 AWS Management Console을 사용하여 IAM 자격 증명 공급자를 생성합니다. 지문을 얻는 다른 방법은 Obtaining the thumbprint for an OpenID Connect identity provider(OpenID Connect 자격 증명 공급자에 대한 지문 얻기)를 참조하세요.

AWS 중국 리전의 경우 AWS_DEFAULT_REGION 환경 변수 확인

AWS 중국 리전의 클러스터에 배포된 포드 또는 daemonset에 IRSA를 사용하는 경우 포드 사양에 AWS_DEFAULT_REGION 환경 변수를 설정합니다. 그렇지 않으면 포드 또는 daemonset 이 다음과 같은 오류를 수신할 수 있습니다.

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

다음 예제를 사용하여 포드 또는 daemonset 사양에 AWS_DEFAULT_REGION 환경 변수를 추가합니다.

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 공식
AWS 공식업데이트됨 2년 전