스터디/AEWS

[AEWS] 6주차 EKS 환경에서 인증/인가

안녕유지 2025. 3. 12. 04:42
Cloudnet AWES 6주차 스터디를 진행하며 정리한 글입니다.

 
이번 포스팅은 EKS에서  인증(Authentication), 인가 (Authorization), 어드미션 컨트롤 (Admission Control)에 대해 알아보겠습니다.
 
EKS)에서는 쿠버네티스 인증 인가를 AWS IAM(Identity and Access Management)과 연계하여 처리합니다.
이번 포스팅에서는 EKS에서 인증(Authentication) 및 인가(Authorization)이 어떻게 작동하는지 알아보겠습니다.
 
 

EKS Cluster Auth

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

 
 

EKS에서의 인증 (Authentication) / 인가(Authorization)

EKS에서 API 요청을 보낼 때, 기본적인 쿠버네티스 인증 방식(X.509 인증서, OIDC 등) 대신 AWS IAM을 기반으로 인증을 수행합니다.
IAM 인증이 완료되면, EKS는 RBAC을 사용하여 인가를 수행합니다.
 

EKS API 서버 요청 시 인증/인가 Flow

  1. 사용자가 kubectl을 실행하여 EKS 클러스터에 요청을 보냄
  2. kubectlaws eks get-token을 통해 AWS STS(Security Token Service)에서 임시 인증 토큰을 요청
  3. AWS STS가 IAM 사용자 또는 IAM 역할을 인증하여 토큰을 발급
  4. kubectl이 API 서버에 요청을 보낼 때 해당 토큰을 포함(Bearer Token Pre-signed URL)
  5. API 서버는 aws-iam-authenticator를 사용하여 토큰의 유효성을 확인하고 사용자 인증 수행
  6. aws-iam-authenticator는 AWS IAM에서 사용자 검증을 요청하고, IAM User, Role ARN을 반환
    1. Configmap 방식일 경우
      aws-auth configmap에서 IAM User, Role의 쿠버네티스 그룹 확인
    2. EKS API 방식일 경우
      Access Entry로 쿠버네티스 그룹과 Access Policy 확인
  7. 해당 과정을 통해 IAM(사용자)와 쿠버네티스 그룹을 연결하여 이 사용자가 어떤 그룹에 속하는지 요청한 사람이 누구인지 확인! -> 인증
  8. 인증이 완료된 사용자(IAM User 또는 Role ARN)가 aws-auth ConfigMap 또는 EKS API를 통해 특정 쿠버네티스 그룹(system:masters, system:authenticated 등)에 속하는지 확인
  9. RBAC(Role-Based Access Control) 정책을 기반으로 요청할 권한이 있는지 확인하여 요청 허용 또는 거부 -> 인가

 
++ 참고) 유용한 플러그인 설치

# 설치
kubectl krew install access-matrix rbac-tool rbac-view rolesum whoami

# k8s 인증된 주체 확인
kubectl whoami
arn:aws:iam::9~~0:user/admin

# RBAC access matrix
# default 네임스페이스 범위 접근 확인
kubectl access-matrix --namespace default
NAME                                            LIST  CREATE  UPDATE  DELETE
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
                                                ✖     ✖       ✖       ✖
bindings                                              ✔
configmaps                                      ✔     ✔       ✔       ✔
controllerrevisions.apps                        ✔     ✔       ✔       ✔
cronjobs.batch                                  ✔     ✔       ✔       ✔
csistoragecapacities.storage.k8s.io             ✔     ✔       ✔       ✔
daemonsets.apps                                 ✔     ✔       ✔       ✔
deployments.apps                                ✔     ✔       ✔       ✔
endpoints                                       ✔     ✔       ✔       ✔
endpointslices.discovery.k8s.io                 ✔     ✔       ✔       ✔
events                                          ✔     ✔       ✔       ✔
events.events.k8s.io                            ✔     ✔       ✔       ✔
horizontalpodautoscalers.autoscaling            ✔     ✔       ✔       ✔
ingresses.networking.k8s.io                     ✔     ✔       ✔       ✔
jobs.batch                                      ✔     ✔       ✔       ✔
leases.coordination.k8s.io                      ✔     ✔       ✔       ✔
limitranges                                     ✔     ✔       ✔       ✔
localsubjectaccessreviews.authorization.k8s.io        ✔
networkpolicies.networking.k8s.io               ✔     ✔       ✔       ✔
persistentvolumeclaims                          ✔     ✔       ✔       ✔
poddisruptionbudgets.policy                     ✔     ✔       ✔       ✔
pods                                            ✔     ✔       ✔       ✔
pods.metrics.k8s.io                             ✔
podtemplates                                    ✔     ✔       ✔       ✔
policyendpoints.networking.k8s.aws              ✔     ✔       ✔       ✔
replicasets.apps                                ✔     ✔       ✔       ✔
replicationcontrollers                          ✔     ✔       ✔       ✔
resourcequotas                                  ✔     ✔       ✔       ✔
rolebindings.rbac.authorization.k8s.io          ✔     ✔       ✔       ✔
roles.rbac.authorization.k8s.io                 ✔     ✔       ✔       ✔
secrets                                         ✔     ✔       ✔       ✔
securitygrouppolicies.vpcresources.k8s.aws      ✔     ✔       ✔       ✔
serviceaccounts                                 ✔     ✔       ✔       ✔
services                                        ✔     ✔       ✔       ✔
statefulsets.apps                               ✔     ✔       ✔       ✔

# subject 이름별로 RBAC 룩업
kubectl rbac-tool lookup system:masters
  SUBJECT        | SUBJECT TYPE | SCOPE       | NAMESPACE | ROLE          | BINDING
-----------------+--------------+-------------+-----------+---------------+----------------
  system:masters | Group        | ClusterRole |           | cluster-admin | cluster-admin
  
# eks:node-bootstrapper 유저 ClusterRole 확인
kubectl describe ClusterRole eks:node-bootstrapper

Name:         eks:node-bootstrapper
Labels:       eks.amazonaws.com/component=node
Annotations:  <none>
PolicyRule:
  Resources                                                      Non-Resource URLs  Resource Names  Verbs
  ---------                                                      -----------------  --------------  -----
  certificatesigningrequests.certificates.k8s.io/selfnodeserver  []                 []              [create]
  
# 이 외의 다양한 명령어가 사용 가능
# Generate ClusterRole with all available permissions from the target cluster
kubectl rbac-tool show

# Shows the subject for the current context with which one authenticates with the cluster
kubectl rbac-tool whoami

# Summarize RBAC roles for subjects : ServiceAccount(default), User, Group
kubectl rolesum -h

 
 
EKS에서 인증 흐름 과정에 대해 명령어를 입력하며 확인해보겠습니다.

1) aws-auth configmap 방식

 
먼저 kubectl 명령어를 사용했을 때  aws eks get-token 명령어를 사용하여  STS에 토큰 요청합니다.
 
++) STS (Security Token Service)

  • AWS 리소스에 대한 액세스를 제어할 수 있는 임시 보안 자격 증명(STS)을 생성하여 신뢰받는 사용자에게 제공할 수 있음
# sts caller id의 ARN 확인
❯ aws sts get-caller-identity --query Arn
"arn:aws:iam::94~~30:user/admin"

# kubeconfig 정보 확인
❯ cat ~/.kube/config
...
- name: arn:aws:eks:ap-northeast-2:94~~30:cluster/myeks
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - --region
      - ap-northeast-2
      - eks
      - get-token
      - --cluster-name
      - myeks
      - --output
      - json
      command: aws
      env: null
      interactiveMode: IfAvailable
      provideClusterInfo: false
      
# 임시 보안 자격 증명(토큰)을 요청 : expirationTimestamp 시간경과 시 토큰 재발급됨
❯ aws eks get-token --cluster-name $CLUSTER_NAME | jq
{
  "kind": "ExecCredential",
  "apiVersion": "client.authentication.k8s.io/v1beta1",
  "spec": {},
  "status": {
    "expirationTimestamp": "2025-03-12T15:42:16Z",
    "token": "k8s-aws-v1.aHR0cH~~ZTE"
  }
}

 
kubectl의 client-go 라이브러리는 Pre-Signed URL을 Bearer Token으로 EKS API Cluster Endpoint로 요청을 보냅니다.

❯ aws eks get-token --cluster-name $CLUSTER_NAME --debug | jq
Action=GetCallerIdentity&
Version=2011-06-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKI~~~~%2F20250312%2Fap-northeast-2%2Fsts%2Faws4_request&
X-Amz-Date=20250312T153126Z&
X-Amz-Expires=60&
X-Amz-SignedHeaders=host%3Bx-k8s-aws-id

 
EKS API는 Token Review 를 Webhook token authenticator에 요청합니다.  (STS GetCallerIdentity 호출)
AWS IAM에서 해당 호출에 대한 인증이 완료되면 User/Role에 대한 ARN 반환합니다.

❯ kubectl api-resources | grep authentication                         

selfsubjectreviews                               authentication.k8s.io/v1          false        SelfSubjectReview
tokenreviews                                     authentication.k8s.io/v1          false        TokenReview


❯ kubectl explain tokenreviews                                       

GROUP:      authentication.k8s.io
KIND:       TokenReview
VERSION:    v1

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.

FIELDS:
    ...

 
 
 
이제 쿠버네티스 RBAC 인가를 처리합니다.
해당 IAM User/Role 확인이 되면 k8s aws-auth configmap에서 mapping 정보를 확인하게 됩니다. aws-auth 컨피그맵에 'IAM 사용자, 역할 arm, K8S 오브젝트' 로 권한 확인 후 k8s 인가 허가가 되면 최종적으로 동작 실행을 합니다.
(참고로 EKS를 생성한 IAM principal은 aws-auth 와 상관없이 kubernetes-admin Username으로 system:masters 그룹에 권한을 가집니다.)
 

❯ kubectl get cm -n kube-system aws-auth -o yaml                ✘ INT ○ myeks 00:40:46

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7
      username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
  creationTimestamp: "2025-03-10T14:51:28Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "1986"
  uid: d178a433-18af-48ee-a722-481189c01815
  
 
# [운영서버1] 
kubectl rbac-tool whoami
{Username: "arn:aws:iam::941377114730:user/admin",
 UID:      "aws-iam-authenticator:941377114730:AIDA5WLTS2JVJR2Z4ZUJI",
 Groups:   ["system:authenticated"],
 Extra:    {accessKeyId:                                   ["AKIA5WLTS2JVMTLRKB5F"],
            arn:                                           ["arn:aws:iam::941377114730:user/admin"],
            canonicalArn:                                  ["arn:aws:iam::941377114730:user/admin"],
            principalId:                                   ["AIDA5WLTS2JVJR2Z4ZUJI"],
            sessionName:                                   [""],
            sigs.k8s.io/aws-iam-authenticator/principalId: ["AIDA5WLTS2JVJR2Z4ZUJI"]}}
            
            
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            
  
  
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
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]

 

실습

이제 aws-auth configmap 사용해서 신규 사용자의 접근이 가능하도록 권한을 부여하겠습니다.
현재 사용하는 운영 환경 1은 기존 EKS 클러스터에 대한 설정이 모두 되어있는 노드이고, 운영 환경 2는 설정이 되어 있지 않은 점 참고 부탁드립니다.

### 운영서버 1에서 실행
aws iam create-user --user-name testuser
{
    "User": {
        "Path": "/",
        "UserName": "testuser",
        "UserId": "AIDA5WLTS2JVKMO7D6OK3",
        "Arn": "arn:aws:iam::941377114730:user/testuser",
        "CreateDate": "2025-03-12T15:57:47+00:00"
    }
}

# 사용자에게 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name testuser

{
    "AccessKey": {
        "UserName": "testuser",
        "AccessKeyId": "AKIA5WLTS2JVDZVM73Q5",
        "Status": "Active",
        "SecretAccessKey": "I6ECpVdmmewCc1zbiof7tFZ7gpN4VXID18COWJY4",
        "CreateDate": "2025-03-12T15:58:05+00:00"
    }
}

# testuser 사용자에 정책을 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser

# get-caller-identity 확인 - 현재는 user/admin
aws sts get-caller-identity --query Arn
"arn:aws:iam::941377114730:user/admin"

# 사용자 확인 - 현재는 user/admin
kubectl whoami
arn:aws:iam::941377114730:user/admin

# 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

 

### 운영서버 2에서 실행

# get-caller-identity 확인 -> aws configure 하지 않아서 불러오지 못함
aws sts get-caller-identity --query Arn
Unable to locate credentials. You can configure credentials by running "aws configure".

# aws configure 설정
aws configure
AWS Access Key ID [None]: AWS Secret Access Key [None]: AKIA5WLTS2JVDZVM73Q5
Default region name [None]:   ap-northeast-2
Default output format [None]: I6ECpVdmmewCc1zbiof7tFZ7gpN4VXID18COWJY4

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

# 노드 조회 -> 실패 -> kubeconfig 없음
kubectl get node -v6
I0313 01:03:36.676550   48722 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 01:03:36.677820   48722 round_trippers.go:553] GET http://localhost:8080/api?timeout=32s  in 0 milliseconds
E0313 01:03:36.677908   48722 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp 127.0.0.1:8080: connect: connection refused"
I0313 01:03:36.679066   48722 cached_discovery.go:120] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.679532   48722 round_trippers.go:553] GET http://localhost:8080/api?timeout=32s  in 0 milliseconds
E0313 01:03:36.679611   48722 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp 127.0.0.1:8080: connect: connection refused"
I0313 01:03:36.680756   48722 cached_discovery.go:120] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.680805   48722 shortcut.go:103] Error loading discovery information: Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.681532   48722 round_trippers.go:553] GET http://localhost:8080/api?timeout=32s  in 0 milliseconds
E0313 01:03:36.681606   48722 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp 127.0.0.1:8080: connect: connection refused"
I0313 01:03:36.683003   48722 cached_discovery.go:120] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.685580   48722 round_trippers.go:553] GET http://localhost:8080/api?timeout=32s  in 2 milliseconds
E0313 01:03:36.685685   48722 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp 127.0.0.1:8080: connect: connection refused"
I0313 01:03:36.687389   48722 cached_discovery.go:120] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.687888   48722 round_trippers.go:553] GET http://localhost:8080/api?timeout=32s  in 0 milliseconds
E0313 01:03:36.687963   48722 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp 127.0.0.1:8080: connect: connection refused"
I0313 01:03:36.689141   48722 cached_discovery.go:120] skipped caching discovery info due to Get "http://localhost:8080/api?timeout=32s": dial tcp 127.0.0.1:8080: connect: connection refused
I0313 01:03:36.689197   48722 helpers.go:264] Connection error: Get http://localhost:8080/api?timeout=32s: dial tcp 127.0.0.1:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?

 

### 운영서버 1에서 동작
# IAM Role이나 유저를 쿠버네티스 유저나 롤과 매핑
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN											USERNAME	GROUPS					ACCOUNT
arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7	system:node:{{EC2PrivateDNSName}}	system:bootstrappers,system:nodes

eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuser
2025-03-13 01:07:47 [ℹ]  checking arn arn:aws:iam::941377114730:user/testuser against entries in the auth ConfigMap
2025-03-13 01:07:47 [ℹ]  adding identity "arn:aws:iam::941377114730:user/testuser" to auth ConfigMap

# 확인
# testuser가 매핑 되었음!
kubectl get cm -n kube-system aws-auth -o yaml

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    - groups:
      - system:masters
      userarn: arn:aws:iam::941377114730:user/testuser
      username: testuser
kind: ConfigMap
metadata:
  creationTimestamp: "2025-03-10T14:51:28Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "735821"
  uid: d178a433-18af-48ee-a722-481189c01815

 

### 운영서버 2에서 작업
# testuser kubeconfig 생성
CLUSTER_NAME=myeks
aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias testuser
Added new context testuser to /root/.kube/config

# 이젠 노드 조회 가능!
kubectl get node -v6
I0313 01:09:51.197766   49261 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 01:09:52.113723   49261 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 200 OK in 910 milliseconds
NAME                                               STATUS   ROLES    AGE    VERSION
ip-192-168-1-243.ap-northeast-2.compute.internal   Ready    <none>   2d1h   v1.31.5-eks-5d632ec
ip-192-168-2-169.ap-northeast-2.compute.internal   Ready    <none>   2d1h   v1.31.5-eks-5d632ec
ip-192-168-3-35.ap-northeast-2.compute.internal    Ready    <none>   2d1h   v1.31.5-eks-5d632ec

# rbac-tool 후 확인
# 기존 aws-auth configmap에 testuser가 system:masters 그룹과 연결되었음
kubectl rbac-tool whoami
{Username: "testuser", # 기존과 다름
 UID:      "aws-iam-authenticator:941377114730:AIDA5WLTS2JVKMO7D6OK3",
 Groups:   ["system:masters", # 기존과 달리 추가됨
            "system:authenticated"],
 Extra:    {accessKeyId:                                   ["AKIA5WLTS2JVDZVM73Q5"],
            arn:                                           ["arn:aws:iam::941377114730:user/testuser"],
            canonicalArn:                                  ["arn:aws:iam::941377114730:user/testuser"],
            principalId:                                   ["AIDA5WLTS2JVKMO7D6OK3"],
            sessionName:                                   [""],
            sigs.k8s.io/aws-iam-authenticator/principalId: ["AIDA5WLTS2JVKMO7D6OK3"]}}

 

### 운영서버 1에서 작업

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

# 확인
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN											USERNAME	GROUPS					ACCOUNT
arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7	system:node:{{EC2PrivateDNSName}}	system:bootstrappers,system:nodes
arn:aws:iam::941377114730:user/testuser							testuser	system:authenticated ## Group 변경 되었음

 

### 운영서버 2에서 작업
# 노드 조회 -> 아까는 되었지만 지금은 안됌! 권한이 없다.!
kubectl get node -v6
I0313 01:29:17.230933   49514 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 01:29:18.118500   49514 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 403 Forbidden in 882 milliseconds
I0313 01:29:18.118773   49514 helpers.go:246] server response object: [{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "nodes is forbidden: User \"testuser\" cannot list resource \"nodes\" in API group \"\" at the cluster scope",
  "reason": "Forbidden",
  "details": {
    "kind": "nodes"
  },
  "code": 403
}]
Error from server (Forbidden): nodes is forbidden: User "testuser" cannot list resource "nodes" in API group "" at the cluster scope

kubectl api-resources -v5
kubectl api-resources -v5
NAME                                SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                         v1                                true         Binding
componentstatuses                   cs           v1                                false        ComponentStatus
configmaps                          cm           v1                                true         ConfigMap
endpoints                           ep           v1                                true         Endpoints
events                              ev           v1                                true         Event
limitranges                         limits       v1                                true         LimitRange
namespaces                          ns           v1                                false        Namespace
nodes                               no           v1                                false        Node
persistentvolumeclaims              pvc          v1                                true         PersistentVolumeClaim
persistentvolumes                   pv           v1                                false        PersistentVolume
pods                                po           v1                                true         Pod
podtemplates                                     v1                                true         PodTemplate
replicationcontrollers              rc           v1                                true         ReplicationController
resourcequotas                      quota        v1                                true         ResourceQuota
secrets                                          v1                                true         Secret
serviceaccounts                     sa           v1                                true         ServiceAccount
services                            svc          v1                                true         Service
mutatingwebhookconfigurations                    admissionregistration.k8s.io/v1   false        MutatingWebhookConfiguration
validatingadmissionpolicies                      admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicy
validatingadmissionpolicybindings                admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations                  admissionregistration.k8s.io/v1   false        ValidatingWebhookConfiguration
customresourcedefinitions           crd,crds     apiextensions.k8s.io/v1           false        CustomResourceDefinition
apiservices                                      apiregistration.k8s.io/v1         false        APIService
controllerrevisions                              apps/v1                           true         ControllerRevision
daemonsets                          ds           apps/v1                           true         DaemonSet
deployments                         deploy       apps/v1                           true         Deployment
replicasets                         rs           apps/v1                           true         ReplicaSet
statefulsets                        sts          apps/v1                           true         StatefulSet
selfsubjectreviews                               authentication.k8s.io/v1          false        SelfSubjectReview
tokenreviews                                     authentication.k8s.io/v1          false        TokenReview
localsubjectaccessreviews                        authorization.k8s.io/v1           true         LocalSubjectAccessReview
selfsubjectaccessreviews                         authorization.k8s.io/v1           false        SelfSubjectAccessReview
selfsubjectrulesreviews                          authorization.k8s.io/v1           false        SelfSubjectRulesReview
subjectaccessreviews                             authorization.k8s.io/v1           false        SubjectAccessReview
horizontalpodautoscalers            hpa          autoscaling/v2                    true         HorizontalPodAutoscaler
cronjobs                            cj           batch/v1                          true         CronJob
jobs                                             batch/v1                          true         Job
certificatesigningrequests          csr          certificates.k8s.io/v1            false        CertificateSigningRequest
leases                                           coordination.k8s.io/v1            true         Lease
eniconfigs                                       crd.k8s.amazonaws.com/v1alpha1    false        ENIConfig
endpointslices                                   discovery.k8s.io/v1               true         EndpointSlice
events                              ev           events.k8s.io/v1                  true         Event
flowschemas                                      flowcontrol.apiserver.k8s.io/v1   false        FlowSchema
prioritylevelconfigurations                      flowcontrol.apiserver.k8s.io/v1   false        PriorityLevelConfiguration
nodes                                            metrics.k8s.io/v1beta1            false        NodeMetrics                      # False 임!!!
pods                                             metrics.k8s.io/v1beta1            true         PodMetrics
policyendpoints                                  networking.k8s.aws/v1alpha1       true         PolicyEndpoint
ingressclasses                                   networking.k8s.io/v1              false        IngressClass
ingresses                           ing          networking.k8s.io/v1              true         Ingress
networkpolicies                     netpol       networking.k8s.io/v1              true         NetworkPolicy
runtimeclasses                                   node.k8s.io/v1                    false        RuntimeClass
poddisruptionbudgets                pdb          policy/v1                         true         PodDisruptionBudget
clusterrolebindings                              rbac.authorization.k8s.io/v1      false        ClusterRoleBinding
clusterroles                                     rbac.authorization.k8s.io/v1      false        ClusterRole
rolebindings                                     rbac.authorization.k8s.io/v1      true         RoleBinding
roles                                            rbac.authorization.k8s.io/v1      true         Role
priorityclasses                     pc           scheduling.k8s.io/v1              false        PriorityClass
csidrivers                                       storage.k8s.io/v1                 false        CSIDriver
csinodes                                         storage.k8s.io/v1                 false        CSINode
csistoragecapacities                             storage.k8s.io/v1                 true         CSIStorageCapacity
storageclasses                      sc           storage.k8s.io/v1                 false        StorageClass
volumeattachments                                storage.k8s.io/v1                 false        VolumeAttachment
volumeattributesclasses             vac          storage.k8s.io/v1beta1            false        VolumeAttributesClass
cninodes                            cnd          vpcresources.k8s.aws/v1alpha1     false        CNINode
securitygrouppolicies               sgp          vpcresources.k8s.aws/v1beta1      true         SecurityGroupPolicy

 

### 운영서버 1에서 작업
# testuser IAM 맵핑 삭제
eksctl delete iamidentitymapping --cluster $CLUSTER_NAME --arn  arn:aws:iam::$ACCOUNT_ID:user/testuser
2025-03-13 01:31:34 [ℹ]  removing identity "arn:aws:iam::941377114730:user/testuser" from auth ConfigMap (username = "testuser", groups = ["system:authenticated"])

# Get IAM identity mapping(s)
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN											USERNAME	GROUPS					ACCOUNT
arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7	system:node:{{EC2PrivateDNSName}}	system:bootstrappers,system:nodes

# aws-auth config 확인
kubectl get cm -n kube-system aws-auth -o yaml
apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7
      username: system:node:{{EC2PrivateDNSName}}
  mapUsers: |
    []
kind: ConfigMap
metadata:
  creationTimestamp: "2025-03-10T14:51:28Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "741719"
  uid: d178a433-18af-48ee-a722-481189c01815

 

### 운영서버 2에서 작업
# 테스트
kubectl get node -v6
I0313 01:32:50.684922   49744 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 01:32:52.481866   49744 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 401 Unauthorized in 1793 milliseconds
I0313 01:32:52.482190   49744 helpers.go:246] server response object: [{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}]
error: You must be logged in to the server (Unauthorized)

kubectl api-resources -v5
E0313 01:33:08.793805   49798 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: the server has asked for the client to provide credentials"
I0313 01:33:08.794973   49798 cached_discovery.go:120] skipped caching discovery info due to the server has asked for the client to provide credentials
NAME   SHORTNAMES   APIVERSION   NAMESPACED   KIND
I0313 01:33:08.795216   49798 helpers.go:246] server response object: [{
  "metadata": {},
  "status": "Failure",
  "message": "the server has asked for the client to provide credentials",
  "reason": "Unauthorized",
  "details": {
    "causes": [
      {
        "reason": "UnexpectedServerResponse",
        "message": "unknown"
      }
    ]
  },
  "code": 401
}]
error: You must be logged in to the server (the server has asked for the client to provide credentials)

 

2) EKS API 방식

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

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

A deep dive into simplified Amazon EKS access management controls | Amazon Web Services

Introduction Since the initial Amazon Elastic Kubernetes Service (Amazon EKS) launch, it has supported AWS Identity and Access Management (AWS IAM) principals as entities that can authenticate against a cluster. This was done to remove the burden—from ad

aws.amazon.com

 
 
현재 EKS 클러스터의 액세스 관리에서 aws-auth configmap을 사용하고 있어서 EKS API 및 ConfigMap으로 되어있는데  이를 EKS API로 변경하여 위의 testuser 유저 생성하여 권한 테스트 하는 실습을 진행해보겠습니다.
참고로, EKS API 및 ConfigMap 정책 중복 시 EKS API 우선되며 ConfigMap은 무시됩니다.
 

### 운영서버 1에서 작업
# EKS API 액세스모드로 변경
aws eks update-cluster-config --name $CLUSTER_NAME --access-config authenticationMode=API
{
    "update": {
        "id": "0a320959-4460-3341-bd02-f93e7a08f9e3",
        "status": "InProgress",
        "type": "AccessConfigUpdate",
        "params": [
            {
                "type": "AuthenticationMode",
                "value": "\"API\"" # API로 변경
            }
        ],
        "createdAt": "2025-03-13T01:38:19.828000+09:00",
        "errors": []
    }
}

# 맵핑 클러스터롤 정보 확인
kubectl get clusterroles -l 'kubernetes.io/bootstrapping=rbac-defaults' | grep -v 'system:'
NAME                                                                   CREATED AT
admin                                                                  2025-03-10T14:42:28Z
cluster-admin                                                          2025-03-10T14:42:28Z
edit                                                                   2025-03-10T14:42:28Z
view                                                                   2025-03-10T14:42:28Z



aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq
{
  "accessEntries": [
    "arn:aws:iam::941377114730:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS",
    "arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7",
    "arn:aws:iam::941377114730:user/admin"
  ]
}

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 
{
  "associatedAccessPolicies": [
    {
      "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
      "accessScope": {
        "type": "cluster",
        "namespaces": []
      },
      "associatedAt": "2025-03-10T23:37:35.556000+09:00",
      "modifiedAt": "2025-03-10T23:37:35.556000+09:00"
    }
  ],
  "clusterName": "myeks",
  "principalArn": "arn:aws:iam::941377114730:user/admin"
}

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

aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/admin | jq
{
  "accessEntry": {
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/admin",
    "kubernetesGroups": [],
    "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/admin/3ccac03e-b0a3-20c7-58d3-86adcdfd040f",
    "createdAt": "2025-03-10T23:37:35.488000+09:00",
    "modifiedAt": "2025-03-10T23:37:35.488000+09:00",
    "tags": {},
    "username": "arn:aws:iam::941377114730:user/admin",
    "type": "STANDARD"
  }
}

aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7 | jq
{
  "accessEntry": {
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7",
    "kubernetesGroups": [
      "system:nodes"
    ],
    "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/role/941377114730/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7/48cac045-0cc1-be8f-0445-c9cdc7e0ec4c",
    "createdAt": "2025-03-10T23:51:29.117000+09:00",
    "modifiedAt": "2025-03-10T23:51:29.117000+09:00",
    "tags": {},
    "username": "system:node:{{EC2PrivateDNSName}}",
    "type": "EC2_LINUX"
  }
}

 

### 운영서버 1에서 작업
 testuser 의 access entry 생성
aws eks create-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser
{
    "accessEntry": {
        "clusterName": "myeks",
        "principalArn": "arn:aws:iam::941377114730:user/testuser",
        "kubernetesGroups": [],
        "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/e2cac5a2-0b64-5e47-c32e-7450f9949ea8",
        "createdAt": "2025-03-13T01:50:50.225000+09:00",
        "modifiedAt": "2025-03-13T01:50:50.225000+09:00",
        "tags": {},
        "username": "arn:aws:iam::941377114730:user/testuser",
        "type": "STANDARD"
    }
}

aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq -r .accessEntries[]

arn:aws:iam::941377114730:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS
arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7
arn:aws:iam::941377114730:user/admin
arn:aws:iam::941377114730:user/testuser

# 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
{
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/testuser",
    "associatedAccessPolicy": {
        "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
        "accessScope": {
            "type": "cluster",
            "namespaces": []
        },
        "associatedAt": "2025-03-13T01:52:09.106000+09:00",
        "modifiedAt": "2025-03-13T01:52:09.106000+09:00"
    }
}

aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq
{
  "associatedAccessPolicies": [
    {
      "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
      "accessScope": {
        "type": "cluster",
        "namespaces": []
      },
      "associatedAt": "2025-03-13T01:52:09.106000+09:00",
      "modifiedAt": "2025-03-13T01:52:09.106000+09:00"
    }
  ],
  "clusterName": "myeks",
  "principalArn": "arn:aws:iam::941377114730:user/testuser"
}

aws eks describe-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser | jq
{
  "accessEntry": {
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/testuser",
    "kubernetesGroups": [],
    "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/e2cac5a2-0b64-5e47-c32e-7450f9949ea8",
    "createdAt": "2025-03-13T01:50:50.225000+09:00",
    "modifiedAt": "2025-03-13T01:50:50.225000+09:00",
    "tags": {},
    "username": "arn:aws:iam::941377114730:user/testuser",
    "type": "STANDARD"
  }
}

 

### 운영 서버 2에서 작업
# testuser 정보 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::941377114730:user/testuser"

kubectl whoami
arn:aws:iam::941377114730:user/testuser

# kubectl 시도
kubectl get node -v6
I0313 02:03:00.264590   50321 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 02:03:01.203633   50321 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500 200 OK in 934 milliseconds
NAME                                               STATUS   ROLES    AGE    VERSION
ip-192-168-1-243.ap-northeast-2.compute.internal   Ready    <none>   2d2h   v1.31.5-eks-5d632ec
ip-192-168-2-169.ap-northeast-2.compute.internal   Ready    <none>   2d2h   v1.31.5-eks-5d632ec
ip-192-168-3-35.ap-northeast-2.compute.internal    Ready    <none>   2d2h   v1.31.5-eks-5d632ec

kubectl api-resources -v5
NAME                                SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                         v1                                true         Binding
componentstatuses                   cs           v1                                false        ComponentStatus
configmaps                          cm           v1                                true         ConfigMap
endpoints                           ep           v1                                true         Endpoints
events                              ev           v1                                true         Event
limitranges                         limits       v1                                true         LimitRange
namespaces                          ns           v1                                false        Namespace
nodes                               no           v1                                false        Node
persistentvolumeclaims              pvc          v1                                true         PersistentVolumeClaim
persistentvolumes                   pv           v1                                false        PersistentVolume
pods                                po           v1                                true         Pod
podtemplates                                     v1                                true         PodTemplate
replicationcontrollers              rc           v1                                true         ReplicationController
resourcequotas                      quota        v1                                true         ResourceQuota
secrets                                          v1                                true         Secret
serviceaccounts                     sa           v1                                true         ServiceAccount
services                            svc          v1                                true         Service
mutatingwebhookconfigurations                    admissionregistration.k8s.io/v1   false        MutatingWebhookConfiguration
validatingadmissionpolicies                      admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicy
validatingadmissionpolicybindings                admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations                  admissionregistration.k8s.io/v1   false        ValidatingWebhookConfiguration
customresourcedefinitions           crd,crds     apiextensions.k8s.io/v1           false        CustomResourceDefinition
apiservices                                      apiregistration.k8s.io/v1         false        APIService
controllerrevisions                              apps/v1                           true         ControllerRevision
daemonsets                          ds           apps/v1                           true         DaemonSet
deployments                         deploy       apps/v1                           true         Deployment
replicasets                         rs           apps/v1                           true         ReplicaSet
statefulsets                        sts          apps/v1                           true         StatefulSet
selfsubjectreviews                               authentication.k8s.io/v1          false        SelfSubjectReview
tokenreviews                                     authentication.k8s.io/v1          false        TokenReview
localsubjectaccessreviews                        authorization.k8s.io/v1           true         LocalSubjectAccessReview
selfsubjectaccessreviews                         authorization.k8s.io/v1           false        SelfSubjectAccessReview
selfsubjectrulesreviews                          authorization.k8s.io/v1           false        SelfSubjectRulesReview
subjectaccessreviews                             authorization.k8s.io/v1           false        SubjectAccessReview
horizontalpodautoscalers            hpa          autoscaling/v2                    true         HorizontalPodAutoscaler
cronjobs                            cj           batch/v1                          true         CronJob
jobs                                             batch/v1                          true         Job
certificatesigningrequests          csr          certificates.k8s.io/v1            false        CertificateSigningRequest
leases                                           coordination.k8s.io/v1            true         Lease
eniconfigs                                       crd.k8s.amazonaws.com/v1alpha1    false        ENIConfig
endpointslices                                   discovery.k8s.io/v1               true         EndpointSlice
events                              ev           events.k8s.io/v1                  true         Event
flowschemas                                      flowcontrol.apiserver.k8s.io/v1   false        FlowSchema
prioritylevelconfigurations                      flowcontrol.apiserver.k8s.io/v1   false        PriorityLevelConfiguration
nodes                                            metrics.k8s.io/v1beta1            false        NodeMetrics
pods                                             metrics.k8s.io/v1beta1            true         PodMetrics
policyendpoints                                  networking.k8s.aws/v1alpha1       true         PolicyEndpoint
ingressclasses                                   networking.k8s.io/v1              false        IngressClass
ingresses                           ing          networking.k8s.io/v1              true         Ingress
networkpolicies                     netpol       networking.k8s.io/v1              true         NetworkPolicy
runtimeclasses                                   node.k8s.io/v1                    false        RuntimeClass
poddisruptionbudgets                pdb          policy/v1                         true         PodDisruptionBudget
clusterrolebindings                              rbac.authorization.k8s.io/v1      false        ClusterRoleBinding
clusterroles                                     rbac.authorization.k8s.io/v1      false        ClusterRole
rolebindings                                     rbac.authorization.k8s.io/v1      true         RoleBinding
roles                                            rbac.authorization.k8s.io/v1      true         Role
priorityclasses                     pc           scheduling.k8s.io/v1              false        PriorityClass
csidrivers                                       storage.k8s.io/v1                 false        CSIDriver
csinodes                                         storage.k8s.io/v1                 false        CSINode
csistoragecapacities                             storage.k8s.io/v1                 true         CSIStorageCapacity
storageclasses                      sc           storage.k8s.io/v1                 false        StorageClass
volumeattachments                                storage.k8s.io/v1                 false        VolumeAttachment
volumeattributesclasses             vac          storage.k8s.io/v1beta1            false        VolumeAttributesClass
cninodes                            cnd          vpcresources.k8s.aws/v1alpha1     false        CNINode
securitygrouppolicies               sgp          vpcresources.k8s.aws/v1beta1      true         SecurityGroupPolicy


kubectl rbac-tool whoami
{Username: "arn:aws:iam::941377114730:user/testuser",
 UID:      "aws-iam-authenticator:941377114730:AIDA5WLTS2JVKMO7D6OK3",
 Groups:   ["system:authenticated"],
 Extra:    {accessKeyId:                                   ["AKIA5WLTS2JVDZVM73Q5"],
            arn:                                           ["arn:aws:iam::941377114730:user/testuser"],
            canonicalArn:                                  ["arn:aws:iam::941377114730:user/testuser"],
            principalId:                                   ["AIDA5WLTS2JVKMO7D6OK3"],
            sessionName:                                   [""],
            sigs.k8s.io/aws-iam-authenticator/principalId: ["AIDA5WLTS2JVKMO7D6OK3"]}}

 
https://catalog.workshops.aws/eks-immersionday/en-US/access-management/3-kubernetes-groups

EKS Advanced Workshop

catalog.workshops.aws

 

# 기존 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[]
arn:aws:iam::941377114730:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS
arn:aws:iam::941377114730:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-FZUyvVNlBcW7
arn:aws:iam::941377114730:user/admin

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
clusterrole.rbac.authorization.k8s.io/pod-viewer-role created
kubectl apply -f ~/pod-admin-role.yaml
clusterrole.rbac.authorization.k8s.io/pod-admin-role created

# ClusterRole 바인딩
kubectl create clusterrolebinding viewer-role-binding --clusterrole=pod-viewer-role --group=pod-viewer
clusterrolebinding.rbac.authorization.k8s.io/viewer-role-binding created
kubectl create clusterrolebinding admin-role-binding --clusterrole=pod-admin-role --group=pod-admin
clusterrolebinding.rbac.authorization.k8s.io/admin-role-binding created

# access-entry 생성
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::941377114730:user/testuser",
        "kubernetesGroups": [
            "pod-viewer"
        ],
        "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/c4cac5a9-f25e-ad76-9e0b-362df889e96f",
        "createdAt": "2025-03-13T02:08:06.014000+09:00",
        "modifiedAt": "2025-03-13T02:08:06.014000+09:00",
        "tags": {},
        "username": "arn:aws:iam::941377114730:user/testuser",
        "type": "STANDARD"
    }
}

# access-entry 조회 및 확인
aws eks list-associated-access-policies --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::$ACCOUNT_ID:user/testuser

{
    "associatedAccessPolicies": [],
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/testuser"
}

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

{
  "accessEntry": {
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/testuser",
    "kubernetesGroups": [
      "pod-viewer"  # 확인
    ],
    "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/c4cac5a9-f25e-ad76-9e0b-362df889e96f",
    "createdAt": "2025-03-13T02:08:06.014000+09:00",
    "modifiedAt": "2025-03-13T02:08:06.014000+09:00",
    "tags": {},
    "username": "arn:aws:iam::941377114730:user/testuser",
    "type": "STANDARD"
  }
}

 

### 운영서버 2에서 작업
# testuser 정보 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::941377114730:user/testuser"

kubectl whoami
arn:aws:iam::941377114730:user/testuser

# kubectl 시도
kubectl get pod -v6
kubectl get pod -v6
I0313 02:10:51.752821   50878 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 02:10:52.655198   50878 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500 200 OK in 897 milliseconds
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          25h

kubectl api-resources -v5
NAME                                SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                         v1                                true         Binding
componentstatuses                   cs           v1                                false        ComponentStatus
configmaps                          cm           v1                                true         ConfigMap
endpoints                           ep           v1                                true         Endpoints
events                              ev           v1                                true         Event
limitranges                         limits       v1                                true         LimitRange
namespaces                          ns           v1                                false        Namespace
nodes                               no           v1                                false        Node
persistentvolumeclaims              pvc          v1                                true         PersistentVolumeClaim
persistentvolumes                   pv           v1                                false        PersistentVolume
pods                                po           v1                                true         Pod
podtemplates                                     v1                                true         PodTemplate
replicationcontrollers              rc           v1                                true         ReplicationController
resourcequotas                      quota        v1                                true         ResourceQuota
secrets                                          v1                                true         Secret
serviceaccounts                     sa           v1                                true         ServiceAccount
services                            svc          v1                                true         Service
mutatingwebhookconfigurations                    admissionregistration.k8s.io/v1   false        MutatingWebhookConfiguration
validatingadmissionpolicies                      admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicy
validatingadmissionpolicybindings                admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations                  admissionregistration.k8s.io/v1   false        ValidatingWebhookConfiguration
customresourcedefinitions           crd,crds     apiextensions.k8s.io/v1           false        CustomResourceDefinition
apiservices                                      apiregistration.k8s.io/v1         false        APIService
controllerrevisions                              apps/v1                           true         ControllerRevision
daemonsets                          ds           apps/v1                           true         DaemonSet
deployments                         deploy       apps/v1                           true         Deployment
replicasets                         rs           apps/v1                           true         ReplicaSet
statefulsets                        sts          apps/v1                           true         StatefulSet
selfsubjectreviews                               authentication.k8s.io/v1          false        SelfSubjectReview
tokenreviews                                     authentication.k8s.io/v1          false        TokenReview
localsubjectaccessreviews                        authorization.k8s.io/v1           true         LocalSubjectAccessReview
selfsubjectaccessreviews                         authorization.k8s.io/v1           false        SelfSubjectAccessReview
selfsubjectrulesreviews                          authorization.k8s.io/v1           false        SelfSubjectRulesReview
subjectaccessreviews                             authorization.k8s.io/v1           false        SubjectAccessReview
horizontalpodautoscalers            hpa          autoscaling/v2                    true         HorizontalPodAutoscaler
cronjobs                            cj           batch/v1                          true         CronJob
jobs                                             batch/v1                          true         Job
certificatesigningrequests          csr          certificates.k8s.io/v1            false        CertificateSigningRequest
leases                                           coordination.k8s.io/v1            true         Lease
eniconfigs                                       crd.k8s.amazonaws.com/v1alpha1    false        ENIConfig
endpointslices                                   discovery.k8s.io/v1               true         EndpointSlice
events                              ev           events.k8s.io/v1                  true         Event
flowschemas                                      flowcontrol.apiserver.k8s.io/v1   false        FlowSchema
prioritylevelconfigurations                      flowcontrol.apiserver.k8s.io/v1   false        PriorityLevelConfiguration
nodes                                            metrics.k8s.io/v1beta1            false        NodeMetrics
pods                                             metrics.k8s.io/v1beta1            true         PodMetrics
policyendpoints                                  networking.k8s.aws/v1alpha1       true         PolicyEndpoint
ingressclasses                                   networking.k8s.io/v1              false        IngressClass
ingresses                           ing          networking.k8s.io/v1              true         Ingress
networkpolicies                     netpol       networking.k8s.io/v1              true         NetworkPolicy
runtimeclasses                                   node.k8s.io/v1                    false        RuntimeClass
poddisruptionbudgets                pdb          policy/v1                         true         PodDisruptionBudget
clusterrolebindings                              rbac.authorization.k8s.io/v1      false        ClusterRoleBinding
clusterroles                                     rbac.authorization.k8s.io/v1      false        ClusterRole
rolebindings                                     rbac.authorization.k8s.io/v1      true         RoleBinding
roles                                            rbac.authorization.k8s.io/v1      true         Role
priorityclasses                     pc           scheduling.k8s.io/v1              false        PriorityClass
csidrivers                                       storage.k8s.io/v1                 false        CSIDriver
csinodes                                         storage.k8s.io/v1                 false        CSINode
csistoragecapacities                             storage.k8s.io/v1                 true         CSIStorageCapacity
storageclasses                      sc           storage.k8s.io/v1                 false        StorageClass
volumeattachments                                storage.k8s.io/v1                 false        VolumeAttachment
volumeattributesclasses             vac          storage.k8s.io/v1beta1            false        VolumeAttributesClass
cninodes                            cnd          vpcresources.k8s.aws/v1alpha1     false        CNINode
securitygrouppolicies               sgp          vpcresources.k8s.aws/v1beta1      true         SecurityGroupPolicy

kubectl auth can-i get pods --all-namespaces
yes

kubectl auth can-i delete pods --all-namespaces
no

 

### 운영서버 1에서 작업
# kubernetesGroup 업데이트 적용
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
{
  "clusterName": "myeks",
  "principalArn": "arn:aws:iam::941377114730:user/testuser",
  "kubernetesGroups": [
    "pod-admin"
  ],
  "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/c4cac5a9-f25e-ad76-9e0b-362df889e96f",
  "createdAt": "2025-03-13T02:08:06.014000+09:00",
  "modifiedAt": "2025-03-13T02:12:16.228000+09:00",
  "tags": {},
  "username": "arn:aws:iam::941377114730:user/testuser",
  "type": "STANDARD"
}

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

{
  "accessEntry": {
    "clusterName": "myeks",
    "principalArn": "arn:aws:iam::941377114730:user/testuser",
    "kubernetesGroups": [
      "pod-admin" # 변경
    ],
    "accessEntryArn": "arn:aws:eks:ap-northeast-2:941377114730:access-entry/myeks/user/941377114730/testuser/c4cac5a9-f25e-ad76-9e0b-362df889e96f",
    "createdAt": "2025-03-13T02:08:06.014000+09:00",
    "modifiedAt": "2025-03-13T02:12:16.228000+09:00",
    "tags": {},
    "username": "arn:aws:iam::941377114730:user/testuser",
    "type": "STANDARD"
  }
}

 

### 운영서버 2에서 작업
# testuser 정보 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::941377114730:user/testuser"
kubectl whoami
arn:aws:iam::941377114730:user/testuser

# kubectl 시도
kubectl get pod -v6
I0313 02:13:34.443859   51414 loader.go:395] Config loaded from file:  /root/.kube/config
I0313 02:13:35.355461   51414 round_trippers.go:553] GET https://8FA477A1B30E5E6D6E7473BD5FA8EA94.sk1.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500 200 OK in 904 milliseconds
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          25h

kubectl api-resources -v5
NAME                                SHORTNAMES   APIVERSION                        NAMESPACED   KIND
bindings                                         v1                                true         Binding
componentstatuses                   cs           v1                                false        ComponentStatus
configmaps                          cm           v1                                true         ConfigMap
endpoints                           ep           v1                                true         Endpoints
events                              ev           v1                                true         Event
limitranges                         limits       v1                                true         LimitRange
namespaces                          ns           v1                                false        Namespace
nodes                               no           v1                                false        Node
persistentvolumeclaims              pvc          v1                                true         PersistentVolumeClaim
persistentvolumes                   pv           v1                                false        PersistentVolume
pods                                po           v1                                true         Pod
podtemplates                                     v1                                true         PodTemplate
replicationcontrollers              rc           v1                                true         ReplicationController
resourcequotas                      quota        v1                                true         ResourceQuota
secrets                                          v1                                true         Secret
serviceaccounts                     sa           v1                                true         ServiceAccount
services                            svc          v1                                true         Service
mutatingwebhookconfigurations                    admissionregistration.k8s.io/v1   false        MutatingWebhookConfiguration
validatingadmissionpolicies                      admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicy
validatingadmissionpolicybindings                admissionregistration.k8s.io/v1   false        ValidatingAdmissionPolicyBinding
validatingwebhookconfigurations                  admissionregistration.k8s.io/v1   false        ValidatingWebhookConfiguration
customresourcedefinitions           crd,crds     apiextensions.k8s.io/v1           false        CustomResourceDefinition
apiservices                                      apiregistration.k8s.io/v1         false        APIService
controllerrevisions                              apps/v1                           true         ControllerRevision
daemonsets                          ds           apps/v1                           true         DaemonSet
deployments                         deploy       apps/v1                           true         Deployment
replicasets                         rs           apps/v1                           true         ReplicaSet
statefulsets                        sts          apps/v1                           true         StatefulSet
selfsubjectreviews                               authentication.k8s.io/v1          false        SelfSubjectReview
tokenreviews                                     authentication.k8s.io/v1          false        TokenReview
localsubjectaccessreviews                        authorization.k8s.io/v1           true         LocalSubjectAccessReview
selfsubjectaccessreviews                         authorization.k8s.io/v1           false        SelfSubjectAccessReview
selfsubjectrulesreviews                          authorization.k8s.io/v1           false        SelfSubjectRulesReview
subjectaccessreviews                             authorization.k8s.io/v1           false        SubjectAccessReview
horizontalpodautoscalers            hpa          autoscaling/v2                    true         HorizontalPodAutoscaler
cronjobs                            cj           batch/v1                          true         CronJob
jobs                                             batch/v1                          true         Job
certificatesigningrequests          csr          certificates.k8s.io/v1            false        CertificateSigningRequest
leases                                           coordination.k8s.io/v1            true         Lease
eniconfigs                                       crd.k8s.amazonaws.com/v1alpha1    false        ENIConfig
endpointslices                                   discovery.k8s.io/v1               true         EndpointSlice
events                              ev           events.k8s.io/v1                  true         Event
flowschemas                                      flowcontrol.apiserver.k8s.io/v1   false        FlowSchema
prioritylevelconfigurations                      flowcontrol.apiserver.k8s.io/v1   false        PriorityLevelConfiguration
nodes                                            metrics.k8s.io/v1beta1            false        NodeMetrics
pods                                             metrics.k8s.io/v1beta1            true         PodMetrics
policyendpoints                                  networking.k8s.aws/v1alpha1       true         PolicyEndpoint
ingressclasses                                   networking.k8s.io/v1              false        IngressClass
ingresses                           ing          networking.k8s.io/v1              true         Ingress
networkpolicies                     netpol       networking.k8s.io/v1              true         NetworkPolicy
runtimeclasses                                   node.k8s.io/v1                    false        RuntimeClass
poddisruptionbudgets                pdb          policy/v1                         true         PodDisruptionBudget
clusterrolebindings                              rbac.authorization.k8s.io/v1      false        ClusterRoleBinding
clusterroles                                     rbac.authorization.k8s.io/v1      false        ClusterRole
rolebindings                                     rbac.authorization.k8s.io/v1      true         RoleBinding
roles                                            rbac.authorization.k8s.io/v1      true         Role
priorityclasses                     pc           scheduling.k8s.io/v1              false        PriorityClass
csidrivers                                       storage.k8s.io/v1                 false        CSIDriver
csinodes                                         storage.k8s.io/v1                 false        CSINode
csistoragecapacities                             storage.k8s.io/v1                 true         CSIStorageCapacity
storageclasses                      sc           storage.k8s.io/v1                 false        StorageClass
volumeattachments                                storage.k8s.io/v1                 false        VolumeAttachment
volumeattributesclasses             vac          storage.k8s.io/v1beta1            false        VolumeAttributesClass
cninodes                            cnd          vpcresources.k8s.aws/v1alpha1     false        CNINode
securitygrouppolicies               sgp          vpcresources.k8s.aws/v1beta1      true         SecurityGroupPolicy

kubectl auth can-i get pods --all-namespaces
yes

kubectl auth can-i delete pods --all-namespaces
yes # 변경