Hyesung Oh

AWS EKS의 RBAC, IRSA 딥다이브 본문

Data Engineering/DevOps

AWS EKS의 RBAC, IRSA 딥다이브

혜성 Hyesung 2022. 5. 31. 12:07
반응형

EKS의 권한 제어 관련해서 궁금했던게 많았던 터라 공부하면서 내 나름대로 이해한 내용을 정리해보았다.


RBAC (role based access control)
K&8에서 정의할 수 있는 리소스 객체들을 이용하여 접근 제어를 하는 개념이다. 아래 리소스들을 사용한다.

  • Role
  • RoleBinding
  • ServiceAccount

Role이 binding된 (RoleBinding을 통해) ServiceAccount를 Pod에 할당함으로서 Pod는 지정된 Role을 사용할 수 있다. 이는 ServiceAcocunt 뿐만 아니라 User에도 동일하게 적용할 수 있다.

예제를 통해 작동원리에 대해 더 자세히 이해해보자.

개발자 A(아래 그림에서 test-user)가 kubernetes 클러스터의 특정 namespace redash에 접근할 수 있도록 제어하는 과정


1. 개발자 A가 맡을 IAM Role을 생성
2. 개발자 A의 워크스테이션에서 아래 명령어 실행하여 k&8 API에 접근할 때 항상 1에서 생성한 IAM Role을 사용하도록 구성

$ aws eks update-kubeconfig --name yourClusterName --role-arn arn:aws:iam::yourAccountID:role/yourIAMRoleName

3. 1에서 생성된 IAM 역할에 아직 클러스터에 대한 액세스 권한이 부여되지 않은 상태이므로, Role 생성

  1. Note: 클러스터 역할(ClusterRole)을 역할 바인딩(**RoleBinding)**에 바인딩할 수 있음. 하지만 역할(**Role)**을 클러스터 역할 바인딩(ClusterRoleBinding)에 바인딩할 수는 없음
# role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: k8s-redash-role
  namespace: redash
rules:
  - apiGroups:
      - ""
      - "apps"
      - "batch"
      - "extensions"
    resources:
      - "configmaps"
      - "cronjobs"
      - "deployments"
      - "events"
      - "ingresses"
      - "jobs"
      - "pods"
      - "pods/attach"
      - "pods/exec"
      - "pods/log"
      - "pods/portforward"
      - "secrets"
      - "services"
    verbs:
      - "create"
      - "delete"
      - "describe"
      - "get"
      - "list"
      - "patch"
      - "update"

 

$ kubectl apply -f role.yaml

4. RoleBinding에 위에서 생성한 k8s-redash-role Role을 binding

# rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: k8s-redash-role
  namespace: redash
subjects:
- kind: User
  name: k8s-redash-user
roleRef:
  kind: Role
  name: k8s-redash-role
  apiGroup: rbac.authorization.k8s.io

Note: RoleBinding에 위에서 생성한 k8s-redash-role Role을 bindingNote 역할 바인딩은 roleRef 섹션의 RBAC 역할을 subjects 섹션의 사용자에게 바인딩하는 네임스페이스 리소스. Kubernetes에는 리소스 유형 사용자가 없으므로 사용자 k8s-redash-user를 생성할 필요없음

RoleBinding 생성

$ kubectl apply -f rolebinding.yaml

5. aws-auth ConfigMAP을 사용하여 IAM 역할을 RBAC 역할 및 그룹에 매핑. 1에서 생성한 IAM 역할 yourIAMRoleName을 Kubernetes 사용자 k8s-redash-user와 연결하려면 다음 명령을 실행
Note
- 클러스터 생성자 또는 클러스터 생성에 사용한 역할의 ARN으로만 아래 작업을 진행 가능
- Terraform을 이용한 aws-auth configmap 관리 방법에 대해선 이전 포스트를 참고

eksctl create iamidentitymapping --cluster yourClusterName --arn arn:aws:iam::yourAccountID:role/yourIAMRoleName --username k8s-redash-user

6. namespace redash에 접근이 잘되는지 테스트

IRSA (IAM Role Service Account)
ServiceAccount와 IAM Role을 매핑하기 위해 AWS에서 제공하는 서비스
예를 들어, K&8네 Pod가 AWS 특정 리소스에 접근하고자 할 때, AWS에서는 IAM policy가 연결된 Role을 부여함으로서 접근을 허용할 수 있다. 이때, ServiceAccount와 IAM Role을 연결시켜주는 것이 IRSA 서비스이다. ISRA를 통해 지정한 IAM Role과 매핑된 ServiceAccount를 Pod에 할당함으로서 Pod는 AWS Resource에 대해서 접근 및 허용된 작업을 진행할 수 있게된다.

간략히 요약하면, OpenID Connector(OIDC) Identity Provider와 STS를 활용하여 쿠버네티스의 Service Account에 IAM Role을 할당(?)할 수 있게 하는 방식으로 동작한다.

마찬가지로 예제를 통해 IRSA 작동 방식을 이해해보자

1. 위 그림의 2~5번 과정
Pod 생성시, K8s API 서버로부터 EKS Pod Identity Webhook으로 Manifest를 전달. Pod Identity Webhook은 해당 Pod에 설정한 ServiceAccount에 'eks.amazonaws.com/role-arn' annotation이 존재할 경우, OIDC로부터 ServiceAccount을 인증, projectedServiceAccountToken 기능을 이용하여 IAM Role 관련 환경변수(AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE)를 Injection한다. 또한 JWT 토큰을 저장할 'aws-iam-token' 볼륨을 Pod에 마운트한다.

2. 5~6번 과정
AWS 리소스 접근시, 'AWS_WEB_IDENTITY_TOKEN_FILE' 경로의 토큰으로 'sts:assume-role-with-web-identity'를 수행하여 IAM Role을 획득한다.

+ 보충설명

AWS SDK는 AWS_ROLE_ARN 및 AWS_WEB_IDENTITY_TOKEN_FILE 라는 이름의 환경변수 값이 설정되어 있을 경우 해당 환경변수를 읽어들여 Web Identity 토큰으로 Assume Role을 시도.
즉, $(AWS_ROLE_ARN) 라는 역할을 Assume하기 위한 자격 증명으로서 $(AWS_WEB_IDENTITY_TOKEN_FILE) 경로의 Web Identity 토큰 파일을 사용하겠다는 뜻.
포드 내부의 AWS SDK는 이 토큰을 통해 AssumeRoleWithWebIdentity를 호출함으로써 임시 자격 증명을 획득하게 되고, 비로소 특정 IAM 역할로 변신

EKS Node Autoscaler Pod가 AWS Resource에 접근할 수 있도록 제어하려면?
*개발자는 1~4번 과정까지만 관여

1. 해당 AWS Resource 접근에 필요한 IAM Policy 생성
2. ServiceAccount 생성
3. AWS EKS IRSA 사용해서 ServiceAccount와 IAM Role을 연결

eksctl create iamserviceaccount \\
                --name yourServiceAccountName \\
                --namespace yourNameSpace \\
                --cluster yourClusterName \\
                --attach-policy-arn arn:aws:iam::199137616366:policy/yourIAMPolicyName \\
                --approve \\
                --region ap-northeast-2

4. ServiceAccount를 Deployment에 사용
5. Pod생성시 Pod Identity Webhook이 ServiceAccount에 대한 OIDC 인증 후 Pod에 id token 주입
6. Pod가 AWS Sdk를 사용하여 AWS Resource에 접근할 때 id token을 사용하여 assume role

 

이상으로 글을 마치겠으며 피드백은 댓글로 부탁드립니다.

 

Reference

반응형
Comments