EKS에서 권한 관리 중에 Node, 클러스터, IAM User에 대한 권한 관리도 있지만 POD에 대한 권한 관리도 할 수 있다.

POD에게 권한을 부여하는 방식은 여럿 있다.

  • EC2 Instance Profile

    ⇒ EC2 Instance에 Role을 부여하게 됨으로써 최소 권한 원칙에 어긋나게 된다. 해당 노드에 있는 파드는 다 같은 권한을 사용할 수 있기 때문!

  • AccessKey, SecretKey

    ⇒ 키 탈취, 키 관리 등으로 인해 Access Key 사용은 지양한다.

  • Assume Role

    ⇒ POD가 특정 IAM Role로 Assume할 수 있다. 이 부분이 IRSA (IAM Roles for Service Accounts)이다.

EKS IRSA

EKS IRSA는 POD가 특정 IAM Role로 Assume할 때, 토큰을 AWS에 전송하고 AWS는 토큰과 EKS IdP를 통해 해당 IAM Role을 사용할 수 있는지 검증한다.

EC2 Instance Profile과 유사하게 자격증명을 통해 IAM Role을 사용하는 것인데 다른 점은 대상이 Node에서 POD로 축소됐다는 점이다.

EKS IRSA의 장점으로는 세 가지가 있다.

  • 최소 권한 원칙
  • 자격 증명의 격리(Credential Isolation)
    • SDK의 Credential Provider Chain를 사용하게 되면 CloudTrail에 node의 역할로 찍힘
    • 누가 어떤 일을 했는지에 대한 분리가 됨
  • 감사(Auditability)

IRSA는 OIDC(OpenID Connect) 공급자를 사용하여 자격 증명을 할 수 있다. 이 기능을 사용하면 AWS API 호출을 인증하고 유효한 OIDC JWT 토큰을 받을 수 있다. 이 토큰을 AWS STS AssumeRoleWithWebIdentity에 전달하고 IAM 임시 역할 자격 증명을 받을 수 있다.

Untitled

[Diving into IAM Roles for Service Accounts Amazon Web Services](https://aws.amazon.com/ko/blogs/containers/diving-into-iam-roles-for-service-accounts/)

실습

IRSA는 eksctl create iamserviceaccount 명령어 한 줄로 가능하다.

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)

AmazonS3ReadOnlyAccess 정책을 붙인 IRSA를 생성하였다.

이는 Cloudformation으로 자동으로 생성되고

Untitled 1

default 네임스페이스에 my-sa 이름으로 IRSA 하나가 생성되었다.

Untitled 2

해당 SA에 자동으로 Role이 생성되었는데 이를 확인해 보면

Condition에 sts.amazonaws.comsystem:serviceaccount:default:my-sa 값이 일치해야 한다는 조건이 생겼다.

또한 sts:AssumeRoleWithWebIdentity이 실행된 것도 알 수 있었다.

신규 POD를 만들어 테스트해 보자!

이 POD에는 위에 생성한 SA를 설정했다.

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

pod-identity-webhookmutating webhook을 통해 아래 Env 내용과 볼륨 하나를 추가했다. pod-identity-webhook은 POD를 생성할 수 있는 권한을 가지고 있다.

  • ENV ⇒ 사용할 Role과 토큰 값이 설정되었다.

    Untitled 3

  • aws-iam-token 볼륨 ⇒ 86400초인 24시간 동안 유효한 토큰을 사용할 수 있다.

    Untitled 4

    Untitled 5

POD 내부에서 명령을 실행해 보면

  • get-caller-identity 실행이 가능하다

    Untitled 6

  • AmazonS3ReadOnlyAccess 정책대로 실행된다.

    Untitled 7

EKS Pod Identity

IRSA는 신뢰정책에 system:serviceaccount:*:*가 들어 있으면 토큰만 검증받으면 또 다른 검증없이 모든 SA에게 동일한 권한을 부여할 수 있다.

Untitled 8

더불어 OIDC의 엔드포인트는 퍼블릭이기에 보안에 취약할 수 있다.

그래서 SA가 가지고 있는 토큰 값과 Role ARN만 알면 STS 임시자격증명 발급을 요청할 수 있고

# IAM_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
# eksctl get iamserviceaccount --cluster $CLUSTER_NAME
NAMESPACE       NAME                            ROLE ARN
default         my-sa                           arn:aws:iam::**:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-sEMLKoOub24T
# ROLE_ARN=arn:aws:iam::**:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-sEMLKoOub24T
# aws sts assume-role-with-web-identity --role-arn $ROLE_ARN --role-session-name mykey --web-identity-token $IAM_TOKEN | jq

Untitled 9

얻어낸 키, 토큰, 역할로 보안에 취약해 질 수 있다.

그래서 출시된게 EKS Pod Identity 라고 한다.

EKS Pod Identity는 기존의 IRSA보다 더 편하게 사용할 수 있게 발전된 형태로 만들어졌다.

  1. 신뢰 정책에서 pods.eks.amazonaws.com을 서비스 주체로 지정한다.
  2. EKS 콘솔 또는 aws cli로 Amazon EKS Pod Identity Agent 추가 기능을 설치한다.
  3. EKS 콘솔 또는 aws cli로 SA에 Role을 매핑한다.

설정은 다를게 없어 보인다고 해도 적용되는 방식은 간소화됐다.

Untitled

[Amazon EKS Pod Identity: a new way for applications on EKS to obtain IAM credentials Amazon Web Services](https://aws.amazon.com/ko/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/)

실습

EKS 콘솔 혹은 aws cli로 addon을 설치한다.

  • aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name eks-pod-identity-agent
  • eksctl create addon --cluster $CLUSTER_NAME --name eks-pod-identity-agent *--version 1.2.0*

Untitled 11

eks-pod-identity-agent는 데몬셋으로 생성되어 hostNetwork를 사용한다.

Untitled

EKS Pod Identity Agent는 hostNetwork를 통해 링크 로컬 169.254.170.23 주소와 80, 2703 포트를 사용한다.

Untitled 13

이제 사용해 보자면

aws cli로 podidentityassociation를 생성한다.

eksctl create **podidentityassociation** \
--cluster $CLUSTER_NAME \
--namespace **default** \
--service-account-name **s3-sa** \
--role-name **s3-eks-pod-identity-role** \
--**permission-policy-arns** arn:aws:iam::aws:policy/**AmazonS3ReadOnlyAccess** \
--region $AWS_REGION

Untitled 14

신뢰 관계를 보면 AssumeRole과 TagSession이 들어가 있다.

“sts:AssumeRole”, “sts:TagSession”

TagSession을 통해 ABAC 설정이 가능하다.

Untitled 15

이제 테스트 SA와 POD를 생성해 보겠다!

kubectl create sa s3-sa

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: **eks-pod-identity**
spec:
  serviceAccountName: s3-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

POD를 생성하면 sa가 podidentityassociation을 통해 AmazonS3ReadOnlyAccess에 연결되어 있기 때문에 아래와 같이 ENV와 토큰 볼륨이 생성된 것을 알 수 있다.

Untitled

아래와 같이 POD에서 S3 조회가 가능하다!

Untitled 17

POD Identity는 좀 더 편리한 방식으로 변경되었지만

작년에 나온 신기능이라서 아직 고려할 부분이 좀 있다

  • SDK 지원되는 버전을 고려해야 하고
  • 링크 로컬 주소 169.254.170.23가 사용 가능한지 확인해야 하고
  • Node의 IAM Policy에서 Action에 eks-auth:AssumeRoleForPodIdentity이 있는지 확인해야 하고
  • Linux EC2만 지원되며
  • EKS 클러스터 버전도 고려해야 한다.
  • 또한 Amazon VPC CNI plugin, AWS Load Balancer Controller, 몇몇 CSI storage drivers가 지원되지 않아 IRSA를 사용해야 한다.

추후에는 태깅을 잘 설정해서 ABAC으로 사용해 보고 싶다!

Categories:

Updated:

Leave a comment