Post

IRSA (IAM Role for Service Account)란? 사용 방법

Photo Query 프로젝트 도중 EKS Pods가 S3, DynamoDB, Secret Manager 등의 서비스에 접근하지 못하는 문제를 직면했고, 부랴부랴 공식문서를 참고해서 해결했던 경험이 있습니다. 이번 Weasel 프로젝트에서도 동일하게 Pod 안의 Application이 Bedrock, Secret Manager에 대해 접근이 필요했습니다.

해당 포스트에서는 OIDC(OpenID Connect)를 사용해 Kubernetes Service Account에 IAM 역할을 부여 후 사용하는 과정에 대해 다뤄보도록 하겠습니다.

사전 조건

  • EKS Cluster
  • EKS Cluster에 대한 IAM OpenID Connect(OIDC) 공급자
    • 확인
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      cluster_name={클러스터 이름}
          
      oidc_id=$(aws eks describe-cluster --name $cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
          
      # oidc_id 확인
      echo $oidc_id
          
      # 존재하는 IAM OIDC 공급자 확인 (출력이 반환 되면 OIDC 공급자가 존재하는 것임)
      aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
      
  • aws cli v.2.12.3 이상
    • aws --version | cut -d / -f2 | cut -d ' ' -f1
  • kubectl

Service Account와 IAM 역할 연결

1. IAM 정책 생성

json 형식으로 pod가 aws 리소스에 대해 필요한 정책 파일을 생성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
cat >weasel-eks-pod-policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",    
                "s3:PutObject",     
                "s3:DeleteObject",  
                "s3:ListBucket"      
            ],
            "Resource": [
                "arn:aws:s3:::weasel-images",
                "arn:aws:s3:::weasel-images/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:PutSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:CreateSecret",
                "secretsmanager:DeleteSecret",
                "secretsmanager:ListSecrets",
                "secretsmanager:TagResource"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel",
                "bedrock:ListModels"
            ],
            "Resource": "*"
        }
    ]
}
EOF

aws-cli를 통해 정책을 생성합니다.

1
aws iam create-policy --policy-name weasel-eks-pod-policy --policy-document file://weasel-eks-pod-policy.json

2. IAM 역할 생성 후 Service Account 연결

아래의 명령어에 상황에 맞는 iamserviceaccount에 대한 이름, 네임스페이스, 클러스터, 역할 이름, 정책 arn을 지정해주어야합니다.

1
2
eksctl create iamserviceaccount --name weasel-eks-pod-sa --namespace weasel --cluster weasel-eks --role-name weasel-eks-pod-role \
    --attach-policy-arn arn:aws:iam::393035689023:policy/weasel-eks-pod-policy --approve

3. 역할 및 정책 확인

  1. IAM 역할의 신뢰 정책 확인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
     aws iam get-role --role-name weasel-eks-pod-role --query Role.AssumeRolePolicyDocument
    
     # 결과
     {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Principal": {
                     "Federated": "arn:aws:iam::393035689023:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/8Dxxx1CDxxxBFFxxx757xxxC95xxxD86"
                 },
                 "Action": "sts:AssumeRoleWithWebIdentity",
                 "Condition": {
                     "StringEquals": {
                         "oidc.eks.us-east-1.amazonaws.com/id/8Dxxx1CDxxxBFFxxx757xxxC95xxxD86:aud": "sts.amazonaws.com",
                         "oidc.eks.us-east-1.amazonaws.com/id/8Dxxx1CDxxxBFFxxx757xxxC95xxxD86:sub": "system:serviceaccount:weasel:weasel-eks-pod-sa"
                     }
                 }
             }
         ]
     }
    
  2. 역할에 정책이 제대로 연결되어있는지 확인
    1
    2
    3
    4
    
     aws iam list-attached-role-policies --role-name weasel-eks-pod-role --query AttachedPolicies[].PolicyArn --output text
    
     # 결과
     arn:aws:iam::393035689023:policy/weasel-eks-pod-policy
    
  3. 사용하려는 정책의 arn을 저장할 변수 설정
    1
    
     export policy_arn=arn:aws:iam::393035689023:policy/weasel-eks-pod-policy
    
  4. 정책의 기본 버전 확인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
     aws iam get-policy --policy-arn $policy_arn
    
     # 결과 (기본 버전이 v1임을 확인)
     {
         "Policy": {
             "PolicyName": "weasel-eks-pod-policy",
             "PolicyId": "ANPAVXAWAVQ75TFUIJ2WR",
             "Arn": "arn:aws:iam::393035689023:policy/weasel-eks-pod-policy",
             "Path": "/",
             "DefaultVersionId": "v1",
             "AttachmentCount": 1,
             "PermissionsBoundaryUsageCount": 0,
             "IsAttachable": true,
             "CreateDate": "2024-08-11T19:24:10+00:00",
             "UpdateDate": "2024-08-11T19:24:10+00:00",
             "Tags": []
         }
     }
    
  5. 정책 내용 확인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    
     aws iam get-policy-version --policy-arn $policy_arn --version-id v1
    
     # 결과 (정책이 모두 잘 부여되어있음)
     {
         "PolicyVersion": {
             "Document": {
                 "Version": "2012-10-17",
                 "Statement": [
                     {
                         "Effect": "Allow",
                         "Action": [
                             "s3:GetObject",
                             "s3:PutObject",
                             "s3:DeleteObject",
                             "s3:ListBucket"
                         ],
                         "Resource": [
                             "arn:aws:s3:::weasel-images",
                             "arn:aws:s3:::weasel-images/*"
                         ]
                     },
                     {
                         "Effect": "Allow",
                         "Action": [
                             "secretsmanager:GetSecretValue",
                             "secretsmanager:PutSecretValue",
                             "secretsmanager:DescribeSecret",
                             "secretsmanager:CreateSecret",
                             "secretsmanager:DeleteSecret",
                             "secretsmanager:ListSecrets",
                             "secretsmanager:TagResource"
                         ],
                         "Resource": "*"
                     },
                     {
                         "Effect": "Allow",
                         "Action": [
                             "bedrock:InvokeModel",
                             "bedrock:ListModels"
                         ],
                         "Resource": "*"
                     }
                 ]
             },
             "VersionId": "v1",
             "IsDefaultVersion": true,
             "CreateDate": "2024-08-11T19:24:10+00:00"
         }
     }
    

Kubernetes Service Account 확인

Service Account 확인

1
2
3
4
5
6
7
8
9
❯ kubectl describe serviceaccount -n weasel weasel-eks-pod-sa
Name:                weasel-eks-pod-sa
Namespace:           weasel
Labels:              app.kubernetes.io/managed-by=eksctl
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::393035689023:role/weasel-eks-pod-role
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

Pod에 Service Account 부여 후 확인

테스트를 위해 Service Account가 부여된 Pod를 생성 후 확인했습니다.

  1. Service Account를 가진 pod 생성 ```yaml apiVersion: v1 kind: Pod metadata: name: aws-cli-pod namespace: weasel spec: serviceAccountName: weasel-eks-pod-sa containers:
    • name: aws-cli-container image: amazon/aws-cli:2.0.30 command: [“/bin/bash”, “-c”, “while true; do sleep infinity; done;”] ```
  2. pod 내부에 접속 후, aws-cli를 통해 실제 aws 리소스에 접근 가능한지 확인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
     # pod 식별
     ❯ kubectl get pods -n weasel
     NAME                              READY   STATUS             RESTARTS         AGE
     aws-cli-pod                       1/1     Running            0                5m46s
        
     # pod 내부 shell 접속 후 확인
     ❯ k exec -it aws-cli-pod -- /bin/bash
     bash-4.2# aws secretsmanager list-secrets
     {
         "SecretList": [
             {
                 "ARN": "arn:aws:secretsmanager:us-east-1:393035689023:secret:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                 "Name": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                 "Description": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                 "LastChangedDate": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                 "LastAccessedDate": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                 "Tags": [],
                 "SecretVersionsToStages": {
                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx": [
                         "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                     ],
                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx": [
                         "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                     ]
                 },
                 "CreatedDate": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
             },
    
  3. 생성

    1
    2
    
     ❯ k apply -f test-sa-nginx-deploy.yaml
     deployment.apps/test-sa-nginx-deploy created
    
  4. Pod가 사용 중인 IAM 역할의 arn 확인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
     # pod이름 식별
     ❯ kubectl get pods -n weasel
     NAME                              READY   STATUS             RESTARTS         AGE
     aws-cli-pod                       1/1     Running            0                5m46s
        
     # 역할 arn 확인
     ❯ kubectl describe pod aws-cli-pod | grep AWS_ROLE_ARN:
        
           AWS_ROLE_ARN:                 arn:aws:iam::393035689023:role/weasel-eks-pod-role
    
  5. Pod에 웹 ID 토큰 파일이 탑재되었는지 확인
    1
    2
    3
    
     ❯ kubectl describe pod aws-cli-pod | grep AWS_WEB_IDENTITY_TOKEN_FILE:
        
           AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    

궁금하신 점이나 추가해야 할 부분은 댓글이나 아래의 링크를 통해 문의해주세요.
Written with KKam._.Ji

This post is licensed under CC BY 4.0 by the author.