EKS pod가 AWS에 로그인하는 방법: IRSA, Pod Identity
EKS 환경에서 각 pod는 어떻게 AWS 로그인을 하는걸까?
- pod의 인스턴스 서버상, AWS SDK를 import할 뿐 ACCESS_KEY, SECRET_ACCESS_KEY 등의 값은 환경 변수로 지정하지 않은 상태에서 AWS 호출이 가능함
1. 배경 지식
k8s는 기본적으로 Pod에게 권한 정체성(identity)를 부여하기 위해서 ServiceAccount(SA) 라는 것을 만든다. k8s의 deployment를 만들 때 별도로 지정하지 않으면 자동으로 default ServiceAccount를 Pod에 붙여준다. 이 SA는 k8s 내부적으로 서로 인증하기 위해서 사용하는 용도이다.
2. IRSA(IAM Role for ServiceAccount)
다만, 여기에 IRSA라는 방식을 적용하면 k8s 내부의 특정 SA가 AWS의 특정 IAM Role을 갖도록 만들 수 있다. 대략 아래와 같은 방식으로 SA에 설정해주면 된다.
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/my-aws-role
이렇게 지정해놓으면 EKS는 해당 SA를 사용하는 Pod가 뜰 때 Pod안에 WebIdentityToken 파일을 생성한다. 그리고 Pod안에 아래 방식의 env를 자동으로 주입한다.
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/....
AWS_ROLE_ARN=arn:aws:iam::....:role/my-aws-role
그리고는 AWS SDK가 동작하면서 STS에게 아래처럼 요청하면, AWS STS가 임시 AccessKey/SecretKey/SessionToken을 발급한다.
AssumeRoleWithWebIdentity(RoleArn=my-aws-role, WebIdentityToken=...)
3. Pod Identity
IRSA 방식은 클러스터마다 IAM Role을 계속 따로 생성해야한다. EKS는 클러스터를 생성할 때 고유한 OIDC Issuer URL이 생기는데 이 URL이 클러스터마다 다르고, 그 정보가 IAM Role에 연결되기 때문이다.
따라서 여러 클러스터(dev/stg/prd)가 있거나 클러스터 버전 업그레이드로 이전이 필요할 때마다 변경해야하고 관리해야하므로 유지보수가 번거롭다. 이를 대체하기 위한 기술이 Amazon EKS Pod Identity이다.
이 기술은 클러스터마다 OIDC가 필요없고 ServiceAccount annotation을 지정할 필요도 없다. Pod Identity Agent라는 EKS내의 DaemonSet을 만들어서 Pod가 AWS API 호출을 할 때 인증 토큰을 주고 받는 중계자 역할을 하게한다. 그리고 Pod Identity Association 방식으로, k8s ServiceAccount와 IAM Role간의 매핑을 EKS Control Plane에서 직접 관리하는 리소스로 만들어준다.