Skip to main content Link Menu Expand (external link) Document Search Copy Copied

IRSA 실습

IRSA

IRSA는 쿠버네티스의 서비스 어카운트(Service Account, SA)와 AWS IAM 역할(Role)을 연결하는 방법이다. 기본적으로 쿠버네티스의 파드는 AWS 리소스(S3, DynamoDB 등)에 직접 접근할 수 없으며, AWS의 보안 정책에 따라 IAM 권한을 부여해야 한다.

기존에는 EC2 인스턴스에 IAM Role을 붙이는 방식을 사용했지만 이는 세분화된 권한 관리를 어렵게 만든다.

IRSA를 사용하면 파드 단위로 IAM 권한을 부여할 수 있어 보안성과 유연성이 증가한다.

  • 불필요한 권한을 줄일 수 있음 → 특정 Pod에만 필요한 AWS 리소스 접근 권한을 부여 가능
  • 멀티테넌시 환경에서 보안 강화 → 동일한 클러스터 내에서도 애플리케이션(파드)별로 다른 IAM 정책을 적용 가능
  • IAM 정책 적용이 파드 수준으로 내려감 → 개발자가 직접 관리 가능

sa

eksctl create iamserviceaccount \
  --name my-sa \
  --namespace default \
  --cluster $CLUSTER_NAME \
  --approve \
  --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3ReadOnlyAccess`].Arn' --output text)
 
kubectl describe sa my-sa
Name:                my-sa
Namespace:           default
Labels:              app.kubernetes.io/managed-by=eksctl
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test3
spec:
  serviceAccountName: my-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF
kubectl get pod eks-iam-test3 -o yaml
...
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-dccvr
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
...
   volumes:
  - name: aws-iam-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
 kubectl describe pod eks-iam-test3
 ...
    Environment:
      AWS_STS_REGIONAL_ENDPOINTS:   regional
      AWS_DEFAULT_REGION:           ap-northeast-2
      AWS_REGION:                   ap-northeast-2
      AWS_ROLE_ARN:                 arn:aws:iam::~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP
      AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    Mounts:
      /var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dccvr (ro)
kubectl exec -it eks-iam-test3 -- aws sts get-caller-identity --query Arn
"arn:aws:sts::~~:assumed-role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP/botocore-session-1742074654"

eks-iam-test3 파드는 my-service-account라는 서비스 어카운트를 사용하고 있고 AWS IAM Role과 연결되어 있다.

파드가 실행되면 AWS IAM STS(Security Token Service)에서 토큰을 받아서 IAM Role을 Assume할 수 있고 이 과정을 통해 파드는 IAM Role의 권한을 사용하여 AWS 리소스에 접근할 수 있다.

IAM 인증 토큰 설정과 Mutating Webhook 확인

kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].volumeMounts'
[
  {
    "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
    "name": "kube-api-access-dccvr",
    "readOnly": true
  },
  {
    "mountPath": "/var/run/secrets/eks.amazonaws.com/serviceaccount",
    "name": "aws-iam-token",
    "readOnly": true
  }
]

kube-api-access-dccvr:

  • 쿠버네티스 기본 서비스 어카운트(SA) 토큰을 저장하는 디렉토리(/var/run/secrets/kubernetes.io/serviceaccount)
  • 파드가 쿠버네티스 API 서버와 통신하는 데 사용된다.

aws-iam-token:

  • IRSA를 통해 AWS STS 토큰을 저장하는 디렉토리(/var/run/secrets/eks.amazonaws.com/serviceaccount)
  • 이 토큰을 사용하여 IAM Role을 Assume하여 AWS 리소스에 접근 가능하다.
kubectl get pod eks-iam-test3 -o json | jq -r '.spec.volumes[] | select(.name=="aws-iam-token")'
{
  "name": "aws-iam-token",
  "projected": {
    "defaultMode": 420,
    "sources": [
      {
        "serviceAccountToken": {
          "audience": "sts.amazonaws.com",
          "expirationSeconds": 86400,
          "path": "token"
        }
      }
    ]
  }
}

IAM STS 토큰 설정

  • audience: “sts.amazonaws.com” → AWS STS(Security Token Service)에서 사용할 IAM 인증 토큰
  • expirationSeconds: 86400 → 토큰 만료 시간(24시간)
  • path: “token” → Pod 내부에서 /var/run/secrets/eks.amazonaws.com/serviceaccount/token 경로에 토큰이 저장된다.
kubectl get MutatingWebhookConfiguration
NAME                            WEBHOOKS   AGE
pod-identity-webhook            1          6h37m
vpc-resource-mutating-webhook   1          6h37m

쿠버네티스에서 파드가 생성될 때 자동으로 특정 설정을 추가할 수 있도록 하는 웹훅이다.

만약 파드 생성 요청이 들어오면 Mutating Webhook이 이를 가로채서 볼륨 마운트, 환경 변수 추가와 같은 추가 설정을 적용한다.

파드에 IAM 롤 설정 확인

kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].env'
 
[
  {
    "name": "AWS_STS_REGIONAL_ENDPOINTS",
    "value": "regional"
  },
  {
    "name": "AWS_DEFAULT_REGION",
    "value": "ap-northeast-2"
  },
  {
    "name": "AWS_REGION",
    "value": "ap-northeast-2"
  },
  {
    "name": "AWS_ROLE_ARN",
    "value": "arn:aws:iam::~~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP"
  },
  {
    "name": "AWS_WEB_IDENTITY_TOKEN_FILE",
    "value": "/var/run/secrets/eks.amazonaws.com/serviceaccount/token"
  }
]
  • IAM Role (AWS_ROLE_ARN)이 할당되어 있다.
  • STS 토큰 파일 (AWS_WEB_IDENTITY_TOKEN_FILE)이 /var/run/secrets/eks.amazonaws.com/serviceaccount/token에 존재한다.
  • 파드 내부에서 STS 토큰을 이용하여 AWS IAM Role을 Assume할 수 있음

파드 내부 STS 인증 토큰 확인

IAM_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
echo $IAM_TOKEN

파드 내부에서 이 토큰을 AWS STS에 제출하여 해당 IAM Role로 AWS API를 호출할 수 있다.

OIDC 설정 정보 확인

curl -s $IDP/.well-known/openid-configuration | jq -r '.'
{
  "issuer": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/XXXXXXXXX",
  "jwks_uri": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/XXXXXXXXX/keys",
  "authorization_endpoint": "urn:kubernetes:programmatic_authorization",
  "response_types_supported": [
    "id_token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "claims_supported": [
    "sub",
    "iss"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ]
}

EKS는 OIDC를 지원하며 OIDC 기반 인증을 통해 AWS IAM 역할을 파드에 부여할 수 있다.

JWKS URL을 통해 공개 키를 제공하며 AWS STS는 이를 사용하여 OIDC 토큰의 유효성을 검증하는데, 이 정보를 기반으로 EKS의 IRSA 가 동작하여 파드가 AWS 리소스에 접근할 수 있도록 한다.

리소스 삭제

kubectl delete pod eks-iam-test3
pod "eks-iam-test3" deleted
 
eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --name my-sa --namespace default
2025-03-16 06:48:14 [ℹ]  1 iamserviceaccount (default/my-sa) was included (based on the include/exclude rules)
2025-03-16 06:48:14 [ℹ]  1 task: {
    2 sequential sub-tasks: {
        delete IAM role for serviceaccount "default/my-sa" [async],
        delete serviceaccount "default/my-sa",
    } }2025-03-16 06:48:15 [ℹ]  will delete stack "eksctl-myeks-addon-iamserviceaccount-default-my-sa"
2025-03-16 06:48:15 [ℹ]  deleted serviceaccount "default/my-sa"