# aws-auth ConfigMap에서 EKS Access Entries로 - 되돌릴 수 없는 전환을 안전하게 하기

EKS에서 누가 클러스터에 들어올 수 있는지는 오랫동안 kube-system 네임스페이스의 ConfigMap 하나가 정했습니다. aws-auth입니다. IAM 역할과 Kubernetes 그룹을 매핑하는 YAML이고, 편집은 kubectl edit으로 합니다.

이 구조에는 잘 알려진 위험이 있습니다. 그 ConfigMap을 잘못 고치면 아무도 클러스터에 들어갈 수 없게 되고, 고치려면 클러스터에 들어가야 합니다. Access Entries는 이 권한 부여를 EKS API 쪽으로 옮겨 그 교착을 없앱니다.

문제는 전환이 한 방향이라는 점입니다. 이 글에서는 두 방식이 무엇이 다른지, 전환에서 자동으로 되는 것과 안 되는 것이 무엇인지, 그리고 어떤 순서로 옮겨야 잠기지 않는지 정리합니다.

# 1. ConfigMap 하나가 인증 경계인 구조의 문제

aws-auth가 만드는 문제는 편의성이 아니라 복구 가능성입니다.

교착. 매핑을 잘못 지우면 그 순간부터 kubectl이 거부됩니다. 되돌리려면 kubectl이 필요합니다. 남은 경로는 클러스터 생성 시점의 IAM 아이덴티티뿐인데, 그 역할이 폐기됐거나 사람이 퇴사했다면 경로가 없습니다.

감사 흔적. 누가 언제 권한을 바꿨는지가 ConfigMap 리소스 버전 말고는 남지 않습니다. IAM 권한 변경이 CloudTrail에 남는 것과 대비됩니다.

공동 편집. 여러 팀이 각자의 역할을 같은 ConfigMap에 추가합니다. IaC로 관리하면 서로의 항목을 덮어쓰기 쉽고, 그렇다고 수동으로 두면 Git에 없는 상태가 됩니다.

Access Entries는 이 셋을 한꺼번에 해결합니다. 문서가 정리한 이점 중 핵심은 이것입니다.

Misconfiguration Recovery: Allows restoring cluster access through the Amazon EKS API without direct Kubernetes API access.

Kubernetes API 없이 EKS API만으로 접근을 복구할 수 있습니다. 잘못 설정해도 잠기지 않습니다. 그리고 변경이 IAM 권한 체계와 CloudTrail 안으로 들어옵니다.

# 2. 세 가지 인증 모드, 그리고 한 방향 전환

클러스터에는 인증 모드가 셋 있습니다.

모드 aws-auth Access Entries
CONFIG_MAP 사용 사용 불가
API_AND_CONFIG_MAP 사용 사용
API 무시됨 사용

전환을 시작하려면 표의 뒤쪽 두 모드 중 하나로 가야 합니다.

To begin using access entries, you must change the authentication mode of the cluster to either the API_AND_CONFIG_MAP or API modes.

그리고 여기에 되돌릴 수 없다는 제약이 붙습니다.

Note that you can't change the authentication mode back to a mode that removes the EKS API and access entries.

CONFIG_MAPAPI_AND_CONFIG_MAPAPI 방향으로만 갑니다. API로 갔다가 aws-auth가 필요해져도 돌아올 수 없습니다. 이 사실이 마이그레이션 순서를 결정합니다.

# 1단계: 병행 모드로 (aws-auth도 계속 유효)
aws eks update-cluster-config --name my-cluster \
  --access-config authenticationMode=API_AND_CONFIG_MAP

# 2단계는 검증이 끝난 뒤에만. 이후 되돌릴 수 없다
# aws eks update-cluster-config --name my-cluster \
#   --access-config authenticationMode=API

API_AND_CONFIG_MAP은 두 경로가 모두 살아 있는 상태입니다. Access Entry를 만들어 검증하는 동안 기존 접근이 그대로 유지되므로, 여기가 안전 지대입니다. 서두를 이유가 없는 구간이고, 몇 주 머물러도 문제가 없습니다.

# 3. 모드를 바꿔도 기존 매핑은 옮겨지지 않는다

가장 큰 오해가 여기서 나옵니다. 모드를 바꾸면 기존 aws-auth 항목이 Access Entry로 변환될 것 같지만 그렇지 않습니다.

If your cluster relies on the legacy aws-auth ConfigMap for access management, only the access entry for the original cluster creator is automatically created upon enabling access entries. Additional roles or permissions added to the ConfigMap (e.g., custom IAM roles for developers or services) are not automatically migrated.

클러스터 생성자 하나만 자동으로 만들어집니다. 개발자 역할, CI 역할, 자체 관리 노드의 인스턴스 역할은 전부 수동입니다.

API_AND_CONFIG_MAP 상태에서는 aws-auth가 아직 유효하므로 이 사실이 드러나지 않습니다. API로 넘어가는 순간 옮기지 않은 모든 주체가 한꺼번에 접근을 잃습니다. 사람만의 문제가 아닙니다. aws-auth로 등록된 자체 관리 노드가 있다면 그 노드들이 클러스터에 조인하지 못합니다.

그래서 전환 전에 반드시 목록을 대조해야 합니다.

# 현재 aws-auth에 무엇이 있는가
kubectl get configmap aws-auth -n kube-system -o yaml

# 지금까지 만든 Access Entry는 무엇인가
aws eks list-access-entries --cluster-name my-cluster

# 두 목록의 ARN을 비교한다 - 왼쪽에만 있는 것이 아직 안 옮긴 것
comm -23 \
  <(kubectl get cm aws-auth -n kube-system -o jsonpath='{.data.mapRoles}{.data.mapUsers}' \
     | grep -oE 'arn:aws:iam::[0-9]+:[^ "]+' | sort -u) \
  <(aws eks list-access-entries --cluster-name my-cluster \
     --query 'accessEntries[]' --output text | tr '\t' '\n' | sort -u)

이 명령의 출력이 비어야 API로 넘어갈 준비가 된 것입니다.

# 4. 권한을 붙이는 두 가지 방법

Access Entry는 IAM 주체를 지정할 뿐이고, 권한은 따로 붙입니다.

You can attach Kubernetes permissions to access entries in two ways:

  • Use an access policy. Access policies are pre-defined Kubernetes permissions templates maintained by AWS.
  • Reference a Kubernetes group. If you associate an IAM Identity with a Kubernetes group, you can create Kubernetes resources that grant the group permissions.

두 방식은 마이그레이션에서 역할이 다릅니다.

그룹 참조는 기존 aws-auth 항목을 그대로 옮기는 방법입니다. aws-auth는 원래 IAM 역할을 Kubernetes 그룹에 매핑하는 구조이므로, 같은 그룹 이름을 Access Entry에 넣으면 기존 Role/ClusterRoleBinding이 그대로 재사용됩니다. 권한이 바뀌지 않으므로 마이그레이션 위험이 가장 낮습니다.

# aws-auth의 { rolearn, groups: [platform-admins] } 항목을 그대로 옮긴다
aws eks create-access-entry --cluster-name my-cluster \
  --principal-arn arn:aws:iam::111122223333:role/PlatformAdmin \
  --type STANDARD \
  --kubernetes-groups platform-admins

액세스 정책은 AWS가 관리하는 권한 템플릿을 붙이는 방법입니다. 클러스터 안에 RBAC 오브젝트를 만들 필요가 없고, 네임스페이스 범위로 한정할 수 있습니다.

# 특정 네임스페이스에서만 편집 권한
aws eks associate-access-policy --cluster-name my-cluster \
  --principal-arn arn:aws:iam::111122223333:role/Developer \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy \
  --access-scope type=namespace,namespaces=team-a

기준을 정하면, 기존 항목은 그룹 참조로 무손실 이관하고 새 부여는 액세스 정책으로 시작하는 조합이 안전합니다. 이관하면서 동시에 권한 모델까지 바꾸면 문제가 생겼을 때 원인이 둘 중 어느 쪽인지 구분할 수 없습니다. 두 변경을 겹치지 않게 하는 것이 요령입니다.

# 5. 생성자의 관리자 권한도 다룰 수 있게 된다

aws-auth 시대에는 클러스터를 만든 주체가 암묵적으로 system:masters였고 이를 회수할 방법이 마땅치 않았습니다. Access Entries의 기능 설명에 이 부분이 있습니다.

Granular Permissions Management: Uses access entries and policies to define fine-grained permissions for AWS IAM principals, including modifying or revoking cluster-admin access from the creator.

생성자의 관리자 권한을 수정하거나 회수할 수 있습니다. 클러스터를 만든 사람의 개인 역할이 영구 관리자로 남는 상태를 정리할 수 있다는 뜻입니다.

새로 만드는 클러스터라면 아예 그 부트스트랩 권한을 끄고 시작하는 선택지도 있습니다. 다만 끄고 나서 관리자 Access Entry를 만들지 않으면 아무도 못 들어갑니다. 클러스터 생성과 관리자 엔트리 생성이 같은 IaC 단위 안에서 원자적으로 일어나야 합니다.

# 6. 순서 있는 전환 절차

정리하면 이렇습니다.

  1. 모드를 API_AND_CONFIG_MAP으로 바꾼다. 기존 접근은 그대로 유지된다.
  2. aws-auth 항목을 전수 조사한다. 사람, CI 역할, 자체 관리 노드 역할을 모두 목록화한다.
  3. 항목마다 Access Entry를 만든다. 기존 그룹 이름을 그대로 쓴다.
  4. 각 주체로 실제 인증해 권한을 확인한다. 목록이 아니라 실제 동작으로 확인한다.
  5. aws-auth를 비운다. 지우지 말고 항목만 제거한다. 이 상태에서 문제가 생기면 항목을 되돌릴 수 있다.
  6. 일정 기간 관찰한다. 잘 안 쓰는 역할은 이 구간에서 드러난다.
  7. API로 전환한다. 되돌릴 수 없다.

5번이 중요합니다. 모드를 API로 바꾸는 것은 되돌릴 수 없지만, API_AND_CONFIG_MAP 상태에서 aws-auth 내용을 비우는 것은 되돌릴 수 있습니다. 되돌릴 수 있는 방법으로 먼저 최종 상태를 흉내 내 보는 것이 이 절차의 핵심입니다. aws-auth를 비운 상태로 며칠 돌려서 아무 일도 안 일어나면, API 전환은 사실상 형식적인 단계가 됩니다.

6번의 기간은 그 클러스터에서 가장 드물게 도는 작업의 주기보다 길어야 합니다. 월 1회 배치 잡이 전용 역할을 쓴다면 한 달을 봐야 합니다.

# 7. 직접 확인하는 방법

현재 모드와 엔트리 상태를 봅니다.

# 현재 인증 모드
aws eks describe-cluster --name my-cluster --query 'cluster.accessConfig'

# 엔트리 목록과 각각의 그룹·정책
for arn in $(aws eks list-access-entries --cluster-name my-cluster \
               --query 'accessEntries[]' --output text); do
  echo "== $arn"
  aws eks describe-access-entry --cluster-name my-cluster \
    --principal-arn "$arn" --query 'accessEntry.{groups:kubernetesGroups,type:type}'
  aws eks list-associated-access-policies --cluster-name my-cluster \
    --principal-arn "$arn" --query 'associatedAccessPolicies[].policyArn'
done

목록 확인만으로는 부족합니다. 실제로 그 역할로 인증해 봐야 합니다.

# 대상 역할을 assume 해서 별도 kubeconfig로 확인
CREDS=$(aws sts assume-role --role-arn arn:aws:iam::111122223333:role/Developer \
          --role-session-name access-check --query Credentials --output json)
export AWS_ACCESS_KEY_ID=$(jq -r .AccessKeyId <<<"$CREDS")
export AWS_SECRET_ACCESS_KEY=$(jq -r .SecretAccessKey <<<"$CREDS")
export AWS_SESSION_TOKEN=$(jq -r .SessionToken <<<"$CREDS")

aws eks update-kubeconfig --name my-cluster --kubeconfig /tmp/kc-check
KUBECONFIG=/tmp/kc-check kubectl auth can-i --list -n team-a

auth can-i --list가 기대한 권한을 보여 주면 그 주체는 이관이 끝난 것입니다. 그리고 인증에 성공했을 때 어떤 사용자·그룹으로 인식됐는지도 확인할 수 있습니다.

# 서버가 나를 누구로 보는지
KUBECONFIG=/tmp/kc-check kubectl auth whoami

노드 쪽은 조인 여부로 확인합니다. 자체 관리 노드가 있다면 전환 전에 새 노드를 하나 띄워 정상 조인하는지 봐야 합니다. 기존에 이미 조인한 노드는 계속 동작하므로, 새 노드가 조인되는지가 진짜 검증입니다.

# 8. 트러블슈팅

증상 원인 조치
모드를 바꿨는데 아무것도 안 달라짐 API_AND_CONFIG_MAP은 병행 모드 정상. Access Entry를 만들어야 효과
API 전환 후 특정 팀이 접근 불가 aws-auth 항목이 이관되지 않음 되돌릴 수 없음. 즉시 Access Entry 생성
API 전환 후 새 노드가 조인 실패 노드 인스턴스 역할이 이관되지 않음 해당 역할의 엔트리를 알맞은 타입으로 생성
모드를 되돌리려는데 거부됨 한 방향 전환 Access Entry로 해결
권한이 예상과 다름 그룹 참조와 액세스 정책을 동시에 변경 이관과 권한 변경을 분리
클러스터 생성자 권한을 못 지움 부트스트랩 권한 Access Entry로 수정·회수
새 클러스터에 아무도 못 들어감 부트스트랩 권한을 끄고 엔트리 미생성 생성과 엔트리를 한 IaC 단위로
목록은 맞는데 실제로 안 됨 RBAC 바인딩이 그룹 이름과 불일치 auth whoami로 인식된 그룹 확인

# 9. 마무리

  • aws-auth의 진짜 문제는 불편함이 아니라 잘못 고치면 복구 경로가 없다는 것입니다. Access Entries는 권한 부여를 EKS API로 옮겨 Kubernetes API 없이 복구할 수 있게 만듭니다.
  • 모드 전환은 한 방향입니다. API로 가면 aws-auth가 필요해져도 돌아올 수 없습니다.
  • 모드를 바꿔도 기존 매핑은 옮겨지지 않습니다. 자동으로 생기는 것은 클러스터 생성자 엔트리 하나뿐입니다.
  • 기존 항목은 그룹 참조로 무손실 이관하고, 새 부여만 액세스 정책으로 시작합니다. 이관과 권한 모델 변경을 같은 시점에 하지 않습니다.
  • API_AND_CONFIG_MAP 상태에서 aws-auth를 비워 최종 상태를 흉내 내 보는 것이 핵심 단계입니다. 이 단계는 되돌릴 수 있고, API 전환은 되돌릴 수 없습니다.
  • 검증은 목록 대조가 아니라 실제 인증으로 합니다. 자체 관리 노드는 새 노드를 띄워 조인 여부를 봐야 합니다.

클러스터 인증 자체가 어떤 경로로 이뤄지는지는 클러스터 안팎에서 Kubernetes API에 인증하기 (opens new window)에 정리했습니다.

# 참고