[AWS EKS] EKS Security 5 - EKS 인증/인가

주영·2025년 3월 15일
0

AWS EKS Workshop Study 3기

목록 보기
22/31

이 글은 CloudNet@팀의 AWS EKS Workshop Study(AEWS) 3기 스터디 내용을 바탕으로 작성되었습니다.
AEWS는 CloudNet@의 '가시다'님께서 진행하는 스터디로, EKS를 학습하는 과정입니다.
EKS를 깊이 있게 이해할 기회를 주시고, 소중한 지식을 나눠주시는 가시다님께 다시 한번 감사드립니다.
이 글이 EKS를 학습하는 분들께 도움이 되길 바랍니다.

AWS Elastic Kubernetes Service(EKS)에서는 인증(Authentication)인가(Authorization)가 두 단계로 이루어집니다.

  • EKS 인증(Authentication): AWS IAM(Identity and Access Management)을 사용하여 클러스터에 접근하는 사용자를 인증합니다.
  • EKS 인가(Authorization): Kubernetes RBAC(Role-Based Access Control)을 사용하여 인증된 사용자의 권한을 관리합니다.
  • IAM과 Kubernetes RBAC 간 매핑은 aws-auth ConfigMap을 사용하지만, 향후 aws-auth는 deprecated 될 예정입니다.

1. EKS 인증/인가 과정

EKS 클러스터에서 kubectl을 실행할 때, 다음과 같은 인증 과정이 수행됩니다.

https://docs.aws.amazon.com/eks/latest/userguide/cluster-auth.html

https://devlos.tistory.com/75

  1. kubectl 실행

    • 사용자가 kubectl 명령을 실행하면, 내부적으로 aws eks get-token 명령을 호출합니다.
  2. IAM STS(Security Token Service) 요청

    • aws eks get-token 명령어가 AWS STS(Security Token Service)에 토큰 발급을 요청합니다.
    • AWS STS는 AWS 리소스에 대한 임시 보안 자격 증명(Security Token)을 발급하는 서비스입니다.
  3. AWS STS 응답 및 IAM 인증

    • STS가 AWS IAM을 통해 사용자 신원을 확인한 후, Pre-Signed URL을 반환합니다.
    • 이 URL은 EKS(Kubernetes) API 서버에 Bearer Token으로 전달됩니다.
  4. EKS API 서버 요청

    • Kubernetes API 서버는 AWS-IAM-Authentication Server에 Token 리뷰를 요청합니다.
    • AWS-IAM-Authentication Server는 AWS IAM에 GetCallerIdentity API를 호출하여 Token 사용자 검증을 요청합니다.달하여 사용자 신원을 확인합니다.
    • AWS IAM은 사용자 신원을 확인하고 IAM User 또는 IAM Role의 ARN을 반환합니다.
    • AWS-IAM-Authentication Server는 configMap을 통해 IAM User / Role의 k8s Group을 확인하여 액세스를 인증합니다.
    • AWS-IAM-Authentication Server는 Kubernetes API 서버에 Token 리뷰를 응답합니다.
  5. EKS API 서버에서 RBAC로 인가 처리

    • 인증된 IAM User 또는 IAM Role은 RBAC(Role-Based Access Control)에 따라 인가 여부가 결정됩니다.

2. EKS 인증(Authentication) 과정 실습

# sts caller id의 ARN 확인
aws sts get-caller-identity --query Arn
# 출력 예시
"arn:aws:iam::<자신의 Account ID>:user/admin"

# kubeconfig 정보 확인
cat ~/.kube/config
...
- name: admin@myeks.ap-northeast-2.eksctl.io
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - eks
      - get-token
      - --output
      - json
      - --cluster-name
      - myeks
      - --region
      - ap-northeast-2
      command: aws
      env:
      - name: AWS_STS_REGIONAL_ENDPOINTS
        value: regional
      interactiveMode: IfAvailable
      provideClusterInfo: false

# Get  a token for authentication with an Amazon EKS cluster.
# This can be used as an alternative to the aws-iam-authenticator.
aws eks get-token help

# 임시 보안 자격 증명(토큰)을 요청 : expirationTimestamp 시간경과 시 토큰 재발급됨
aws eks get-token --cluster-name $CLUSTER_NAME | jq
aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token'
aws eks get-token --cluster-name $CLUSTER_NAME --debug | jq

# 출력 예시
DEBUG - Endpoint provider result: https://sts.ap-northeast-2.amazonaws.com

Action=GetCallerIdentity&

Version=2011-06-15&

X-Amz-Algorithm=AWS4-HMAC-SHA256&

X-Amz-Credential=AKIA5ILF.../20230525/ap-northeast-2/sts/aws4_request&

X-Amz-Date=20230525T120720Z&

X-Amz-Expires=60&

X-Amz-SignedHeaders=host;x-k8s-aws-id&

X-Amz-Signature=6e09b846da702767f38c78831986cb558.....

# Tokenreviews API 리소스 확인 
kubectl api-resources | grep authentication
# 출력 예시
tokenreviews                                   authentication.k8s.io/v1               false        TokenReview

# List the fields for supported resources.
# Tokenrevies API 상세 정보
kubectl explain tokenreviews
# 출력 예시
...
DESCRIPTION:
     TokenReview attempts to authenticate a token to a known user. Note:
     TokenReview requests may be cached by the webhook token authenticator
     plugin in the kube-apiserver.

3. EKS 인가(Authorization) 과정 실습

IAM User 또는 Role이 Kubernetes 내에서 어떤 권한을 가지는지 확인하기 위해 aws-auth ConfigMap을 사용합니다.

# aws-auth 컨피그맵 확인 : 현재는 IAM access entry 방식 우선 적용으로 아래 출력 내용과 다를 수 있습니다.
kubectl get cm -n kube-system aws-auth -o yaml
# 출력 예시
apiVersion: v1
kind: ConfigMap
metadata: 
  name: aws-auth
  namespace: kube-system
data: 
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::91128.....:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1OS1WSTV0YB9X
      username: system:node:{{EC2PrivateDNSName}}
#---<아래 생략(추정), ARN은 EKS를 설치한 IAM User , 여기 있었을경우 만약 실수로 삭제 시 복구가 가능했을까?---
  mapUsers: |
    - groups:
      - system:masters
      userarn: arn:aws:iam::111122223333:user/admin
      username: kubernetes-admin

# EKS 설치한 IAM User 정보 
kubectl rbac-tool whoami
{Username: "kubernetes-admin",
 UID:      "aws-iam-authenticator:9112834...:AIDA5ILF2FJIR2.....",
 Groups:   ["system:masters",
            "system:authenticated"],
...

# system:masters , system:authenticated 그룹의 정보 확인
kubectl rbac-tool lookup system:masters
kubectl rbac-tool lookup system:authenticated
kubectl rolesum -k Group system:masters
kubectl rolesum -k Group system:authenticated

# system:masters 그룹이 사용 가능한 클러스터 롤 확인 : cluster-admin
kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name            Namespace
  ----   ----            ---------
  Group  system:masters

# cluster-admin 의 PolicyRule 확인 : 모든 리소스  사용 가능!
kubectl describe clusterrole cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]

# system:authenticated 그룹이 사용 가능한 클러스터 롤 확인
kubectl describe ClusterRole system:discovery
kubectl describe ClusterRole system:public-info-viewer
kubectl describe ClusterRole system:basic-user
kubectl describe ClusterRole eks:podsecuritypolicy:privileged

4. 계정 생성 및 aws-auth ConfigMap을 사용한 RBAC 설정 실습

AWS EKS에서 aws-auth ConfigMap을 활용하여 IAM 사용자 및 역할을 Kubernetes RBAC에 매핑하는 방법을 설명합니다.
이 실습에서는 DevOps 신입 사원을 위한 testuser 계정을 생성하고, 운영 서버에서 관리하는 방법을 단계별로 정리합니다.

4.1 testuser IAM 사용자 생성 및 설정

먼저, AWS IAM에서 testuser라는 새로운 사용자를 생성합니다.

[myeks-bastion 운영서버1 or 자신의PC]

# testuser 사용자 생성
aws iam create-user --user-name testuser

# 사용자에게 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name testuser
{
    "AccessKey": {
        "UserName": "testuser",
        "AccessKeyId": "AKIA5ILF2##",
        "Status": "Active",
        "SecretAccessKey": "TxhhwsU8##",
        "CreateDate": "2023-05-23T07:40:09+00:00"
    }
}
# testuser 사용자에 정책을 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser

# get-caller-identity 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::911283464785:user/admin"

kubectl whoami

# EC2 IP 확인 : myeks-bastion-EC2-2 PublicIPAdd 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table

4.2 testuser의 EKS 클러스터 접근 테스트

[myeks-bastion-2 운영서버2]

# 아래 실습 진행을 위해, kind(k8s) 삭제
kind delete cluster --name myk8s
mv ~/.kube/config ~/.kube/config.old

# get-caller-identity 확인 >> 왜 안될까요?
aws sts get-caller-identity --query Arn

# testuser 자격증명 설정
aws configure
AWS Access Key ID [None]: AKIA5ILF2F...
AWS Secret Access Key [None]: ePpXdhA3cP....
Default region name [None]: ap-northeast-2

# get-caller-identity 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::911283464785:user/testuser"

# kubectl 시도 >> testuser도 AdministratorAccess 권한을 가지고 있는데, 실패 이유는?
kubectl get node -v6
ls ~/.kube
  • testuserAdministratorAccess 권한을 가지고 있지만, aws-auth ConfigMap에 등록되지 않았기 때문에 Kubernetes에서 인증되지 않습니다.
  • aws-auth ConfigMap에 추가해야만 EKS 접근이 가능합니다.

4.3 testuser에 EKS 관리자 권한 부여

testuser를 EKS의 관리자(system:masters 그룹)로 추가합니다.

[myeks-bastion]

# 방안1 : eksctl 사용 >> iamidentitymapping 실행 시 aws-auth 컨피그맵 작성해줌
# Creates a mapping from IAM role or user to Kubernetes user and groups
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuser

# 확인
kubectl get cm -n kube-system aws-auth -o yaml
...

# 확인 : 기존에 있는 role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-YYYYY 는 어떤 역할/동작을 하는 걸까요?
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN											USERNAME				GROUPS					ACCOUNT
arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ	system:node:{{EC2PrivateDNSName}}	system:bootstrappers,system:nodes	
arn:aws:iam::911283464785:user/testuser							testuser				system:masters
  • system:masters 그룹에 추가되면 Kubernetes에서 cluster-admin 역할을 가지게 되어 모든 권한을 부여받습니다.

4.4 testuser의 Kubeconfig 생성 및 kubectl 실행 확인

[myeks-bastion-2]

# testuser kubeconfig 생성 >> aws eks update-kubeconfig 실행이 가능한 이유는?, 3번 설정 후 약간의 적용 시간 필요
CLUSTER_NAME=myeks
aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias testuser

# 운영서버의 config와 비교해보자
cat ~/.kube/config

# kubectl 사용 확인
kubectl ns default
kubectl get node -v6

# 현재 사용자 확인
# rbac-tool 후 확인 >> 기존 계정과 비교해보자
kubectl rbac-tool whoami
{Username: "testuser",
 UID:      "aws-iam-authenticator:911283464785:AIDA5ILF2FJIV65KG6RBM",
 Groups:   ["system:masters",
            "system:authenticated"],
 Extra:    {accessKeyId:  ["AKIA5ILF2FJIZJUZSG4D"],
            arn:          ["arn:aws:iam::911283464785:user/testuser"],
            canonicalArn: ["arn:aws:iam::911283464785:user/testuser"],
...
  • system:masters 그룹에 추가되었기 때문에 kubectl 명령이 정상적으로 실행됩니다.

4.5 testuser의 RBAC 그룹을 변경 테스트

EKS 관리자에서 testuser의 그룹을 system:masters에서 system:authenticated로 변경하여 권한을 제한합니다.

[myeks-bastion]

# 방안2 : 아래 edit로 mapUsers 내용 직접 수정 system:authenticated
kubectl edit cm -n kube-system aws-auth
...

# 변경 확인
eksctl get iamidentitymapping --cluster $CLUSTER_NAME

[myeks-bastion-2]

# 시도
kubectl get node -v6
kubectl api-resources -v5
  • system:authenticated 그룹은 기본적인 조회 권한만 가지고 있으며(api-resources 조회는 가능), 관리 권한이 없습니다.
  • 따라서 kubectl get node 실행 시 "권한 부족(Forbidden)" 오류가 발생합니다.

4.6 testuser의 IAM 맵핑 삭제 테스트

testuser를 aws-auth ConfigMap에서 삭제하여 Kubernetes 접근을 차단합니다.

[myeks-bastion]

# testuser IAM 맵핑 삭제
eksctl delete iamidentitymapping --cluster $CLUSTER_NAME --arn  arn:aws:iam::$ACCOUNT_ID:user/testuser

# Get IAM identity mapping(s)
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
kubectl get cm -n kube-system aws-auth -o yaml

[myeks-bastion-2]

# 시도
kubectl get node -v6
kubectl api-resources -v5

4.7 AWS CloudTrail에서 이벤트 기록 확인

https://ap-northeast-2.console.aws.amazon.com/cloudtrail/home?region=ap-northeast-2#/events?EventName=GetCallerIdentity

5. EC2 Instance Profile(IAM Role)과 Kubernetes RBAC 연계 확인 및 보안 리스크

AWS EC2 Instance Profile에 맵핑된 IAM Role이 Kubernetes RBAC과 어떻게 연계되며, 이로 인해 발생할 수 있는 보안 리스크를 설명합니다.
실습을 통해 EKS 노드의 IAM Role이 Kubernetes에 어떻게 반영되는지 확인하고, 이를 이용한 보안 위협을 분석합니다.

5.1 개요

EC2 Instance Profile과 Kubernetes RBAC 연계 개념

  • AWS EC2 인스턴스는 IAM Role을 할당받을 수 있으며, 이를 EC2 Instance Profile이라고 합니다.
  • AWS EKS에서 EC2 노드(Worker Node)는 IAM Role을 이용하여 AWS API 요청을 수행할 수 있습니다.
  • Kubernetes에서는 EKS 노드가 클러스터 리소스를 관리할 수 있도록 aws-auth ConfigMap을 사용하여 IAM Role을 RBAC 그룹(system:nodes)에 맵핑합니다.

보안 리스크

  • EKS 노드에 IAM Role이 부여되어 있으므로, 노드 내 컨테이너가 해당 IAM Role을 이용하여 AWS 리소스에 접근할 가능성이 있습니다.
  • 컨테이너가 Instance Metadata Service(IMDS)에 접근할 경우, IAM Role의 보안 토큰(Security Token)을 탈취하여 AWS 리소스를 조작할 위험이 있습니다.
  • 특히, 보안이 설정되지 않은 컨테이너가 실행될 경우, 해당 컨테이너가 AWS API를 무단으로 사용할 가능성이 높아집니다.

https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html#creating-access-entries

5.2 EKS 노드의 IAM Role 확인

5.2.1 노드에서 IAM Role(Instance Profile) 정보 확인

EKS 노드에 접속하여 IAM Role을 확인합니다.

# 노드에 STS ARN 정보 확인 : Role 뒤에 인스턴스 ID!
for node in $N1 $N2 $N3; do ssh ec2-user@$node aws sts get-caller-identity --query Arn; done
"arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-07c9162ed08d23e6f"
"arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-00d9d24c0af0d6815"
"arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-031e672f89572abe8"
  • assumed-role을 통해 EKS 노드가 IAM Role을 사용하고 있음을 확인할 수 있습니다.
  • Role 뒤의 /i-xxxxxxxxxxxxxx는 EC2 인스턴스의 ID를 의미합니다.

5.2.2 aws-auth ConfigMap에서 IAM Role 확인

# aws-auth 컨피그맵 확인 >> system:nodes 와 system:bootstrappers 의 권한은 어떤게 있는지 찾아보세요!
# username 확인! 인스턴스 ID? EC2PrivateDNSName?
kubectl describe configmap -n kube-system aws-auth
...
mapRoles:
----
- groups:
  - system:nodes
  - system:bootstrappers
  rolearn: arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng-f6c38e4-NodeInstanceRole-1OU85W3LXHPB2
  username: system:node:{{EC2PrivateDNSName}}
...

# Get IAM identity mapping(s)
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN												USERNAME		GROUPS					ACCOUNT
arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1OS1WSTV0YB9X	system:node:{{EC2PrivateDNSName}}	system:bootstrappers,system:nodes
...
  • EKS 노드의 IAM Role이 system:nodes 그룹에 포함되어 있습니다.
  • 이를 통해, Kubernetes RBAC에서 해당 노드에 특정 권한을 부여할 수 있습니다.

5.3 AWS CLI 파드를 사용하여 IAM Role의 AWS 리소스 접근 확인

IAM Role이 설정된 EKS 노드에서 실행되는 컨테이너가 AWS API를 호출할 수 있는지 확인합니다.

# awscli 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: awscli-pod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: awscli-pod
  template:
    metadata:
      labels:
        app: awscli-pod
    spec:
      containers:
      - name: awscli-pod
        image: amazon/aws-cli
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
EOF

# 파드 생성 확인
kubectl get pod -owide

# 파드 이름 변수 지정
APODNAME1=$(kubectl get pod -l app=awscli-pod -o jsonpath="{.items[0].metadata.name}")
APODNAME2=$(kubectl get pod -l app=awscli-pod -o jsonpath="{.items[1].metadata.name}")
echo $APODNAME1, $APODNAME2

# awscli 파드에서 EC2 InstanceProfile(IAM Role)의 ARN 정보 확인
kubectl exec -it $APODNAME1 -- aws sts get-caller-identity --query Arn
kubectl exec -it $APODNAME2 -- aws sts get-caller-identity --query Arn
  • 컨테이너 내부에서 AWS CLI를 실행하면, IAM Role을 이용하여 AWS API 요청을 수행할 수 있습니다.

5.4 보안 문제점 분석 (IMDS 취약점)

컨테이너가 AWS EC2 Instance Metadata Service(IMDS)에 접근할 수 있는지 확인합니다.

# awscli 파드에서 EC2 InstanceProfile(IAM Role)을 사용하여 AWS 서비스 정보 확인 >> 별도 IAM 자격 증명이 없는데 어떻게 가능한 것일까요?
# > 최소권한부여 필요!!! >>> 보안이 허술한 아무 컨테이너나 탈취 시, IMDS로 해당 노드의 IAM Role 사용 가능!
kubectl exec -it $APODNAME1 -- aws ec2 describe-instances --region ap-northeast-2 --output table --no-cli-pager
kubectl exec -it $APODNAME2 -- aws ec2 describe-vpcs --region ap-northeast-2 --output table --no-cli-pager
 
# EC2 메타데이터 확인 : IDMSv1은 Disable, IDMSv2 활성화 상태, IAM Role - 링크
kubectl exec -it $APODNAME1 -- bash 
-----------------------------------
아래부터는 파드에 bash shell 에서 실행
curl -s http://169.254.169.254/ -v
...

# Token 요청 
curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" ; echo
curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" ; echo

# Token을 이용한 IMDSv2 사용
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
echo $TOKEN
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/ ; echo
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/ ; echo
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/ ; echo

# 위에서 출력된 IAM Role을 아래 입력 후 확인
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1DC6Y2GRDAJHK
{
  "Code" : "Success",
  "LastUpdated" : "2023-05-27T05:08:07Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIA5ILF2FJI5VPIYJHP",
  "SecretAccessKey" : "rke6HXkaG4B/YLGUyAYtDnd3eMrjXlCpiB4h+9XJ",
  "Token" : "IQoJb3JpZ2luX2VjEAUaDmFwLW5vcnRoZWFzdC0yIkcwRQIhAOLQr2c2k4UwqTR2Iof2wq9Faduno1a2FX07ASHsO/rCAiAvCqQRv/JrSDZNZKNMloaBTR4s91O+RNWfSlfNluimmirLBQg+EAEaDDkxMTI4MzQ2NDc4NSIM1/RJmwkWziNhz8TEKqgFZZr1FpwHmLWNzdCdbNxtPk/YhbqbED6JzFiWJssqdRq4UniamoGrkV75oaf7o0CXQTlgK7r6f07goYA268UlqGx9XHKmeSoUt3ZTG79B1BIiSW22JVFzs4/fMpcwQLFv1lJKcGOqKehXrlq4yQ2zln4QTi/S30rp2ARiUfjgdp2+gkWKzOVWkdgoKtn3OAfdI/hBJHiz1eDPZsqqzv8eyP6sdo1xHJ6OY7xjLtTHWRaQpt6SStKTzsN88sJi9NebBXV63FJ6EkGNaC7eFo/nq9xZtGJqsu3PEuseadl8a8LJzOfNO0NP+4p8o0fMV4oeKSItZUIu88CvinvGd3bp1FWlVItDsGwjo6qOTxCg2ov6p7cAbTudEA5AwSjDlHm/BX08JN4XN7kDKtBQhHoWRbeI3suqZmtLPrSu5NCfgVu2jJpMiwOEhVV9W+fBUica345sIp94qIVVwrVbDnuLC0QDSXKxD+GRhcqdtA54QmUodqxv/bEUlRy1wVUty7Umucxl3B6MYBVSXR7PRzcf2U3vvqbJDJAT5dhFTRI1gK1YcXLzpT1T3wluMsyMPFpEWYMe/QEDAn0UwJ55pZt2pKohioiLJ3amWfNUhzoDkmXXZhAOM71e8gUVdrtAVcnl30MTDjHlIWIOBWrVMshunM5Wfmr4H4BAV+8of6xGz5AhoodWNVE+/x+XifO6h9l+Plwq24Jp8SbiCF3ZFQVe20ijsfDqK6SFAveL4vcVz7sEGLTZXLNLycgeGQmcvkb7Mmmoir/9UwNCWFWBbWXZfsEbNfSLhInw+k53FLb5I+axJPhEDSE5Iqmu+cuvoZfLy+bOailVgQN/jX6vZSL3ihhJwsP7t58urN34tKP+sjOpIBWv2bV2OnntaAqbc24tmc0wjWkaw5IwqKDGowY6sQGFB40kmsXmxihug/yKwcMK/pg5xFknPFO56P6BzErLmt1hcpNF4QBQzh/sdFi7Y/EOh9NqU/XFdFeJLp6KgaxUASLSW/k6ee+RzhbW0aSJb9GYi7tZdArcjg4YaQ6hdXdCFXiYWbNyIMs2MH8APT5jFDnwpbqSnlO2Ao64XY12cm2tMWVH+KTUyLGICHP1az7kD3/tV9glw9rJB2AOL4iA3TTuK+U2o+pHWEHRQOVh3p4=",
  "Expiration" : "2023-05-27T11:09:07Z"
}
## 출력된 정보는 AWS API를 사용할 수 있는 어느곳에서든지 Expiration 되기전까지 사용 가능

# 파드에서 나오기
exit
---

AWS Management 콘솔에서 워커 노드에 연결된 IAM 역할(정책) 확인

5.5 IAM Role을 사용하여 Kubernetes 접근 확인

컨테이너 내부에서 IAM Role을 사용하여 Kubernetes API에 접근할 수 있는지 확인합니다.

# node 의 IAM Role ARN을 변수로 지정
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
NODE_ROLE=<각자 자신의 노드 Role 이름>
NODE_ROLE=eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1DC6Y2GRDAJHK

# awscli 파드에서 kubeconfig 정보 생성 및 확인 >> kubeconfig 에 정보가 기존 iam user와 차이점은?
kubectl exec -it $APODNAME1 -- aws eks update-kubeconfig --name $CLUSTER_NAME --role-arn $NODE_ROLE
kubectl exec -it $APODNAME1 -- cat /root/.kube/config
...
  - --role
  - eksctl-myeks-nodegroup-ng1-NodeInstanceRole-3GQR27I04PAJ

kubectl exec -it $APODNAME2 -- aws eks update-kubeconfig --name $CLUSTER_NAME --role-arn $NODE_ROLE
kubectl exec -it $APODNAME2 -- cat /root/.kube/config
  • --role 옵션이 추가되어 IAM Role을 사용하여 Kubernetes API에 접근하고 있음을 확인할 수 있습니다.

6. AWS EKS 액세스 관리(Access Management) 최신 기능 및 실습 정리

AWS EKS에서는 IAM과 Kubernetes RBAC을 연계하여 클러스터 및 리소스에 대한 액세스를 관리합니다.
기존에는 aws-auth ConfigMap을 활용했지만, 현재는 EKS API 기반의 Access Entries 방식이 도입되었습니다.
AWS EKS의 새로운 액세스 관리 기능과 이를 활용한 테스트 사용자(testuser) 설정 및 실습 과정을 설명합니다.

6.1 EKS 액세스 관리 개요

기존 aws-auth ConfigMap 방식

  • EKS 클러스터에 접근하는 IAM 사용자 또는 IAM 역할을 Kubernetes RBAC에 연결하기 위해 aws-auth ConfigMap을 사용했습니다.
  • 문제점:
    • IAM 역할을 수정하려면 직접 ConfigMap을 편집해야 함 → 유지보수 어려움, 휴먼에러 위험성
    • IAM 역할과 Kubernetes RBAC 간 매핑이 자동화되지 않음 → 운영 복잡성 증가

새로운 Access Entries 방식 (EKS API 기반)

  • EKS API를 통해 IAM 사용자 또는 역할을 Kubernetes RBAC에 매핑하는 방식이 도입되었습니다.
  • 장점:
    • IAM 정책과 Kubernetes RBAC을 손쉽게 연결 가능
    • ConfigMap을 직접 수정할 필요 없음
    • 정책 충돌 시 EKS API 기반 정책이 우선 적용되며 ConfigMap은 무시됨

지원되는 액세스 정책 (Access Policies)

정책 이름설명
AmazonEKSClusterAdminPolicy클러스터 관리자 (Cluster Admin)
AmazonEKSAdminPolicyKubernetes 관리자 (Admin)
AmazonEKSEditPolicyKubernetes 편집자 (Editor)
AmazonEKSViewPolicyKubernetes 뷰어 (Viewer)

https://aws.amazon.com/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/

6.2 EKS API 기반 액세스 관리 설정

주의: ComfigMap 모드로 원복 불가능하다.

# EKS API 액세스모드로 변경
aws eks update-cluster-config --name $CLUSTER_NAME --access-config authenticationMode=API

# List all access policies : 클러스터 액세스 관리를 위해 지원되는 액세스 정책
# https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html
## AmazonEKSClusterAdminPolicy – 클러스터 관리자
## AmazonEKSAdminPolicy – 관리자
## AmazonEKSEditPolicy – 편집
## AmazonEKSViewPolicy – 보기
...
aws eks list-access-policies | jq

# 맵핑 클러스터롤 정보 확인
kubectl get clusterroles -l 'kubernetes.io/bootstrapping=rbac-defaults' | grep -v 'system:'
NAME                                                                   CREATED AT
admin                                                                  2024-04-06T05:58:32Z
cluster-admin                                                          2024-04-06T05:58:32Z
edit                                                                   2024-04-06T05:58:32Z
view                                                                   2024-04-06T05:58:32Z

kubectl describe clusterroles admin
kubectl describe clusterroles cluster-admin
kubectl describe clusterroles edit
kubectl describe clusterroles view

#
aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq
{
  "accessEntries": [
    "arn:aws:iam::911283...:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK",
    "arn:aws:iam::911283...:user/admin"
  ]
}

# 확인 : macOS - 뒤에 admin 은 자신의 IAM User로 변경해서 실행 할 것!
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID\:user/admin | jq # macOS

# 확인 : Linux (운영서버, WSL2 등) - 뒤에 admin 은 자신의 IAM User로 변경해서 실행 할 것!
export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/admin | jq # Linux
{
  "associatedAccessPolicies": [
    {
      "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
      "accessScope": {
        "type": "cluster",
        "namespaces": []
      },
      "associatedAt": "2024-04-06T14:53:36.982000+09:00",
      "modifiedAt": "2024-04-06T14:53:36.982000+09:00"
    }
  ],
  "clusterName": "myeks",
  "principalArn": "arn:aws:iam::91128...:user/admin"
}

# 위에서 출력된 nodegroup IAM Role ARN 을 아래 입력 해서 실행 할 것!
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID\:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK | jq
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK | jq
{
  "associatedAccessPolicies": [],
  "clusterName": "myeks",
  "principalArn": "arn:aws:iam::9112834...:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK"
}

#
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID\:user/admin | jq
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/admin | jq
...
    "kubernetesGroups": [],
    ...
    "username": "arn:aws:iam::9112...:user/admin",
    "type": "STANDARD"
...

aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID\:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK | jq
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-t4MD9Py4ZCyK | jq
...
    "kubernetesGroups": [
      "system:nodes"
    ...
    "username": "system:node:{{EC2PrivateDNSName}}",
    "type": "EC2_LINUX"
...
  • Kubernetes는 기본적으로 admin, cluster-admin, edit, view 역할을 제공합니다.

6.3 testuser 설정 및 클러스터 관리자(Admin) 권한 부여

testuser가 EKS에 접근할 수 있도록 IAM 사용자로 등록하고, EKS 클러스터 관리자(Cluster Admin) 역할을 부여합니다.

# testuser 의 access entry 생성
aws eks create-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser
aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq -r .accessEntries[]

# testuser에 AmazonEKSClusterAdminPolicy 연동
aws eks associate-access-policy --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster

#
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq

[myeks-bastion-2]에서 testuser로 EKS 접근 테스트

# testuser 정보 확인
aws sts get-caller-identity --query Arn
kubectl whoami

# kubectl 시도
# testuser가 실행 가능한 kubectl 명령 확인
kubectl get node -v6
kubectl api-resources -v5
kubectl rbac-tool whoami
kubectl auth can-i delete pods --all-namespaces
kubectl get cm -n kube-system aws-auth -o yaml
eksctl get iamidentitymapping --cluster $CLUSTER_NAME

6.4 testuser의 RBAC 그룹 변경 테스트

1. testuser의 기존 액세스 정책 제거

# 기존 testuser access entry 제거
aws eks delete-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser
aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq -r .accessEntries[]

2. ClusterRole 생성

#
cat <<EoF> ~/pod-viewer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-viewer-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["list", "get", "watch"]
EoF

cat <<EoF> ~/pod-admin-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-admin-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["*"]
EoF

kubectl apply -f ~/pod-viewer-role.yaml
kubectl apply -f ~/pod-admin-role.yaml

#
kubectl create clusterrolebinding viewer-role-binding --clusterrole=pod-viewer-role --group=pod-viewer
kubectl create clusterrolebinding admin-role-binding --clusterrole=pod-admin-role --group=pod-admin

3. testuser에게 pod-viewer 그룹 할당

#
aws eks create-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser --kubernetes-group pod-viewer
...
    "accessEntry": {
        "clusterName": "myeks",
        "principalArn": "arn:aws:iam::91128...:user/testuser",
        "kubernetesGroups": [
            "pod-viewer"
        ],

#
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq
...
    "kubernetesGroups": [
      "pod-viewer"
    ],
...

4. [myeks-bastion-2]에서 testuser로 테스트

# testuser 정보 확인
aws sts get-caller-identity --query Arn
kubectl whoami

# kubectl 시도
kubectl get pod -v6
kubectl api-resources -v5
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i delete pods --all-namespaces

5. kubernetesGroups 업데이트 적용 (pod-viewer → pod-admin)

#
aws eks update-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser --kubernetes-group pod-admin | jq -r .accessEntry
...
  "kubernetesGroups": [
    "pod-admin"
...
aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq
...
    "kubernetesGroups": [
      "pod-admin"
    ],
...
  • testuser의 Kubernetes RBAC 그룹을 pod-admin으로 변경하여 Pods를 생성, 수정, 삭제할 수 있도록 설정합니다.

6. [myeks-bastion-2]에서 testuser로 테스트

# testuser 정보 확인
aws sts get-caller-identity --query Arn
kubectl whoami

# kubectl 시도
kubectl get pod -v6
kubectl api-resources -v5
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i delete pods --all-namespaces

0개의 댓글