EKS Study 4주차 첫번째

덴고·2026년 4월 5일

이번주도 어김없이 스터디 공유를 시작하겠습니다


주제는 EKS AuthN/AuthZ입니다

관리자가 kubectl get node 실행 시 과정

[1] 클라이언트(aws cli)에서 토큰 생성 : Client side (aws-iam-authenticator token) - Github

  • AWS STS (Security Token Service) : AWS 리소스에 대한 액세스를 제어할 수 있는 임시 보안 자격 증명을 생성하여 신뢰받는 사용자에게 제공
    • AWS CLI 버전 1.16.156 이상에서는 별도 aws-iam-authenticator 설치 없이 aws eks get-token으로 사용 가능
# sts caller id의 ARN 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::<자신의 Account ID>:user/admin"

# kubeconfig 정보 확인
cat ~/.kube/config
...
users:
- name: arn:aws:eks:ap-northeast-2:911283464785: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

# 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 시간경과 시 토큰 재발급 필요.
## kubectl이 expirationTimestamp를 보고 알아서 새 토큰을 받아오기 때문에 사용자는 인지하지 못한 채 계속 작업할 수 있습니다.
export CLUSTER_NAME=myeks
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
...
2026-03-31 23:41:10,583 - MainThread - botocore.regions - DEBUG - Calling endpoint provider with parameters: {'Region': 'ap-northeast-2', 'UseDualStack': False, 'UseFIPS': False, 'UseGlobalEndpoint': False}
2026-03-31 23:41:10,583 - MainThread - botocore.regions - DEBUG - Endpoint provider result: https://sts.ap-northeast-2.amazonaws.com
...


# EKS 인증 토큰 가져오기
## 각 토큰은 k8s-aws-v1로 시작하여 base64 인코딩 문자열로 이어집니다.
TOKEN_DATA=$(aws eks get-token --cluster-name myeks | jq -r '.status.token')
echo $TOKEN_DATA
k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUE1SUxGMkZKSTNFR0tOR05ZJTJGMjAyNjAzMzElMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzMxVDEzNTAxNVomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTM1YzhkZmZiMWFiYzYwYmQ0Njg2ZmRhMWU0YWU1ZTgzN2Y2Y2NhNDczMjdhMWVjY2M5YTQ3Y2U5NDY2MDE2OTQ

# JWT 구조 분리 (Header, Payload, Signature)
## IFS='.': 내부 필드 구분자(Internal Field Separator)를 마침표로 설정
## read ...: 토큰을 세 부분으로 나누어 각각 header, payload, signature 변수에 담기
IFS='.' read header payload signature <<< "$TOKEN_DATA"

# Payload 디코딩 및 데이터 추출 => Pre-signed URL
## fold -w 4: 페이로드 문자열을 4글자씩 끊어서 여러 줄로 만듭니다. Base64 패딩 처리를 위한 준비
## sed '$ d': 마지막 줄을 삭제. AWS EKS 토큰의 페이로드 끝에는 간혹 URL-Safe 변환 과정에서 생긴 불필요한 문자나 패딩 이슈가 있을 수 있는데, 이를 정제하는 트릭
## tr -d '\n': 다시 모든 줄바꿈을 제거하여 하나의 문자열로 합침
## base64 --decode: 최종적으로 인코딩된 문자열을 복호화하여 실제 JSON 데이터를 출력
echo "$header"
echo "$signature"

echo "$payload"
echo "$payload" | fold -w 4 | sed '$ d' | tr -d '\n' | base64 --decode
https://sts.ap-northeast-2.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA5ILF2FJI3EGKNGNY%2F20260331%2Fap-northeast-2%2Fsts%2Faws4_request&X-Amz-Date=20260331T135015Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=35c8dffb1abc60bd4686fda1e4ae5e837f6cca47327a1eccc9a47ce9466016

https://sts.ap-northeast-2.amazonaws.com/?Action=GetCallerIdentity&
Version=2011-06-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIA5ILF2FJI3EGKNGNY%2F20260331%2Fap-northeast-2%2Fsts%2Faws4_request&  # aws access key id
X-Amz-Date=20260331T135015Z&X-Amz-Expires=60&
X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&
X-Amz-Signature=35c8dffb1abc60bd4686fda1e4ae5e837f6cca47327a1eccc9a47ce9466016
  • check

[2] 클라이언트(kubectl)가 K8S(EKS) API 서버(Endpoint)에 Action 요청 : 일반적인 k8s api 요청 호출 + Bearer Token 포함

# kubectl 실행 시, 출력 로그 확인
# https://18041FBFE166FC9F18E70E63241C796E.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500
kubectl get node -v=10
...
I0401 15:48:58.414931   87026 helper.go:113] "Request Body" body=""
## kubectl은 보안 민감 정보(Authorization 헤더 등)를 일반적인 로그 레벨에서 마스킹(Masking) 처리하여 출력하지 않도록 설계되어 있습니다.
## curl 명령어를 흉내 내어 출력할 때 Authorization 헤더는 고의적으로 제외
I0401 15:48:58.414961   87026 round_trippers.go:527] "Request" curlCommand=<
        curl -v -XGET  -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.35.3 (darwin/arm64) kubernetes/6c1cd99" 'https://18041FBFE166FC9F18E70E63241C796E.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500'

 
# kubectl 대신, 직접 토큰을 사용해서 k8s api 호출 해보기!

# 1. 토큰 확보
TOKEN_DATA=$(aws eks get-token --cluster-name myeks | jq -r '.status.token')
echo $TOKEN_DATA

# 2. curl 호출 : 로그에 찍힌 URL과 헤더에 토큰 추가하여 실행 => 15분 후 토큰 만료되니, 15분 이후에는 토큰 재발급해서 사용 필요!
## Authorization: Bearer 확인!
curl -k -v -XGET \
  -H "Authorization: Bearer $TOKEN_DATA" \
  -H "Accept: application/json" \
  'https://D101CFA79EB3A774D39A52E2425B034F.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500'
...
> Authorization: Bearer k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUE1SUxGMkZKSTNFR0tOR05ZJTJGMjAyNjA0MDElMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDAxVDA4NTYyMFomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPThkZGE5M2Y1MzEyMGM3Y2FjOGU0MWIxY2EzNTliOGZmMWY0MDEyNDMyNTIzNDgyZGE4NzUwZjhlYTI4OTVmNjg
...

curl -k -s -XGET \
  -H "Authorization: Bearer $TOKEN_DATA" \
  -H "Accept: application/json" \
  'https://D101CFA79EB3A774D39A52E2425B034F.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/nodes?limit=500' | jq
  • chcek

[3] k8s(eks) api 는 ‘웹 토큰 인증’ 방식을 통한 인증을 위해서, Token Review 요청 ⇒ AWS 인증 확인 후 응답 시 : 유저, K8S Subject(group) 등

웹훅 인증 전략 webhook authentication strategy 은 bearer tokens을 검증하는 웹훅을 호출합니다. Amazon EKS에서 이러한 베어러 토큰 bearer tokens 은 kubectl 명령을 실행할 때 AWS CLI 또는 aws-iam-authenticator client 에 의해 생성됩니다. 명령을 실행하면 토큰이 kube-apiserver로 전달되어 인증 웹훅으로 전달됩니다. 요청이 잘 구성된 경우, 웹훅은 토큰 본문에 포함된 사전 서명된 URL을 호출합니다. 이 URL은 요청의 서명을 검증하고 사용자 계정, Arn, UserId와 같은 사용자에 대한 정보를 kube-apiserver로 반환합니다.

# tokenreviews api 리소스 확인 
kubectl api-resources | grep authentication
tokenreviews                                   authentication.k8s.io/v1               false        TokenReview

# TokenReview는 사용자에 대한 토큰 인증을 시도(확인)합니다.
kubectl explain tokenreviews.spec
kubectl explain tokenreviews.status
kubectl explain tokenreviews.status.user
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.


# 직접 TokenReview 요청 해보기!
TOKEN_DATA=$(aws eks get-token --cluster-name myeks | jq -r '.status.token')
cat > token-review.yaml << EOF
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
  name: mytoken
spec:
  token: ${TOKEN_DATA}
EOF
cat token-review.yaml

# AWS 인증 확인 후 응답 시 : 유저, K8S Subject(group) 등
## => Amazon EKS 클러스터를 생성할 경우, 클러스터를 생성하는 IAM 보안 주체에게는 Amazon EKS 제어 영역의 클러스터 역할 기반 액세스 제어(RBAC) 구성에 system:masters 권한이 자동으로 부여됩니다. 
## => 이 보안 주체는 표시되는 구성에 나타나지 않음!
## groups=[system:authenticated] => 즉, system:masters 가 생략되어 있다고 보면 됨!
kubectl create -f token-review.yaml -v=9
...
# 가장 마지막 출력 확인해보자
I0331 23:50:19.504430   13262 helper.go:246] "Response Body" body="{\"kind\":\"TokenReview\",\"apiVersion\":\"authentication.k8s.io/v1\",\"metadata\":{\"managedFields\":[{\"manager\":\"kubectl-create\",\"operation\":\"Update\",\"apiVersion\":\"authentication.k8s.io/v1\",\"time\":\"2026-03-31T14:50:19Z\",\"fieldsType\":\"FieldsV1\",\"fieldsV1\":{\"f:spec\":{\"f:token\":{}}}}]},\"spec\":{\"token\":\"k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUE1SUxGMkZKSTNFR0tOR05ZJTJGMjAyNjAzMzElMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzMxVDE0NDgzN1omWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPTYyM2I1MDA0ODA2MWI2YjA1YWExMzdkZTlhNmYxMjJlODJjYWQyYTMzZTM5NmNhYzdlNjU3NjNiNzM5YmU1YTQ\"},\"status\":{\"authenticated\":true,\"user\":{\"username\":\"arn:aws:iam::911283464785:user/admin\",\"uid\":\"aws-iam-authenticator:911283464785:AIDA5ILF2FJIR2CFPVMG7\",\"groups\":[\"system:authenticated\"],\"extra\":{\"accessKeyId\":[\"AKIA5ILF2FJ [truncated 299 chars]"
...
  "status": {
    "authenticated": true,
    "user": {
      "username": "arn:aws:iam::911283464785:user/admin",
      "uid": "aws-iam-authenticator:911283464785:AIDA5ILF2FJIR2CFPVMG7",
      "groups": [
        "system:authenticated"
      ],
      "extra": {
        "accessKeyId": [
          "AKIA5ILF2FJI3EGKNGNY"
        ],
        "arn": [
          "arn:aws:iam::911283464785:user/admin"
        ],
        "canonicalArn": [
          "arn:aws:iam::911283464785:user/admin"
        ],
        "principalId": [
          "AIDA5ILF2FJIR2CFPVMG7"
        ],
        "sessionName": [
          ""
        ],
        "sigs.k8s.io/aws-iam-authenticator/principalId": [
          "AIDA5ILF2FJIR2CFPVMG7"
        ]
      }
    },
    "audiences": [
      "https://kubernetes.default.svc"
    ]
  }
}
tokenreview.authentication.k8s.io/mytoken created
  • check

[4] Server side (aws-iam-authenticator server) 는 AWS STS GetCallerIdentity 호출(제출)을 통해 서명 검증(인증!) 후 사용자 정보 반환

AWS IAM 주체 → K8S Subject 매칭 + 인가! k8s Authz : 방안1(EKS API - Docs) , 방안2(aws-auth ConfigMap is deprecated - Docs)

  • 방안2 확인 : aws-auth ConfigMap is deprecated + K8S RBAC → CR/CRB 관리리소스 필요, 휴먼 에러 발생 가능 - Docs
# 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: |
    - rolearn: arn:aws:iam::911283464785:role/myeks-ng-1
      groups:
      - system:bootstrappers
      - system:nodes
      username: system:node:{{EC2PrivateDNSName}}
#---<아래 생략(추정), ARN은 EKS를 설치한 IAM User , 여기 있었을경우 만약 실수로 삭제 시 복구가 가능했을까?---
  mapUsers: |
    - groups:
      - system:masters
      userarn: arn:aws:iam::111122223333:user/admin
      username: kubernetes-admin

# AWS IAM 주체를 → K8S Subject 매칭 방안2 사용 시 eksctl 명령어를 통한 확인
eksctl get iamidentitymapping --cluster myeks
ARN                                             USERNAME                                GROUPS                           ACCOUNT
arn:aws:iam::911283464785:role/myeks-ng-1       system:node:{{EC2PrivateDNSName}}       system:bootstrappers,system:nodes
  • check

K8S(EKS) API가 TokenReview 응답을 받고 나서, K8S RBAC 인가 확인 후, 허용(Allow)시 K8S Action 실행 후 최종 사용자에게 응답!

[5] 방안1 EKS API - Docs : AWS IAM 주체 → K8S Subject 매칭 + k8s Authz ‘Webhook’ 인가! - SubjectAccessReview
k8s(eks) api 서버 로그 : 인증(authentication-token-webhook), 인가(authorization-webhook) → 즉 AWS측에서 ‘인증/인가’ 가능!

  • Access Entry : AWS IAM 주체 → K8S Subject 매칭(Authorization Mapping) + k8s Authz ‘Webhook’ 인가! ⇒ k8s action 실행 후 리턴!
  • EKS 컨트롤 플레인이 관리하는 Access Entry DB(API)를 조회하여 해당 IAM 주체에 매핑된 Kubernetes Username과 Group 정보를 가져옵니다. (Authorization Mapping)
  • IAM Entity: 인증을 시도하는 AWS IAM User 또는 Role의 ARN입니다.

K8S 대신 AWS 측에서 인가 처리 동작(Webhook, SubjectAccessReviews) 확인

# 현재 Access Entry 에 IAM User admin 
aws eks list-access-entries --cluster-name myeks | jq
{
  "accessEntries": [
    "arn:aws:iam::911283464785:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS",
    "arn:aws:iam::911283464785:role/myeks-ng-1",
    "arn:aws:iam::911283464785:user/admin"
  ]
}

# api 리소스 확인
kubectl api-resources | grep subject   
...
subjectaccessreviews                             authorization.k8s.io/v1           false        SubjectAccessReview

# SubjectAccessReviews는 사용자/그룹이 K8S Action이(인가) 가능한지 확인
kubectl explain subjectaccessreviews.spec
kubectl explain subjectaccessreviews.status
kubectl explain subjectaccessreviews
...
DESCRIPTION:
    SubjectAccessReview checks whether or not a user or group can perform an
    action.


# Shows the subject for the current context with which one authenticates with the cluster
kubectl rbac-tool -h
kubectl rbac-tool whoami
{Username: "arn:aws:iam::911283464785:user/admin",
 UID:      "aws-iam-authenticator:911283464785:AIDA5ILF2FJIR2CFPVMG7",
 Groups:   ["system:authenticated"],     # system:masters 생략!
 Extra:    {accessKeyId:                                   ["AKIA5ILF2FJI3EGKNGNY"],
            arn:                                           ["arn:aws:iam::911283464785:user/admin"],
            canonicalArn:                                  ["arn:aws:iam::911283464785:user/admin"],
            principalId:                                   ["AIDA5ILF2FJIR2CFPVMG7"],
            sessionName:                                   [""],
            sigs.k8s.io/aws-iam-authenticator/principalId: ["AIDA5ILF2FJIR2CFPVMG7"]}}


# 직접 SubjectAccessReviews 요청 확인 해보기
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
cat > sar-request.yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SubjectAccessReview
spec:
  user: "arn:aws:iam::${ACCOUNT_ID}:user/admin" # 확인하고 싶은 IAM ARN 또는 K8s User
  groups:
    - system:masters
  resourceAttributes:
    namespace: "kube-system"
    verb: "get"
    resource: "pods"
EOF
cat sar-request.yaml
kubectl create -f sar-request.yaml -v=8

# AWS 인증 확인 후 응답 시 : 유저, K8S Subject(group) 등
## => Amazon EKS 클러스터를 생성할 경우, 클러스터를 생성하는 IAM 보안 주체에게는 Amazon EKS 제어 영역의 클러스터 역할 기반 액세스 제어(RBAC) 구성에 system:masters 권한이 자동으로 부여됩니다. 
## => 이 보안 주체는 표시되는 구성에 나타나지 않음!
## groups=[system:authenticated] => 즉, system:masters 가 생략되어 있다고 보면 됨!
kubectl create -f token-review.yaml -v=9
...
# 가장 마지막 출력 확인해보자
I0402 00:34:22.205722   93399 helper.go:246] "Response Body" body=<
        {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1","metadata":{"managedFields":[{"manager":"kubectl-create","operation":"Update","apiVersion":"authorization.k8s.io/v1","time":"2026-04-01T15:34:22Z","fieldsType":"FieldsV1","fieldsV1":{"f:spec":{"f:groups":{},"f:resourceAttributes":{".":{},"f:namespace":{},"f:resource":{},"f:verb":{}},"f:user":{}}}}]},"spec":{"resourceAttributes":{"namespace":"kube-system","verb":"get","resource":"pods"},"user":"arn:aws:iam::911283464785:user/admin","groups":["system:masters"]},"status":{"allowed":true}}
...
{
  "kind": "SubjectAccessReview",
  "apiVersion": "authorization.k8s.io/v1",
  ...
  "spec": {
    "resourceAttributes": {
      "namespace": "kube-system",
      "verb": "get",
      "resource": "pods"
    },
    "user": "arn:aws:iam::911283464785:user/admin",
    "groups": [
      "system:masters"
    ]
  },
  "status": {
    "allowed": true
  • check

EKS에서 제공하는 EKA API Access Entry 관리형 정책 확인 - Docs

# 맵핑된 정책 확인 : 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
...
  "associatedAccessPolicies": [
    {
      "policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy",
      "accessScope": {
        "type": "cluster",
...

# 맵핑된 정책 확인 : 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


# EKS에서 제공하는 관리형 정책 확인
aws eks list-access-policies
aws eks list-access-policies --output table
|+--------------------------------------------------------------------------------------+------------------------------------------------+|
||  arn:aws:eks::aws:cluster-access-policy/AmazonAIOpsAssistantPolicy                   |  AmazonAIOpsAssistantPolicy                    ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonARCRegionSwitchScalingPolicy           |  AmazonARCRegionSwitchScalingPolicy            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSACKPolicy                           |  AmazonEKSACKPolicy                            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy                         |  AmazonEKSAdminPolicy                          ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminViewPolicy                     |  AmazonEKSAdminViewPolicy                      ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSArgoCDClusterPolicy                 |  AmazonEKSArgoCDClusterPolicy                  ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSArgoCDPolicy                        |  AmazonEKSArgoCDPolicy                         ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSAutoNodePolicy                      |  AmazonEKSAutoNodePolicy                       ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSBlockStorageClusterPolicy           |  AmazonEKSBlockStorageClusterPolicy            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSBlockStoragePolicy                  |  AmazonEKSBlockStoragePolicy                   ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy                  |  AmazonEKSClusterAdminPolicy                   ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSComputeClusterPolicy                |  AmazonEKSComputeClusterPolicy                 ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSComputePolicy                       |  AmazonEKSComputePolicy                        ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy                          |  AmazonEKSEditPolicy                           ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSEventPolicy                         |  AmazonEKSEventPolicy                          ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSHybridPolicy                        |  AmazonEKSHybridPolicy                         ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSKROPolicy                           |  AmazonEKSKROPolicy                            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSLoadBalancingClusterPolicy          |  AmazonEKSLoadBalancingClusterPolicy           ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSLoadBalancingPolicy                 |  AmazonEKSLoadBalancingPolicy                  ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSNetworkingClusterPolicy             |  AmazonEKSNetworkingClusterPolicy              ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSNetworkingPolicy                    |  AmazonEKSNetworkingPolicy                     ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSSecretAdminPolicy                   |  AmazonEKSSecretAdminPolicy                    ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSSecretReaderPolicy                  |  AmazonEKSSecretReaderPolicy                   ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy                          |  AmazonEKSViewPolicy                           ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonEMRJobPolicy                           |  AmazonEMRJobPolicy                            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodClusterPolicy         |  AmazonSagemakerHyperpodClusterPolicy          ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodControllerPolicy      |  AmazonSagemakerHyperpodControllerPolicy       ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodSpacePolicy           |  AmazonSagemakerHyperpodSpacePolicy            ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodSpaceTemplatePolicy   |  AmazonSagemakerHyperpodSpaceTemplatePolicy    ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodSystemNamespacePolicy |  AmazonSagemakerHyperpodSystemNamespacePolicy  ||
||  arn:aws:eks::aws:cluster-access-policy/AmazonSagemakerHyperpodUserClusterPolicy     |  AmazonSagemakerHyperpodUserClusterPolicy      ||
|+--------------------------------------------------------------------------------------+------------------------------------------------+|
  • check

[6] 방안1 EKS API 을 통한 인증/인가를 마친 후, K8S(EKS) API는 K8S Action 실행 후 클라이언트에 최종 응답!

별도 aws cli 환경에서, 신입 Devops 엔지어를 위한 eks 자격 증명 설정

[사전 준비 1] testuser 사용자 생성

# 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"
  • check

[사전 준비 2] aws-cli 컨테이너 실행 후 aws iam 자격증명 설정 및 확인

# aws-cli 컨테이너 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-------------------------------------------------
# aws cli 명령 시도
aws s3 ls

# 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"

# aws cli 명령 시도
aws s3 ls
  • check

[1] testuser kubeconfig 생성 및 kubectl 사용 확인

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

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

# kubeconfig 확인
cat ~/.kube/config


# kubectl 설치
# https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.35.2/2026-02-27/bin/linux/arm64/kubectl  # macOS
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.35.2/2026-02-27/bin/linux/amd64/kubectl  # windows (WSL2)
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client=true

    
# kubectl 사용 확인 : 실패!
kubectl get node -v6


# rbac-tool 설치 : https://github.com/alcideio/rbac-tool
yum install tar gzip -y
curl https://raw.githubusercontent.com/alcideio/rbac-tool/master/download.sh | bash

# Shows the subject for the current context with which one authenticates with the cluster
./bin/rbac-tool whoami
Error: Failed to create kubernetes client - the server has asked for the client to provide credentials
  • check

[2] 방안1 EKS API 을 통한 Access 설정 : testuser에 AmazonEKSAdminPolicy 정책 부여로 EKS 관리자 수준 권한 설정

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행 -> 혹은 자신의 PC에서 실행해도됨(aws 관리자 수준 자격증명 상태에서)
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# testuser 의 access entry 생성
export CLUSTER_NAME=myeks
export ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
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에 AmazonEKSAdminPolicy 연동
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/AmazonEKSAdminPolicy --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
  • check

[3] 최종 kubectl 사용 확인!

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# kubectl 시도
kubectl get node -v6
kubectl get deploy -A
kubectl auth can-i delete pods --all-namespaces
  • check

EKS에서 제공하는 관리형 정책이 아닌, 직접 만든 커스텀 RBAC을 사용해보자!~~
[0] testuser에 Access Entry 제거

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행 -> 혹은 자신의 PC에서 실행해도됨(aws 관리자 수준 자격증명 상태에서)
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# 기존 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[]

[1] K8S 에 ClusterRole 과 ClusterRoleBinding 생성

# 자신의 PC에서 실행

# ClusterRole 생성
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-viewer-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["list", "get", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-admin-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["*"]
EOF

kubectl get clusterrole | grep ^pod
pod-admin-role                                                         2026-04-01T17:53:14Z
pod-viewer-role                                                        2026-04-01T17:53:14Z


# ClusterRoleBinding 생성
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
kubectl get clusterrolebinding | grep -E 'admin-role|viewer-role'

# 확인
kubectl rbac-tool lookup pod-viewer                      
  SUBJECT    | SUBJECT TYPE | SCOPE       | NAMESPACE | ROLE            | BINDING              
-------------+--------------+-------------+-----------+-----------------+----------------------
  pod-viewer | Group        | ClusterRole |           | pod-viewer-role | viewer-role-binding 

kubectl rbac-tool lookup pod-admin
  SUBJECT   | SUBJECT TYPE | SCOPE       | NAMESPACE | ROLE           | BINDING             
------------+--------------+-------------+-----------+----------------+---------------------
  pod-admin | Group        | ClusterRole |           | pod-admin-role | admin-role-binding  

kubectl rolesum -k Group pod-viewer     
Group: pod-viewer

Policies:
• [CRB] */viewer-role-binding ⟶  [CR] */pod-viewer-role
  Resource  Name  Exclude  Verbs  G L W C U P D DC  
  pods      [*]     [-]     [-]   ✔ ✔ ✔ ✖ ✖ ✖ ✖ ✖   

kubectl rolesum -k Group pod-admin 
Group: pod-admin

Policies:
• [CRB] */admin-role-binding ⟶  [CR] */pod-admin-role
  Resource  Name  Exclude  Verbs  G L W C U P D DC  
  pods      [*]     [-]     [-]   ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔   
  • check

[2] Access Entry 설정 : pod-viewer 그룹

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행 -> 혹은 자신의 PC에서 실행해도됨(aws 관리자 수준 자격증명 상태에서)
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# Access Entry 설정 : 먼저 k8s group 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"
        ],

# Access Entry 확인
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
  • check

[3] kubectl 사용 확인!

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# kubectl 시도
kubectl get node -A
kubectl get pod -A
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i delete pods --all-namespaces

[4] Access Entry 설정 업데이트 : pod-admin그룹

# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# Access Entry 설정 업데이트
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"
    ],
...
  • check

[5] kubectl 사용 확인!


# [사전 준비 2] 에서 컨테이너 sh 진입 상태에서 아래 실행
docker run -it --name aws-cli --entrypoint /bin/sh amazon/aws-cli
-----------------------------------------------------------------

# kubectl 시도
kubectl get node -A
kubectl get pod -A
kubectl auth can-i get pods --all-namespaces
kubectl auth can-i delete pods --all-namespaces
  • check

K8S(EKS) Pod(SA) with IAM Role → AWS 리소스 사용

IRSA 소개 : K8S 에서 발급한 토큰 검증을 위해서, AWS가 ODIC 프로바이더(예. 구글 인증)인 K8S(토큰 발급 주체)를 통해 검증 후, IAM Role Assume 전달

IRSA 동작 과정

AWS SDK는 AWS_ROLE_ARN 및 AWS_WEB_IDENTITY_TOKEN_FILE 이름의 환경변수를 읽어들여 Web Identity 토큰으로 AssumeRoleWithWebIdentify를 호출함으로써 Assume Role을 시도하여 임시 자격 증명을 획득하고, 특정 IAM Role 역할을 사용할 수 있게 됩니다.
이때 Assume Role 동작을 위한 인증은 AWS가 아닌 외부 Web IdP(EKS IdP)에 위임하여 처리합니다.

  • AWS EKS Service Account에 AWS IAM Role 부여 (IRSA)

실습1 : 파드에 서비스 어카운트 없이 생성해보기

# 파드1 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test1
spec:
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      args: ['s3', 'ls']
  restartPolicy: Never
  automountServiceAccountToken: false
  terminationGracePeriodSeconds: 0
EOF

# 확인
kubectl get pod
kubectl describe pod

# 로그 확인
kubectl logs eks-iam-test1

# 파드1 삭제
kubectl delete pod eks-iam-test1
  • check

실습2 : 기본 Kubernetes API 접근용 ServiceAccount 첫번째 토큰 확인 aud : https://kubernetes.default.svc - Docs

# 파드2 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test2
spec:
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

# 확인
kubectl get pod
kubectl describe pod
kubectl get pod eks-iam-test2 -o yaml
...
  volumes:
  - name: kube-api-access-g9shf
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token

kubectl get pod eks-iam-test2 -o yaml | grep serviceAccount
  serviceAccount: default
  serviceAccountName: default
  
kubectl get sa default
kubectl exec -it eks-iam-test2 -- ls -al /var/run/secrets/kubernetes.io/serviceaccount
kubectl exec -it eks-iam-test2 -- ls -al /var/run/secrets/kubernetes.io/serviceaccount/..data
kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ;echo

# aws 서비스 사용 시도
kubectl exec -it eks-iam-test2 -- aws s3 ls

# 서비스 어카운트 토큰 확인
SA_TOKEN=$(kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $SA_TOKEN

# jwt 혹은 아래 JWT 웹 사이트 이용 https://jwt.io/
jwt decode $SA_TOKEN --json --iso8601
...

#헤더
{
  "alg": "RS256",
  "kid": "1559d9b7d1fc97f5da6354aba03386bf67988a3d",
  "typ": "JWT"
}

# 페이로드 확인
# OAuth2에서 쓰이는 aud, exp 속성 확인! > projectedServiceAccountToken 기능으로 토큰에 audience 등 항목을 덧붙힘
# iss : 토큰 발급자(OIDC 제공업체)를 나타냅니다 https://oidc.eks.us-east-1.amazonaws.com/id/80D562ED8026E91294D52E09BEA261D4. 이 OIDC 제공업체 URL은 토큰 검증 과정에서 사용됩니다.
# aud : 토큰의 대상 주소를 나타냅니다 https://kubernetes.default.svc. 이는 Kubernetes API 서버에 접근하는 데 사용되는 클러스터 내부의 주소입니다. 즉, 이 토큰은 API 서버에서는 승인되지만 다른 서비스에서는 거부됩니다.
# exp 와 iat : 이는 토큰의 만료 시간을 나타내며, 기본적으로 시간 제한 토큰을 가능하게 합니다.
{
  "aud": [
    "https://kubernetes.default.svc"  # 해당 주소는 k8s api의 ClusterIP 서비스 주소 도메인명, kubectl get svc kubernetes
  ],
  "exp": 1716619848, # 만료 시간
  "iat": 1685083848, # 발급 시간
  "iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/F6A7523462E8E6CDADEE5D41DF2E71F6", # 토큰 발급자(OIDC 제공업체)
  "jti": "ee823c34-f020-4f77-90f3-61fab4de244a", # 토큰 고유 ID - replay attack 방지 / 추적용
  "kubernetes.io": {
    "namespace": "default",
    "node": {
      "name": "ip-192-168-1-70.ap-northeast-2.compute.internal",
      "uid": "f4fabf42-4a9c-43f0-8a1e-edeb2a8fbb42"
    },
    "pod": {
      "name": "eks-iam-test2",
      "uid": "10dcccc8-a16c-4fc7-9663-13c9448e107a"
    },
    "serviceaccount": {
      "name": "default",
      "uid": "acb6c60d-0c5f-4583-b83b-1b629b0bdd87"
    },
    "warnafter": 1685087455 # Kubernetes 내부 로직에서 사용 - 이 시간 이후에는 토큰 갱신 권장
  },
  "nbf": 1685083848, # 이 사간 이후 유효
  "sub": "system:serviceaccount:default:default" # 이 토큰의 주인. default 네임스페이스의 default 서비스 계정.
}

# 파드2 삭제
kubectl delete pod eks-iam-test2
  • check

실습3 : IRSA 설정 및 SA 두번째 토큰 확인 aud : sts.amazonaws.com - Blog , Github

  • 목표 1 : AWS LBC Helm 설치 시, IRSA로 LBC 파드에만 필요한 권한(ALB/NLB 제어 등)을 부여해보자!

IRSA 설정 - Workshop , Docs

# 클러스터에 기존 IAM OIDC 공급자가 있는지 확인합니다. 클러스터의 OIDC 공급자 ID를 검색하여 변수에 저장합니다.
oidc_id=$(aws eks describe-cluster --name myeks --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
echo $oidc_id
032357E88E266F4AE7C2E8CF6F5EFEB0

# 클러스터 ID를 가진 IAM OIDC 공급자가 계정에 이미 있는지 확인합니다.
# aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
aws iam list-open-id-connect-providers | grep $oidc_id | cut -d "/" -f4
032357E88E266F4AE7C2E8CF6F5EFEB0
 
IDP=$(aws eks describe-cluster --name myeks --query cluster.identity.oidc.issuer --output text)
curl -s $IDP/.well-known/openid-configuration | jq -r '.'
curl -s $IDP/keys | jq -r '.'

curl -s https://oidc.eks.ap-northeast-2.amazonaws.com/id/D101CFA79EB3A774D39A52E2425B034F/.well-known/openid-configuration | jq .

# Discovery 엔드포인트 호출 (.well-known) : OIDC issuer 주소 뒤에 /.well-known/openid-configuration을 붙이면 됩
curl -s https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0/.well-known/openid-configuration | jq .
{
  "issuer": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0",
  "jwks_uri": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0/keys",
  "authorization_endpoint": "urn:kubernetes:programmatic_authorization",
  "response_types_supported": [
    "id_token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "claims_supported": [
    "sub",
    "iss"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ]
}

# JWKS(JSON Web Key Set) 호출 : 위에서 찾은 jwks_uri (보통 끝에 /keys가 붙음)로 다시 요청을 보냅니다.
## EKS가 발행한 JWT 토큰을 검증할 때 사용하는 공개키 세트
curl -s https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0/keys | jq .
{
  "keys": [
    {
      "kty": "RSA",
      "kid": "1559d9b7d1fc97f5da6354aba03386bf67988a3d",
      "use": "sig",
      "alg": "RS256",
      "n": "7FP6H4lhMYbuTq8orkcDw5zJcbYHhP4tD0KhiR3Tk8nLklaRsWZLXaqcbouFkDDCKV07mU6o3Dv-3HZSst9clyuc2nHzriIECUiLN_z-iPDaMgA5UyO78qS-OErXz_Nz3FwQNrjdrkQ54a0HBOwAadewOigYENR6paGjg2Nu7XEmWSQA5lT5cvXLHwm4NOKXDVafT7gvLL2oGKsQreTxVa7XI47XQ5Se5Up8O0FqWd5WvQ1Lia5d2C-BNxXCjDsickX--ZNm3qPgIY5M4Ao98hbfoIA5PCAMazTq-jGjWCjey17wlKRJfmsbHjXOTkcP6DILHCbfHHhCf2m8BsaWhw",
      "e": "AQAB"
    }
  ]
}

# 왜 이 과정이 중요한가요? (IRSA 검증 원리)
## AWS STS나 다른 검증 주체는 여러분이 뽑은 JWT 토큰의 서명이 유효한지 확인하기 위해 위 과정을 거칩니다.
## 토큰 수신: Pod에서 보낸 JWT 토큰을 받음.
## Issuer 확인: 토큰 내부의 iss 필드를 보고 위 URL로 접속.
## 공개키 획득: /keys 경로에서 현재 유효한 공개키(JWKS)를 가져옴.
## 서명 검증: 가져온 공개키와 토큰의 서명(Signature)을 대조하여 변조 여부를 확인.
  • check

Kubernetes 서비스 계정이 IAM 역할을 통해 사용할 IAM Policy 생성 - Docs

# IAM Policy json 파일 다운로드 : Download an IAM policy for the AWS Load Balancer Controller that allows it to make calls to AWS APIs on your behalf.
curl -o aws_lb_controller_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json
cat aws_lb_controller_policy.json | jq

# AWSLoadBalancerControllerIAMPolicy 생성 : Create an IAM policy using the policy downloaded in the previous step.
aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://aws_lb_controller_policy.json

# 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy | jq
  • check

Pod가 Kubernetes 서비스 계정을 사용하도록 구성합니다 : IAM Role 생성, K8S SA 생성, K8S SA Annonation 추가

# IRSA 생성 : cloudforamtion 를 통해 IAM Role 생성
CLUSTER_NAME=myeks
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller

eksctl create iamserviceaccount \
  --cluster=$CLUSTER_NAME \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --attach-policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \
  --override-existing-serviceaccounts \
  --approve

# 확인 : 아래 출력되는 Role ARN을 관리콘솔에서 확인!
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
NAMESPACE       NAME                            ROLE ARN
kube-system     aws-load-balancer-controller    arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-kube-sys-Role1-n7mN9x019mGE

# k8s 에 SA 확인
# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-kube-sys-Role1-cNSJN97wewS7
  ...
  • check

AWS LBC 설치 : 현재 Node IAM Role에 ELB 권한 없는 상태 - Link , Docs , values

# Helm Chart Repository 추가
helm repo add eks https://aws.github.io/eks-charts
helm repo update

# Helm Chart - AWS Load Balancer Controller 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --version 3.1.0 \
  --set clusterName=$CLUSTER_NAME \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set serviceAccount.create=false \
  --set enableCertManager=true

# 확인
helm list -n kube-system
kubectl get pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
kubectl logs -n kube-system deployment/aws-load-balancer-controller -f

# 인증서 관련 정보 확인
## LBC는 단순히 AWS ALB/NLB를 만들기만 하는 것이 아니라, 사용자가 작성한 Ingress나 Service 설정이 올바른지 검토하고 수정하는 역할도 수행
## 이를 위해 API 서버는 LBC의 9443 포트로 HTTPS 요청을 보내는데, 이 통신을 위해 aws-load-balancer-tls 인증서가 필요함. 
## 이때 해당 인증서의 만료 전 Cert-manager 이 자동 갱신 처리해줌
## 발급된 인증서 데이터를 aws-load-balancer-tls라는 이름의 Secret에 저장
kubectl get certificaterequests,issuers,certificates -n kube-system
kubectl get secret -n kube-system
kubectl get secret aws-load-balancer-tls -n kube-system -o yaml

# cert-manager 류의 인증서 자동 갱신 미사용 시?
## LBC의 웹훅 인증서는 보통 유효기간이 짧습니다. cert-manager가 없으면 인증서가 만료되는 순간 ,
# kubectl apply 명령이 모두 에러(Internal error: failed calling webhook...)가 나며 클러스터 관리가 불가능해집니다.

# AWS Load Balancer Controller 확인
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml
kubectl rolesum -n kube-system aws-load-balancer-controller
kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller | grep 'Service Account'
  Service Account:  aws-load-balancer-controller

상세 확인 : Pod Spec 주입 확인, aud 가 aws sts 확인!

# 아래 ENV 와 두번쨰 볼륨은 어떻게 pod spec 에 설정이 주입되었을까요?
k get deploy -n kube-system aws-load-balancer-controller -o yaml # 비교해보자!
kubectl describe pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
...
    Environment:
      AWS_STS_REGIONAL_ENDPOINTS:   regional
      AWS_DEFAULT_REGION:           ap-northeast-2
      AWS_REGION:                   ap-northeast-2
      AWS_ROLE_ARN:                 arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-kube-sys-Role1-OUFLQbVkFHFn
      AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    Mounts:
      /tmp/k8s-webhook-server/serving-certs from cert (ro)
      /var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-t6zct (ro)
...
Volumes:
  aws-iam-token:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  86400
  cert:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  aws-load-balancer-tls
    Optional:    false
  kube-api-access-t6zct:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true

# aud 가 k8s api 가 아닌 AWS STS 이다! 즉, 해당 토큰 검증은 AWS STS 요청!
kubectl get pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller -o yaml
...
      env:
      - name: AWS_STS_REGIONAL_ENDPOINTS
        value: regional
      - name: AWS_DEFAULT_REGION
        value: ap-northeast-2
      - name: AWS_REGION
        value: ap-northeast-2
      - name: AWS_ROLE_ARN
        value: arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-kube-sys-Role1-OUFLQbVkFHFn
      - name: AWS_WEB_IDENTITY_TOKEN_FILE
        value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
     ...
     volumeMounts:
      - mountPath: /tmp/k8s-webhook-server/serving-certs
        name: cert
        readOnly: true
      - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
        name: kube-api-access-t6zct
        readOnly: true
      - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
        name: aws-iam-token
        readOnly: true
...
    volumes:
    - name: aws-iam-token
      projected:
        defaultMode: 420
        sources:
        - serviceAccountToken:
            audience: sts.amazonaws.com
            expirationSeconds: 86400
            path: token


# 해당 SA를 사용하는 파드가 생성 시 mutatingwebhook으로 Env,Volume 주입!
kubectl get MutatingWebhookConfiguration
NAME                            WEBHOOKS   AGE
aws-load-balancer-webhook       6          19m
cert-manager-webhook            1          23m
pod-identity-webhook            1          4h38m
vpc-resource-mutating-webhook   1          4h38m

# pod-identity-webhook 확인
kubectl describe MutatingWebhookConfiguration pod-identity-webhook 
kubectl get MutatingWebhookConfiguration pod-identity-webhook -o yaml
...
 name: iam-for-pods.amazonaws.com
 
# iam-for-pods.amazonaws.com은 AWS EKS에서 Pod Identity Webhook의 Mutating Webhook으로, 다음과 같은 작업을 수행합니다:
# Pod 생성 시 호출되어 ServiceAccount의 IAM 역할 정보를 확인.
# Pod에 환경 변수(AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE)와 토큰 볼륨을 주입.
# Pod이 AWS 리소스에 안전하고 세밀하게 접근할 수 있도록 인증 메커니즘 제공.
  • check

(AWS LBC 동작 확인) kube-ops-view 배포 + ALB Ingress(MyDomain, HTTPS → HTTP)

# kube-ops-view : NodePort 나 LoadBalancer Type 필요 없음!
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=ClusterIP --set env.TZ="Asia/Seoul" --namespace kube-system

# 확인
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view


# 사용 리전의 인증서 ARN 변수 지정 : 정상 상태 확인(만료 상태면 에러 발생!)
CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
echo $CERT_ARN

# 자신의 공인 도메인 변수 지정
MyDomain=<자신의 공인 도메인>
echo $MyDomain

MyDomain=gasida.link
echo $MyDomain


# kubeopsview 용 Ingress 설정 : group 설정으로 1대의 ALB를 여러개의 ingress 에서 공용 사용
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
    alb.ingress.kubernetes.io/group.name: study
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/success-codes: 200-399
    alb.ingress.kubernetes.io/target-type: ip
  labels:
    app.kubernetes.io/name: kubeopsview
  name: kubeopsview
  namespace: kube-system
spec:
  ingressClassName: alb
  rules:
  - host: kubeopsview.$MyDomain
    http:
      paths:
      - backend:
          service:
            name: kube-ops-view
            port:
              number: 8080
        path: /
        pathType: Prefix
EOF

# service, ep, ingress 확인
kubectl get ingress,svc,ep -n kube-system

# Kube Ops View 접속 정보 확인 
echo -e "Kube Ops View URL = https://kubeopsview.$MyDomain/#scale=1.5"
open "https://kubeopsview.$MyDomain/#scale=1.5" # macOS


# (참고) 삭제 시
kubectl delete ingress -n kube-system kubeopsview

목표 2 : AWS S3 읽기 전용 권한이 필요한 파드에 IRSA 설정

# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account
eksctl create iamserviceaccount \
  --name my-sa \
  --namespace default \
  --cluster $CLUSTER_NAME \
  --approve \
  --role-name eksctl-myeks-pod-irsa-s3-readonly-role \
  --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3ReadOnlyAccess`].Arn' --output text)

# 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get sa
kubectl describe sa my-sa
...
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::911283464785:role/eksctl-myeks-pod-irsa-s3-readonly-role
...

# 파드 3번 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test3
spec:
  serviceAccountName: my-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

# Pod Identity Webhook은 mutating webhook을 통해 아래 Env 내용과 1개의 볼륨을 추가함
kubectl get pod eks-iam-test3
kubectl get pod eks-iam-test3 -o yaml
...
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::911283464785:role/eksctl-myeks-pod-irsa-s3-readonly-role
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
...
    volumeMounts: 
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  ...
  volumes: 
  - name: aws-iam-token
    projected: 
      sources: 
      - serviceAccountToken: 
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
...

kubectl exec -it eks-iam-test3 -- ls /var/run/secrets/eks.amazonaws.com/serviceaccount
token

kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token ; echo
...

# 서비스 어카운트 두 번째 토큰 확인
SA_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
echo $SA_TOKEN

# jwt 혹은 아래 JWT 웹 사이트 이용 https://jwt.io/
jwt decode $SA_TOKEN --json --iso8601
...

#헤더
{
  "alg": "RS256",
  "kid": "1559d9b7d1fc97f5da6354aba03386bf67988a3d",
  "typ": "JWT"
}

# 페이로드 확인 : 해당 토큰은 “EKS Pod가 AWS IAM Role을 Assume하기 위한 IRSA 전용 JWT”
{
  "aud": [
    "sts.amazonaws.com"  # AWS STS 전용, 즉 IRSA 토큰
  ],
  "exp": 1775208011,
  "iat": 1775121611,
  "iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0", # 이 토큰을 발급한 주체 = EKS OIDC Provider
  "jti": "3c491844-9bb0-45a3-87f7-91027503f233",
  "kubernetes.io": {
    "namespace": "default",
    "node": {
      "name": "ip-192-168-12-7.ap-northeast-2.compute.internal",
      "uid": "f42ea459-d9d0-45ea-b891-e16b79903cdd"
    },
    "pod": {
      "name": "eks-iam-test3",
      "uid": "fa9be901-b9e9-4bbd-9f89-4ca876ef2315"
    },
    "serviceaccount": {
      "name": "my-sa",
      "uid": "491bbb33-01ef-4646-b184-97e32e9519ae"
    }
  },
  "nbf": 1775121611,
  "sub": "system:serviceaccount:default:my-sa"
}


# 파드에서 aws cli 사용 확인
kubectl exec -it eks-iam-test3 -- aws sts get-caller-identity --query Arn
"arn:aws:sts::911283464785:assumed-role/eksctl-myeks-pod-irsa-s3-readonly-role/botocore-session-1775122119"

# 되는 것고 안되는 것은 왜그런가?
kubectl exec -it eks-iam-test3 -- aws s3 ls
kubectl exec -it eks-iam-test3 -- aws ec2 describe-instances --region ap-northeast-2
kubectl exec -it eks-iam-test3 -- aws ec2 describe-vpcs --region ap-northeast-2
  • check

목표 2 실습 후 관련 리소스 삭제

kubectl delete pod eks-iam-test3
eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --name my-sa --namespace default
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get sa

EKS Pod Identity 소개 - Docs



pod-identity-agent 설치 확인 : 노드 네트워크 정보 확인

# 확인
eksctl get addon --cluster $CLUSTER_NAME
kubectl -n kube-system get daemonset eks-pod-identity-agent
kubectl -n kube-system get pods -l app.kubernetes.io/name=eks-pod-identity-agent
kubectl get ds -n kube-system eks-pod-identity-agent -o yaml
...
      containers: 
      - args: 
        - --port
        - "80"
        - --cluster-name
        - myeks
        - --probe-port
        - "2703"
        command: 
        - /go-runner
        - /eks-pod-identity-agent
        - server
      ....
      ports: 
        - containerPort: 80
          name: proxy
          protocol: TCP
        - containerPort: 2703
          name: probes-port
          protocol: TCP
      ...
        securityContext: 
          capabilities: 
            add: 
            - CAP_NET_BIND_SERVICE
      ...
      hostNetwork: true
...

# 네트워크 정보 확인 : SSM 을 통해 노드 접속 후 아래 확인
## EKS Pod Identity Agent uses the hostNetwork of the node and it uses port 80 and port 2703 on a link-local address on the node. 
## This address is 169.254.170.23 for IPv4 and [fd00:ec2::23] for IPv6 clusters.
sudo ss -tnlp | grep eks-pod-identit
LISTEN 0      4096   169.254.170.23:80         0.0.0.0:*    users:(("eks-pod-identit",pid=4446,fd=6))
LISTEN 0      4096        127.0.0.1:2703       0.0.0.0:*    users:(("eks-pod-identit",pid=4446,fd=8))
LISTEN 0      4096   [fd00:ec2::23]:80            [::]:*    users:(("eks-pod-identit",pid=4446,fd=3))
LISTEN 0      4096                *:2705             *:*    users:(("eks-pod-identit",pid=4446,fd=7))

sudo ip -c route
sudo ip -c -br -4 addr
sudo ip -c addr
...
6: pod-id-link0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether e2:0e:05:d1:1f:06 brd ff:ff:ff:ff:ff:ff
    inet 169.254.170.23/32 scope global pod-id-link0
       valid_lft forever preferred_lft forever
...
  • check

eksctl 로 podidentityassociation 설정 : IAM Role 생성, K8S SA 생성

# eksctl 로 podidentityassociation 설정 : AWS CloudFormation 확인
eksctl create podidentityassociation \
--cluster $CLUSTER_NAME \
--namespace default \
--create-service-account \
--service-account-name s3-sa \
--role-name s3-eks-pod-identity-role \
--permission-policy-arns arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--region ap-northeast-2

# 확인
kubectl get sa
kubectl get sa s3-sa -oyaml
eksctl get podidentityassociation --cluster $CLUSTER_NAME
ASSOCIATION ARN											                                                      NAMESPACE	SERVICE ACCOUNT NAME	IAM ROLE ARN
arn:aws:eks:ap-northeast-2:911283464785:podidentityassociation/myeks/a-blaanudo8dc1dbddw	default		s3-sa			            arn:aws:iam::911283464785:role/s3-eks-pod-identity-role

aws eks list-pod-identity-associations --cluster-name $CLUSTER_NAME | jq
{
  "associations": [
    {
      "clusterName": "myeks",
      "namespace": "default",
      "serviceAccount": "s3-sa",
      "associationArn": "arn:aws:eks:ap-northeast-2:911283464785:podidentityassociation/myeks/a-pm07a3bg79bqa3p24",
      "associationId": "a-pm07a3bg79bqa3p24"
    }
  ]
}

# IAM Role 확인 : ABAC 지원을 위해 sts:Tagsession 추가
aws iam get-role --query 'Role.AssumeRolePolicyDocument' --role-name s3-eks-pod-identity-role | jq .
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "pods.eks.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole",
        "sts:TagSession"
      ]
    }
  ]
}
  • check

테스트용 파드 생성 및 AWS 사용 확인 : AssumeRoleForPodIdentity - Link

# 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-pod-identity
spec:
  serviceAccountName: s3-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

# 확인
## Amazon EKS가 EKS Pod Identity 연결이 있는 서비스 계정을 사용하는 새 Pod를 시작하면 EKS Pod Identity 웹훅이 실행됩니다
## 두 개의 환경 변수를 추가하여 pod 사양을 변경 합니다 : AWS_CONTAINER_CREDENTIALS_FULL_URI , AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE
kubectl get pod eks-pod-identity -o yaml
kubectl exec -it eks-pod-identity -- aws sts get-caller-identity --query Arn
kubectl exec -it eks-pod-identity -- aws s3 ls
kubectl exec -it eks-pod-identity -- env | grep AWS
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE=/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token
AWS_STS_REGIONAL_ENDPOINTS=regional
AWS_DEFAULT_REGION=ap-northeast-2
AWS_REGION=ap-northeast-2
AWS_CONTAINER_CREDENTIALS_FULL_URI=http://169.254.170.23/v1/credentials

# 토큰 정보 확인
kubectl exec -it eks-pod-identity -- ls /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/
kubectl exec -it eks-pod-identity -- cat /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token

# https://www.jwt.io/
## iss : 토큰 발급자(OIDC 제공업체)를 나타냅니다 https://oidc.eks.us-west-2.amazonaws.com/id/8BA4A70AA33A68D27898EB4903D8A6E7. 이 OIDC 제공업체 URL은 토큰 검증 과정에서 사용됩니다.
## aud : 이는 토큰의 수신자를 나타냅니다 pods.eks.amazonaws.com. 즉, EKS Pod Identity Service, 다시 말해 EKS Auth 서비스에서만 토큰이 허용되고 다른 서비스에서는 거부됩니다.
## exp 와 iat : 이는 토큰의 만료 시간을 나타내며, 기본적으로 시간 제한 토큰을 가능하게 합니다.
## kubernetes.io : 이 토큰은 네임스페이스 내의 app1 서비스 계정을 가진 특정 파드에 바인딩되어 있음을 나타냅니다 . 즉, 동일한 서비스 토큰과 동일한 네임스페이스를 가진 다른 파드에서도 이 토큰을 사용할 수 없습니다.sa1ns-a
{
  "aud": [
    "pods.eks.amazonaws.com"
  ],
  "exp": 1775206063,
  "iat": 1775124814,
  "iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/032357E88E266F4AE7C2E8CF6F5EFEB0",
  "jti": "f68ab71b-6360-459e-b20a-7277000ff0da",
  "kubernetes.io": {
    "namespace": "default",
    "node": {
      "name": "ip-192-168-12-7.ap-northeast-2.compute.internal",
      "uid": "f42ea459-d9d0-45ea-b891-e16b79903cdd"
    },
    "pod": {
      "name": "eks-pod-identity",
      "uid": "c15f3022-1f8c-4748-87e1-51532d4da001"
    },
    "serviceaccount": {
      "name": "s3-sa",
      "uid": "a5ae3504-7237-461c-9027-3eb58288e1b9"
    }
  },
  "nbf": 1775124814,
  "sub": "system:serviceaccount:default:s3-sa"
}
  • check

실습 후 관련 리소스 삭제

eksctl delete podidentityassociation --cluster $CLUSTER_NAME --namespace default --service-account-name s3-sa
kubectl delete pod eks-pod-identity
kubectl delete sa s3-sa
profile
클라우드엔지니어

0개의 댓글