일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 블로그
- Spark structured streaming
- redis bloom filter
- dataengineer
- mlops
- DataEngineering
- pyspark
- hadoop
- 클라우데라
- 추천시스템
- Data engineering
- 개발자혜성
- 빅데이터
- cloudera
- eks
- 개발자
- BigData
- 데이터엔지니어
- AWS SageMaker
- recommendation system
- kafka
- Terraform
- spark
- 하둡
- apache spark
- 하둡에코시스템
- Python
- 빅데이터플랫폼
- 데이터엔지니어링
- kubernetes
- Today
- Total
Hyesung Oh
AWS EKS의 RBAC, IRSA 딥다이브 본문
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 생성
- 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
'Data Engineering > DevOps' 카테고리의 다른 글
Dockerfile Reference 문서를 읽고 나름대로 정리한 중요한 포인트들 (0) | 2022.09.28 |
---|---|
Kubernetes에서 Open Source Redash Helm Chart로 운영하기 (0) | 2022.05.12 |
Terraform으로 AWS EKS의 aws-auth configmap 관리하기 (0) | 2022.04.28 |
Terraform 입문하기 (0) | 2021.01.28 |