Kubernetes ServiceAccount와 IRSA : EKS에서의 권한 관리

이숭늉·2025년 7월 2일
0

DevOps

목록 보기
16/19
post-thumbnail

🔐 Kubernetes ServiceAccount와 IRSA : EKS에서의 권한 관리

이전에 ALB Controller 등을 EKS에 설치하면서 서비스 어카운트와 IRSA 등을 사용한 적이 있다. 그때도 '이게 정확히 뭐지?' 하면서 찾아보았을텐데, 매번 이 개념을 다시 접할 때마다 잘 기억이 나지 않아 계속해서 다시 찾아보게 되었다. 그래서 이번에 확실히 개념을 정리해두고자 한다. 다음엔 나의 기억 속에서 찾아낼 수 있기를 바라며.... 이번 글에서는 이와 관련된 개념인 ServiceAccount, RBAC, 그리고 AWS EKS에서의 IRSA까지 하나씩 살펴볼 것이다.


🔑 Service Account란?

Kubernetes에서 Pod는 실제로 어떤 작업을 수행하기 위해 인증 주체가 필요하다. 이 역할을 담당하는 것이 바로 ServiceAccount이다.
즉, ServiceAccount는 K8s 클러스터 내에서 Pod가 인증된 요청을 보낼 수 있도록 하는 계정이다.

  • 각 네임스페이스마다 default라는 기본 ServiceAccount가 자동으로 생성된다.
  • Pod에 별도로 SA를 지정하지 않으면, Pod는 자동으로 이 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

Role과 RoleBinding : 권한을 어떻게 줄까?

K8s RBAC 모델에서는 다음 두 리소스를 통해 권한을 구성한다.

  • Role : 어떤 리소스에 대해 어떤 동작을 할 수 있는가?
  • RoleBinding : 누가 해당 Role을 사용할 수 있는가?
    아래 예시처럼, 특정 SA에 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 정보를 조회할 수 있다.

☁️ IRSA (IAM Roles for Service Accounts)

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 없이 AWS 리소스 접근 시

IRSA를 구성하지 않으면, Pod는 기본적으로 자신이 실행 중인 노드의 IAM Role을 사용한다. 즉, 해당 EC2 인스턴스의 IAM Role이 S3, EBS 권한을 갖고 있다면, 그 노드에서 실행 중인 모든 Pod가 같은 권한을 공유하게 된다.

하지만, 이 방식은 다음과 같은 보안 문제를 일으킬 수 있다.

  • 모든 Pod가 동일한 IAM Role을 공유 -> S3, EBS 등 민감한 리소스에 모두 접근 가능.
  • 실수로 특정 Pod에 과한 권한이 열려 있을 수 있음.
  • 보안 사고 발생 시, 어떤 Pod가 무슨 권한을 사용했는지 추적하기 어려움.

이 때문에 AWS는 전용 ServiceAccount + 전용 IAM Role을 사용한 IRSA 구성을 강력히 권장하고 있다.

예시 : CSI Driver

IRSA의 대표적인 사용 예시가 EBS CSI Driver, EFS CSI Driver와 같은 스토리지 드라이버이다. 이 드라이버들은 다음과 같은 작업을 수행하기 위해 실제로 AWS API를 호출한다.

  • EBS 볼륨을 생성, 삭제
  • EBS 볼륨 마운트
  • EFS 파일 시스템 연결
  • ENI 설정 등

이런 작업을 위해서는 IAM 권한이 반드시 필요하다.

IRSA 자동 연결 : Terraform + AddOn

이때, 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  # 이 부분이 핵심!
}

세부 흐름은 이러하다.

  1. EKS는 kube-system 네임스페이스에 CSI 드라이버용 Pod및 ServiceAccount를 자동 생성한다.

  2. 내가 생성한 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
  3. 결과적으로, CSI Pod는 해당 SA를 통해 IAM Role을 Assume하고, EBS 등 필요한 AWS API를 호출할 수 있게 된다.

profile
부지런히 살자

0개의 댓글