본문 바로가기

DevOps

[AWS EKS] EKS 중요한 3가지 특징

CloudNet@팀의 EKS 스터디 AEWS 2기에 작성된 자료를 토대로 작성합니다.

 

EKS 스터디를 진행하기 이전에 먼저 Native K8s와 EKS의 차이점에 대해서 알아보도록 하겠다. 여러가지 차이점이 있겠지만 이번 포스팅에서는 아래 3가지에 초점을 맞춰서 작성해보도록 한다.

 

  • 컨트롤 플레인을 AWS가 관리하는점 
  • VPC CNI를 사용하는점
  • AWS IAM을 통한 IRSA 인증/인가 방식을 사용한다는 점 

 

✅   Amazon Managed 라는 의미는 무엇을 뜻할까?

우선 kubernetes는 기능에 의해서 두가지로 나뉜다.

 

  • 컨트롤 플레인 
    • ETCD
    • API server
    • 컨트롤러, 스케쥴러
  • 데이터 플레인
    • EKS owned ENI
    • 노드 그룹
    • kubelet
    • kube-proxy

✅  Control 플레인

  • 쿠버네티스를 제어 하기 위한 컴포넌트
  • AWS가 관리한다 
  • 고가용성을 고려한 설계가 되어있다. ( ELB, NLB, AZ, AutoScalingGroup )
  • API 서버, 컨트롤러, 스케쥴러, ETCD 등의 컴포넌트가 있다.

생성되는 VPC는 AWS에서 관리하는 Account가 관리하는 VPC 입니다.

 

  • 가용성 보장을 위해 가용영역을 나누고 etcd만 별개의 인스턴스로 분리하여 구성합니다.
  • 오토스케일링 그룹으로 각 컴포넌트들을 묶어 다수의 자원들이 안정적으로 유지됩니다.
  • 또한 각 가용영역 별로 트래픽 분산을 하는 환경을 구성하기 위해 Amazon ELB와 Amazon NLB를 사용합니다.

✅  Data 플레인

  • 워커노드를 구성하기 위한 데이터 플레인 컴포넌트
  • 사용자 VPC에 생성됨 ( 사용자 어카운트에 배치 되기 때문에 사용자가 직접적으로 관리 및 운영)
  • POD, kubelet , Kube-proxy , Container-Runtime 등 
  • 노드 구성 방식들이 다양함 
    • 관리형
    • 자체형 : 사용자 정의 AMI를 사용해서 구성 , 유지관리 및 버전관리를 직접 수행
    • AWS Fargate : 컨테이너 형태의 구조가 아닌 마이크로 VM 형태의 가상머신으로 이루어짐
  • EKS Owned ENI 
    • 해당 네트워크 인터페이스는 소유자와 대상자가 서로 다른 어카운트로 이루어짐
    • == 크로스 어카운트 ENI
    • 해당 인터페이스를 통해 데이터 플레인과 컨트롤 플레인이 통신

 

✅   Amazon VPC CNI 소개

 

  •   K8s에서는 pod간의 통신을 확장하는 규약을 CNI(Container Network Interface)로 정의합니다.
  •   EKS는 여러가지 이유로  AWS VPC CNI를 전용으로 사용합니다.
  •  Overlay 네트워크와 Underlay 네트워크의 구성이 달라 관리가 어려운 일반적인 k8s 환경과 달리 관리가 수월합니다.
  • VPC가 제공하는 VPC Flow log나 라우팅 정책, 보안 그룹 등에 대한 기능도 함께 사용 가능합니다

 

일반적인 바닐라 쿠버네티스
노드의 ip 대역은 10.20.2.0/24 대역이고, POD의 대역은 10.233.x.x 대역임을 확인할수 있습니다.

EKS는 Node와 Pod가 동일한 네트워크를 가집니다.
노드의 대역과 POD의 대역이 일치함을 확인 할수 있음.

 

  • 그렇다면? POD가 실제적인 인터페이스를 가지고 있는것인가? 
    • 아뇨 그렇지는 않습니다. 하나의 인터페이스에 SecondaryIP를 보조 아이피로 여러개 가지고 있는것이죠

 


✅ 일반적인 k8s는 Calico와 같은 CNI를 사용하며 오버레이 네트워크를 사용함
✅ EKS는 VPC CNI를 사용하며 오버레이 네트워크가 아닌 노드와 동일 대역으로 직접 통신함

VPC CNI 장점: 컴퓨팅 리소스의 사용이 줄고, 네트워크의 지연이 감소하며, 높은 대역폭을 제공할 수 있습니다.

 

✅   노드당 몇개의 POD를 배포할수 있을까? 

✔️  기본적으로 노드그룹에 인스턴스 타입에 따라 노드당 배포할수 있는 IP가 정해진다고 보면 된다.

✔️ EC2 인스턴스별로 최대 ENI 수량이 정해져 있으며, ENI별로는 최대 IP 수량이 정해져 있기 때문에, 제한되는것임


예를 들어 m5.large 정도의 인스턴스를 사용한다면 ENI 당 10개의 Pod를 배포할수 있고
m5.large EC2인스턴스는 3개의 ENI를 붙일수 있으니 30개가 되겠다. 그리고 노드의 Primary IP와 AWS CNI(aws-node) Kube-proxy등 반드시 필요한 아이피를 제외하여 사용자가 서비스로 사용할수 있는 POD는 27개다.

 

✔️  IPv4 Prefix 위임과 같은 방법도 있음

Prefix 기능 은 작년 7월 발표된 기능으로 Nitro 인스턴스에서만 확장이 가능한 방법입니다.

✔️  서브넷 크기를 크게 잡자 처음부터.. 

  •  EC2 Node가 포함된 subnet의 크기가 작다면, 역시 IP 할당이 원할하지 않을 것이기 때문
  • 24bit subnet 보다는 더 많은 IP를 사용할 수 있는 22bit subnet 등으로 올려서 사용하는 것이 좋습니다. 

✅   POD간 내부 통신

✔️  다른 워커노드에 통신하는 것을 보기 위해서 다음과 같이 netshoot을 배포하여  tcpdump로 패킷을 잡아 분석해보자.

  • netshoot pod는 통신 테스트 용도로 배포한다.
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
    app: pod
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
  labels:
    app: pod
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0

 

✔️  다른 워커노드에 통신하는 것을 다음 그림을 통해 step by step으로 이해해 보자.

  • pod 1에 접속해서 그림을 이해해보자.
$ k exec -it pod-1 /bin/sh
 
$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

$ arp -n
? (169.254.1.1) at ca:ab:00:c7:b4:12 [ether] PERM on eth0


$ ping 192.168.3.197

64 bytes from 192.168.3.197: icmp_seq=1 ttl=125 time=1.33 ms
64 bytes from 192.168.3.197: icmp_seq=2 ttl=125 time=1.06 ms
64 bytes from 192.168.3.197: icmp_seq=3 ttl=125 time=1.11 ms


$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

$ arp -n
? (192.168.1.203) at ca:ab:00:c7:b4:12 [ether]  on eth0
? (169.254.1.1) at ca:ab:00:c7:b4:12 [ether] PERM on eth0
  • pod 안에는 default gateway말고는 아무런 라우팅 정보가 없다.
  • 첫 통신 전에는 arp table에도 default gateway의 MAC정보 이외에는 아무런 정보가 없다.
  • 즉 다시말하면, 아직 본인이 어떤 pod 나 또는 어떤 인터페이스와 통신할지 모르더라도 default gateway로 무조건 요청을 보낸다는의미이다.
  • 하지만 통신 하고 난뒤에는 arp table에는 pod1이 위치한 노드 node1의 eni 인터페이스의 mac주소가 학습되었다.
  • 물론 해당 인터페이스는 가상의 인터페이스 (veth-1) 이며 User space가 아닌 커널 space에 존재하며 ip-link 로 연결되어 있다.
  • next hop은 해당 노드의 eth0 인터페이스임

 

✔️  Pod는 노드의  가상 인터페이스의 mac주소만 가지고 어떻게 통신을 하지?

 

  • 인터페이스 없이 어떻게 통신하지? (arp-proxy를 통한 arp 퍼블리싱)
  • ARP Proxy라는 기능은 라우터 자신이 알고있는 대역에 대한 ARP라면 응답으로 라우터 자신의 MAC 주소를 알려준다. 또한 목적지 대상은 라우터가 받은 패킷을 받는다.
  • 여기서 라우터는 가상 인터페이스이며, 통신하고자 하는 목적지는 노드의 인터페이스이기 때문에, 다음과 같은 통신이 인터페이스 없이 arp 퍼블리싱을 통해 동작한다.
$ arp -n
? (192.168.1.203) at ca:ab:00:c7:b4:12 [ether]  on eth0
? (169.254.1.1) at ca:ab:00:c7:b4:12 [ether] PERM on eth0


192.168.1.203은 pod1이 위치한 node1의 IP주소이다. 하지만 ARP-proxy 기능이 동작했기 때문에
라우터가 자신의 MAC 주소를 적어놨다.

 


 

✅   EKS의 인증,인가 

EKS의 인증과 인가는 어떻게 이루어져 있을까? 

 

☑️ 인증  - AWS IAM을 통해서 지원

☑️ 인가  - Kubernetes RBAC 기능을 통해서 지원

 

kubectl 인증 과정 뜯어보기

 

☑️ kubectl 명령어 실행 

- kubeconfig 확인 해볼것

- aws eks get-token → EKS Service endpoint(STS)에 토큰 요청 ⇒ 응답값 token과 유효기간 포함

# kubeconfig 확인해보면 다음과 같은 명령어가 실행되는것을 알수 있음
args:
      - eks
      - get-token
      - --output
      - json
      - --cluster-name
      - myeks
      - --region
      - ap-northeast-2
      
      
$ aws eks get-token --cluster-name $CLUSTER_NAME | jq

{
  "kind": "ExecCredential",
  "apiVersion": "client.authentication.k8s.io/v1beta1",
  "spec": {},
  "status": {
    "expirationTimestamp": "2024-02-22T02:45:40Z",
    "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFXWklZNVVJRVdUNlhXQ1hMJTJGMjAyNDAyMjIlMkZhcC1ub3J0aGVhc3QtMiUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMjIyVDAyMzE0MFomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPWZhNGJlMTgwODhjNWU3ZjA0M2I3MzE1YTI0NTE5NjZmNzE4MjNlMTQzMjQ3YWE2MDlhZmJiOWUwNDVlNGRiZmE"
  }
}

# 받은 토큰을 decoding 해보자.

 

☑️ pre-signed URL

- kubectl의 Go 라이브러리는 위의 Pre-signed URL을 Bearer Token으로  EKS API Cluster Endpoint로 요청을 보냄

- 받은 토큰은 base64로 디코딩 되어있는 STS의 getCallerIdentity pre-signed URL

Bearer type 경우, 서버에서 지정한 어떠한 문자열도 입력할 수 있습니다. 하지만 굉장히 허술한 느낌을 받습니다. 이를 보완하고자 쿠버네티스에서 Bearer 토큰을 전송할 때 주로 JWT (JSON Web Token) 토큰을 사용합니다.

JWT는 X.509 Certificate와 마찬가지로 private key를 이용하여 토큰을 서명하고 public key를 이용하여 서명된 메세지를 검증합니다. 이러한 메커니즘을 통해 해당 토큰이 쿠버네티스를 통해 생성된 valid한 토큰임을 인증할 수 있습니다.

X.509 Certificate의 lightweight JSON 버전이라고 생각하면 편리합니다.

 

☑️ Token Review를 요청

- 주체: AWS IAM Authenticator 서버

- EKS API는 Token Review 를 aws-IAM-authenticator에 요청

- pre-signed-URL을 통해서 AWS IAM에 sts GetCallerIdentity를 보냄

- 사용자 검증을 AWS IAM으로부터 받음

- User ID,User, Role에 대한 ARN 반환

 

 

☑️ AWS-auth 컨피그맵

- 주체: AWS-auth Configmap

- IAM의 User ID, Role의 정보와 매핑되는 Kubernetes RBAC 정보 확인

 

☑️ Token Review에 응답 

- username과 group을 이용하여 RBAC 기반의 인가

- Allow 할것인지 Deny 할것인지 ?


✅   IRSA ( IAM Role for Service Account )

앞서 사용자가 Kubectl 명령어를 사용할때 인증과 인가를 받는 과정을 다뤘다면 
이번에는 Pod가 사용하는 Service Account의 인증과 인가에 대해서 그 과정을 다뤄보겠다.
  • IRSA를 만들게 되면 특정 IAM 역할을 Assume 받아 Kubernetes Service Account로 생성할수 있다.
  • 해당 Service Account에는 Annotation으로 IRSA의 arn이 기입된다. 
  •  이렇게 만들어진 Service Account를 Kubernetes Pods에 주입하려면 추가 구성 요소가 필요합니다.
  • Kubernetes는 validation webhook과 mutation webhook를 지원하며 Pod 생성 될 때 추가 토큰을 Pods에 주입할 수 있습니다.

 

☑️ 실습 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
EOF

# 확인
kubectl get pod
kubectl describe pod

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

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

 

  • CloudTrail 이벤트 ListBucket 확인
{
    "eventVersion": "1.09",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "xxx:i-09f2cb72d2366336a",
        "arn": "arn:aws:sts::xxx:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-xxx/i-xxx",
        "accountId": "xxx",
        "accessKeyId": "xxx",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "xxx",
                "arn": "arn:aws:iam::xxx:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-xxx",
                "accountId": "466593096201",
                "userName": "eksctl-myeks-nodegroup-ng1-NodeInstanceRole-xxx"
            },
            "attributes": {
                "creationDate": "2024-02-22T05:35:37Z",
                "mfaAuthenticated": "false"
            },
            "ec2RoleDelivery": "2.0"
        }
    },
    "eventTime": "2024-02-22T06:07:42Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "ListBuckets",
    "awsRegion": "ap-northeast-2",
    "sourceIPAddress": "13.125.34.241",
    "userAgent": "[aws-cli/2.15.22 Python/3.11.6 Linux/5.10.209-198.812.amzn2.x86_64 docker/x86_64.amzn.2 prompt/off command/s3.ls]",
    "errorCode": "AccessDenied",
    "errorMessage": "Access Denied",
    "requestParameters": {
        "Host": "s3.ap-northeast-2.amazonaws.com"

☑️ 실습 2

# 파드2 생성
# 위에 POD와 차이점 SA 토큰이 Auto Mount 된다는 사실을 보려고 
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
EOF

# 확인
kubectl get pod
kubectl describe pod

# 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 웹 사이트 이용
jwt decode $SA_TOKEN --json --iso8601
...

#헤더
{
  "alg": "RS256",
  "kid": "1a8fcaee12b3a8f191327b5e9b997487ae93baab"
}

# 페이로드 : OAuth2에서 쓰이는 aud, exp 속성 확인! > projectedServiceAccountToken 기능으로 토큰에 audience,exp 항목을 덧붙힘
## iss 속성 : EKS OpenID Connect Provider(EKS IdP) 주소 > 이 EKS IdP를 통해 쿠버네티스가 발급한 토큰이 유요한지 검증
{
  "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",
  "kubernetes.io": {
    "namespace": "default",
    "pod": {
      "name": "eks-iam-test2",
      "uid": "10dcccc8-a16c-4fc7-9663-13c9448e107a"
    },
    "serviceaccount": {
      "name": "default",
      "uid": "acb6c60d-0c5f-4583-b83b-1b629b0bdd87"
    },
    "warnafter": 1685087455
  },
  "nbf": 1685083848,
  "sub": "system:serviceaccount:default:default"
}

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

"iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/720A019C610D7Cxxx6CBAAB0"

☑️ 실습 3

  • 파드는 SA 토큰을 Volume에 주입받는데 거기에 Mutation Webhook 기능이 이용됨
  •  쿠버네티스에 SA를 만들고, SA에 annotation을 통해서 IAM ARN을 적어주고, Trust Policy를 만들어주는것이 필요하다.
# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account
eksctl create iamserviceaccount \
  --name my-sa \
  --namespace default \
  --cluster $CLUSTER_NAME \
  --approve \
  --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3ReadOnlyAccess`].Arn' --output text)

# 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인
# aws-load-balancer-controller IRSA는 어떤 동작을 수행할 것 인지 생각해보자!
eksctl get iamserviceaccount --cluster $CLUSTER_NAME

# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.
kubectl get sa
kubectl describe sa my-sa

### 
...
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-1MJUYW59O6QGH

...
  • 파드 생성 하고 확인
  • 위에서 irsa로 s3 정책을 Assume 했고 pod를 생성할때 service Account의 이름만 적어주면 자동으로 mutation Webhook 기능을 통해서 pod의 볼륨에 sa가 탑재되고 ENV값이 생성된다.
# 파드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
EOF


kubectl describe pod eks-iam-test3

...
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-default-Role1-GE2DZKJYWCEN
      AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    Mounts:
      /var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-69rh8 (ro)
...
Volumes:
  aws-iam-token:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  86400
  kube-api-access-sn467:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
...


# 되는 것고 안되는 것은 왜그런가?
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

 

  • IAM_TOKEN과 ROLE_ARN을 탈취할 경우 Assume Token을 발급받아서 악용이 가능하다.
# AWS_WEB_IDENTITY_TOKEN_FILE 토큰 값 변수 지정
IAM_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
echo $IAM_TOKEN

# ROLE ARN 확인 후 변수 직접 지정
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
ROLE_ARN=<각자 자신의 ROLE ARN>
ROLE_ARN=arn:aws:iam::911283464785:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-1W8J3Q0GAMA6U

# assume-role-with-web-identity STS 임시자격증명 발급 요청
aws sts assume-role-with-web-identity --role-arn $ROLE_ARN --role-session-name mykey --web-identity-token $IAM_TOKEN | jq
{
  "Credentials": {
    "AccessKeyId": "ASIA5ILF2FJIZLOCB36X",
    "SecretAccessKey": "IvuD2BEt/TtScyv6uq3U5mF3RStuxya5gHydlz2Z",
    "SessionToken": "IQoJb3JpZ2luX2VjELH//////////wEaDmFwLW5vcnRoZWFzdC0yIkYwRAIgFsxs4rNyxuWTgqIuQWONuU8lkb+S1E9rvY4YLMtAR0ACIAfRrLYpisS1Ql+2agL0meQ+iy08bLv992tTCr0vZkqVKvkECOr//////////wEQARoMOTExMjgzNDY0Nzg1IgwmJn8sjNaBM0F+L/gqzQSnX6M6BlgzqiX3Sob0R8QZo0TEumVqCsLopwdHBzIZL6VU3kFaeqIpUh9uuZ+JaR7MlFKS7FYhIq7r+fMh5f8toWojtyKwLjT9eN2yi5A5ZfWahln1MIu9fv/dASR4USMxLtbMHOGpx3BE/pCHhV+u85z/LoHSlVNaF5IrQiCXbo3f9DrJ0kHQZuQY3N0pFDlGzXuv5hCedGlJQU2IzUcmW5kHQ/jNyIf+xEO2nTSksna5iE3r9TNnO6b6v8gZc5zDUs3fGfJfP4QwKjRXOUDMnydJ9LzME+mYoYHObdeCqncGuGwJ3GIXx9qw9ZABXuAlvATuLROaYkeLsXuote1UOqPILxvETvWo1VHA2f0hYL9ZFDSF3j6yGU+GEHbFGoMRVaVFqdbpF1bMEbC9FlmR5AWbAkkYZs8kfXRcObfpZxLB4vQBXeqj9OU/yDPvvNA+CgOoA5HFI0SjeFQHOVB7S5KVm6CAOKtoMIzTeKnKpKmN07dqJzvGrpwtNMh/GhCouunvbgNG7jF/TM3jgAniDxoD9IzCQMICNgxdioOFnB6Oe1AzMkKui53MP8Af/lcDiUKTIUNrKxdm0719kuXqR88coihzrLGkdA7Eb5Gg/gCnk+SzPu7Wu5xZaYXBe6Xqh0/c1dKsN1YQLOANo5aF3B2RCGJFDwr78rOUvNWxXs84us/Uz5k6LIGZseVzZcGh5U9ztJqhzoKFvnphbtU8b1Ctg/pTrF8EnjLGR0s4QggdrsW1b7vznisMwFrHh0F+FhSy7ldvfeXmwpQgMNP666MGOpsBmNam9fm/qK6EjmllDDvf6mR9l99Vop++V2vf1GoM4ru8/TfgP25+B1N9gEbnRuhMTxQrN6VGcyaNNlKBkwxtAs+aikBcvjk3cm0jPZmiQntTkNtBw92NAJwbRmhSIQynznxN7I1FnFukP06J9V9MiuhsJGXpGXi0kWOOQnqb9u2YraRLKJdTqVfv5dGt7aM67PeJrr/0v2YKU0M=",
    "Expiration": "2023-06-03T09:44:03+00:00"
  },
  "SubjectFromWebIdentityToken": "system:serviceaccount:default:my-sa",
  "AssumedRoleUser": {
    "AssumedRoleId": "AROA5ILF2FJI7UWTLJWKW:mykey",
    "Arn": "arn:aws:sts::911283464785:assumed-role/eksctl-myeks-addon-iamserviceaccount-default-Role1-1W8J3Q0GAMA6U/mykey"
  },
  "Provider": "arn:aws:iam::911283464785:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/8883A42CB049E2FA9B642086E7021450",
  "Audience": "sts.amazonaws.com"
}