이전에 ALB Controller 등을 EKS에 설치하면서 서비스 어카운트와 IRSA 등을 사용한 적이 있다. 그때도 '이게 정확히 뭐지?' 하면서 찾아보았을텐데, 매번 이 개념을 다시 접할 때마다 잘 기억이 나지 않아 계속해서 다시 찾아보게 되었다. 그래서 이번에 확실히 개념을 정리해두고자 한다. 다음엔 나의 기억 속에서 찾아낼 수 있기를 바라며.... 이번 글에서는 이와 관련된 개념인 ServiceAccount, RBAC, 그리고 AWS EKS에서의 IRSA까지 하나씩 살펴볼 것이다.
Kubernetes에서 Pod는 실제로 어떤 작업을 수행하기 위해 인증 주체가 필요하다. 이 역할을 담당하는 것이 바로 ServiceAccount이다.
즉, ServiceAccount는 K8s 클러스터 내에서 Pod가 인증된 요청을 보낼 수 있도록 하는 계정이다.
default
라는 기본 ServiceAccount가 자동으로 생성된다.default
SA를 사용한다. default
SA는 Role이 바인딩되어 있지 않기 때문에 아무런 권한이 없어, 대부분의 K8s API 요청은 거부된다.→ 권한을 부여하려면? 전용 ServiceAccount를 만들고, 필요한 Role을 연결해줘야 한다.
# 특정 SA를 사용하는 Pod
apiVersion: v1
kind: Pod
metadata:
name: custom-pod
spec:
serviceAccountName: ebs-csi-controller-sa
containers:
- name: mycontainer
image: myimage
K8s RBAC 모델에서는 다음 두 리소스를 통해 권한을 구성한다.
pods
리소스의 조회 권한을 부여할 수 있다.apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
kind: ServiceAccount
metadata:
name: web-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: default
subjects:
- kind: ServiceAccount
name: web-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
이제 web-sa
라는 ServiceAccount를 사용하는 Pod는 클러스터 내에서 pods
정보를 조회할 수 있다.
Kubernetes RBAC는 K8s 리소스에 대해서만 통제할 수 있다. 하지만, EKS에서는 Pod가 S3에서 객체를 가져오거나, EBS 볼륨을 마운트하는 등, AWS 리소스에 접근할 필요가 있는 경우가 많다.
이런 경우에는 AWS IAM 권한이 필요하다. 그래서 등장한 것이 바로 IRSA(IAM Roles for Service Accounts)이다.
IRSA란, Kubernetes의 ServiceAccount에 AWS IAM Role을 연결하여, Pod가 IAM Role을 Assume하고 AWS 리소스에 접근할 수 있도록 해주는 기능이다.
IRSA를 구성하지 않으면, Pod는 기본적으로 자신이 실행 중인 노드의 IAM Role을 사용한다. 즉, 해당 EC2 인스턴스의 IAM Role이 S3, EBS 권한을 갖고 있다면, 그 노드에서 실행 중인 모든 Pod가 같은 권한을 공유하게 된다.
하지만, 이 방식은 다음과 같은 보안 문제를 일으킬 수 있다.
이 때문에 AWS는 전용 ServiceAccount + 전용 IAM Role을 사용한 IRSA 구성을 강력히 권장하고 있다.
IRSA의 대표적인 사용 예시가 EBS CSI Driver, EFS CSI Driver와 같은 스토리지 드라이버이다. 이 드라이버들은 다음과 같은 작업을 수행하기 위해 실제로 AWS API를 호출한다.
이런 작업을 위해서는 IAM 권한이 반드시 필요하다.
이때, EKS에서는 이 과정을 간소화할 수 있도록 aws_eks_addon
리소스를 제공한다.
aws_eks_addon
리소스를 사용해서 설치할 경우, IRSA를 직접 구성하지 않아도 된다.
다음과 같이 구성할 수 있다.
resource "aws_eks_addon" "ebs_csi_driver" {
cluster_name = var.cluster_name
addon_name = "aws-ebs-csi-driver"
addon_version = var.ebs_csi_driver_version
service_account_role_arn = aws_iam_role.ebs_csi_role.arn # 이 부분이 핵심!
}
세부 흐름은 이러하다.
EKS는 kube-system
네임스페이스에 CSI 드라이버용 Pod및 ServiceAccount를 자동 생성한다.
내가 생성한 ebs_csi_role
에 IRSA용 OIDC 신뢰 정책이 제대로 되어 있다면, EKS가 해당 SA에 IRSA용 IAM Role ARN 어노테이션을 자동으로 붙인다.
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/ebs-csi-role
결과적으로, CSI Pod는 해당 SA를 통해 IAM Role을 Assume하고, EBS 등 필요한 AWS API를 호출할 수 있게 된다.