본 페이지는 AWS EKS Workshop 실습 스터디의 일환으로 매주 실습 결과와 생각을 기록하는 장으로써 작성하였습니다.
$curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick5.yaml
$aws cloudformation deploy --template-file eks-oneclick5.yaml --stack-name myeks --parameter-overrides KeyName=atomy-test-key.pem SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIAR5... MyIamUserSecretAccessKey='R1oQ...' ClusterBaseName=myeks --region ap-northeast-2
$ssh -i eljoe-test-key.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)
$kubectl ns default
$NICK=eljoelee
$kubectl ctx
$kubectl config rename-context admin@myeks.ap-northeast-2.eksctl.io $NICK
$MyDomain=eljoe-test.link
$echo "export MyDomain=eljoe-test.link" >> /etc/profile
$MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
# ExternalDNS
$curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
$MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
# LB Controller
$helm repo add eks https://aws.github.io/eks-charts
$helm repo update
$helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
# 노드 IP 변수 지정
$N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
$N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
$N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
$echo "export N1=$N1" >> /etc/profile
$echo "export N2=$N2" >> /etc/profile
$echo "export N3=$N3" >> /etc/profile
# 노드 보안그룹 확인 및 설정
$NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values='*ng1*' --query "SecurityGroups[*].[GroupId]" --output text)
$aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.0/24
# 노드 접속 확인
$for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done
krew 플러그인 설치
$kubectl krew install access-matrix rbac-tool rbac-view rolesum
# Namespace(default) 리소스 접근 권한 출력
$kubectl access-matrix --namespace default
# User, Group, ServiceAccount에 연결한 Role/ClusterRole 검색
$kubectl rbac-tool lookup system:masters
SUBJECT | SUBJECT TYPE | SCOPE | NAMESPACE | ROLE
+----------------+--------------+-------------+-----------+---------------+
system:masters | Group | ClusterRole | | cluster-admin
Flow
💡 인증은 AWS IAM, 인가는 K8S RBAC에서 처리
EKS Cluster 접근 권한을 부여한 PC에서 kubectl 명령어를 입력한다.
$kubectl get node
PC의 kubeconfig 내 정의된 eks get-token
명령어를 실행하여 STS(Security Token Service)로 요청을 전달한다.
$cat ~/.kube/config | yh
...
users:
- name: eljoe@myeks.ap-northeast-2.eksctl.io
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- eks
- get-token
- --output
- json
- --cluster-name
- myeks
- --region
- ap-northeast-2
command: aws
env:
- name: AWS_STS_REGIONAL_ENDPOINTS
value: regional
interactiveMode: IfAvailable
provideClusterInfo: false
# 하기 명령어를 실행하는 것과 동일하다.
$aws eks get-token --output json --cluster-name myeks --region ap-northeast-2
STS로부터 Base64로 인코딩된 토큰 값을 응답으로 전달 받는다.
$aws eks get-token --output json --cluster-name myeks --region ap-northeast-2 | jq
{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"spec": {},
"status": {
"expirationTimestamp": "2023-05-31T20:49:26Z",
"token": "k8s-aws-v1.aHR0cHM6..."
}
}
kubectl의 Client-Go 라이브러리가 Pre-Signed URL을 Bearer Token으로 EKS Cluster Endpoint를 통해 API 서버로 요청을 전송한다.
💡 Client-Go
K8S 클러스터와 상호작용하기 위한 공식 Go 라이브러리, kubectl은 Client-Go를 내부적으로 사용하여 K8S 클러스터와 상호작용한다.
API 서버는 내부의 token webhook server로 동작하는 aws-iam-authenticator에게 eks get-token
명령어를 통해 생성한 토큰의 Review를 요청한다.
요청을 전달 받은 aws-iam-authenticator는 Token authentication webhook을 호출하고 토큰을 통해 sts get-caller-identity
명령어를 수행하여 IAM에 요청한다.
# 호출한 자신의 IAM Entity 반환
$aws sts get-caller-identity
{
"UserId": "AIDAR5GKWUSFIWT65CUO3",
"Account": "131421611146",
"Arn": "arn:aws:iam::131421611146:user/eljoe"
}
# 다음과 같이 x-k8s-aws-id header를 통해 고유한 클러스터 ID를 삽입하여 요청한다.
$curl -H 'x-k8s-aws-id: myeks' "https://sts.ap-northeast-2.amazonaws.com/?
Action=GetCallerIdentity&
Version=2011-06-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIAR5GKW...%2F20230601%2Fap-northeast-2%2Fsts%2Faws4_request&
X-Amz-Date=20230601T015250Z&
X-Amz-Expires=60&
X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&
X-Amz-Signature=97ecd3cd2c64b4180a267f2c76....."
<GetCallerIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<GetCallerIdentityResult>
<Arn>arn:aws:iam::131421611146:user/eljoe</Arn>
<UserId>AIDAR5GKWUSFIWT65CUO3</UserId>
<Account>131421611146</Account>
</GetCallerIdentityResult>
<ResponseMetadata>
<RequestId>75ce0824-62c2-41a9-976c-6723b98d7315</RequestId>
</ResponseMetadata>
</GetCallerIdentityResponse>
IAM으로부터 반환받은 UserId
, User
또는 Role
의 ARN을 kube-system 네임 스페이스의 ConfigMap aws-auth
의 User/Group 정보와 매핑하고 API 서버에 TokenReview
라는 데이터 타입으로 반환한다.
# kubectl get cm -n kube-system aws-auth -o yaml
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-COZS3070MAKG
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
- groups:
- system: masters
userarn: arn:aws:iam::131421611146:user/eljoe
username: admin
kind: ConfigMap
metadata:
creationTimestamp: "2023-05-31T14:28:19Z"
name: aws-auth
namespace: kube-system
$kubectl api-resources | grep authentication
tokenreviews authentication.k8s.io/v1 false TokenReview
$kubectl explain tokenreviews
KIND: TokenReview
VERSION: authentication.k8s.io/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.
반환 받은 TokenReview
를 활용하여 RBAC를 통해 요청을 허용/거부하는 인가 작업을 처리한다.
# EKS를 설치한 IAM User는 aws-auth와 상관없이 system:masters 그룹에 속한다.
$kubectl rbac-tool whoami
{Username: "kubernetes-admin",
UID: "aws-iam-authenticator:131421611146:AIDAR5GKWUSFIWT65CUO3",
Groups: ["system:masters",
"system:authenticated"],
Extra: {accessKeyId: ["AKIAR5GKWUSFNUELTDHK"],
arn: ["arn:aws:iam::131421611146:user/eljoe"],
canonicalArn: ["arn:aws:iam::131421611146:user/eljoe"],
principalId: ["AIDAR5GKWUSFIWT65CUO3"],
sessionName: [""]}}
$kubectl rbac-tool lookup system:master
SUBJECT | SUBJECT TYPE | SCOPE | NAMESPACE | ROLE
+----------------+--------------+-------------+-----------+---------------+
system:masters | Group | ClusterRole | | cluster-admin
$kubectl rolesum -k Group system:masters
Group: system:masters
Policies:
• [CRB] */cluster-admin ⟶ [CR] */cluster-admin
Resource Name Exclude Verbs G L W C U P D DC
*.* [*] [-] [-] ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
# system:master 그룹이 사용 가능한 Cluster Role : cluster-admin
$kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
# PolicyRule : 모든 리소스 사용 가능
$kubectl describe clusterrole cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
Example - 임의 사용자(testuser) 권한 설정해보기
IAM User 생성 - myeks-bastion
$aws iam create-user --user-name testuser
# 액세스 키 부여
$aws iam create-access-key --user-name testuser
{
"AccessKey": {
"UserName": "testuser",
"AccessKeyId": "AKIAR5GK...",
"Status": "Active",
"SecretAccessKey": "+RI3Z28KkqegyUbHXDd....",
"CreateDate": "2023-06-01T07:34:52+00:00"
}
}
# AdministratorAccess 정책 부여
$aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser
# getCallerIdentity 확인
$aws sts get-caller-identity --query Arn
"arn:aws:iam::131421611146:user/eljoe"
자격증명 설정 - myeks-bastion-2
$aws configure
AWS Access Key ID [None]: AKIAR5...
AWS Secret Access Key [None]: +RI3Z28Kkqeg...
Default region name [None]: ap-northeast-2
Default output format [None]:
$aws sts get-caller-identity --query Arn
"arn:aws:iam::131421611146:user/testuser"
# kubectl 명령어 실패
$kubectl get node
E0601 16:44:28.272734 5811 memcache.go:265] 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
testuser > system:masters 그룹 부여 - myeks-bastion
$eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuser
# configmap > aws-auth mapUsers 확인
$kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-COZS3070MAKG
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
- groups:
- system:masters
userarn: arn:aws:iam::131421611146:user/testuser
username: testuser
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
# 확인
$eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN USERNAME GROUPS ACCOUNT
arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-COZS3070MAKG system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes
arn:aws:iam::131421611146:user/testuser testuser system:masters
testuser kubeconfig 생성 및 kubectl 확인 - myeks-bastion-2
# kubeconfig 생성
$aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias testuser
# kubectl 사용 확인
$kubectl ns default
$kubectl get node
$kubectl krew install rbac-tool && kubectl rbac-tool whoami
...
{Username: "testuser",
UID: "aws-iam-authenticator:131421611146:AIDAR5GKWUS...",
Groups: ["system:masters",
"system:authenticated"],
Extra: {accessKeyId: ["AKIAR5GKWUS..."],
arn: ["arn:aws:iam::131421611146:user/testuser"],
canonicalArn: ["arn:aws:iam::131421611146:user/testuser"],
principalId: ["AIDAR5GKWUS..."],
sessionName: [""]}}
testuser > Group 변경(system:masters > system:authenticated) 후 RBAC 동작 확인 - myeks-bastion
$kubectl edit cm -n kube-system aws-auth
...
mapUsers: |
- groups:
- system:authenticated
userarn: arn:aws:iam::131421611146:user/testuser
username: testuser
...
$eksctl get iamidentitymapping --cluster $CLUSTER_NAME
...
arn:aws:iam::131421611146:user/testuser testuser system:authenticated
testuser kubectl 사용 확인 - myeks-bastion-2
$kubectl get node
Error from server (Forbidden): nodes is forbidden: User "testuser" cannot list resource "nodes" in API group "" at the cluster scope
$kubectl api-resources
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
...
testuser IAM Mapping 삭제 - myeks-bastion
$eksctl delete iamidentitymapping --cluster $CLUSTER_NAME --arn arn:aws:iam::$ACCOUNT_ID:user/testuser
$eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN USERNAME GROUPS ACCOUNT
arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-COZS3070MAKG system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes
$kubectl get cm -n kube-system aws-auth -o yaml | yh
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-COZS3070MAKG
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
[]
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
testuser kubectl 사용 확인
$kubectl get node
error: You must be logged in to the server (Unauthorized)
$kubectl api-resources
E0601 17:52:37.342753 6877 memcache.go:265] couldn't get current server API group list: the server has asked for the client to provide credentials
NAME SHORTNAMES APIVERSION NAMESPACED KIND
error: You must be logged in to the server (the server has asked for the client to provide credentials)
$cat <<EOF | kubectl apply -f -
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: resource-readonly
subjects:
- kind: Group
name: readonly
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: resource-readonly
apiGroup: rbac.authorization.k8s.io
EOF
$cat <<EOF | kubectl apply -f -
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: resource-readonly
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "watch", "list"]
EOF
# 'readonly' 그룹으로 수정
$kubectl edit cm -n kube-system aws-auth
...
mapUsers: |
- groups:
- readonly
userarn: arn:aws:iam::123456789:user/testuser
username: testuser
...
$eksctl get iamidentitymapping --cluster $CLUSTER_NAME
ARN USERNAME GROUPS ACCOUNT
arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1GNS41CWX1J3T system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes
arn:aws:iam::131421611146:user/testuser testuser readonly
$kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 4h24m
# aws-cli 명령어를 실행하는 pod 생성
$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
# SA가 없으므로 Access Denied이 되었음을 확인할 수 있다.
$kubectl logs eks-iam-test1
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
# CloudTrail Event로도 조회할 수 있다.
$aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=ListBuckets --max-items 5 --query "Events[].CloudTrailEvent"| jq
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "xxx",
"arn": "arn:aws:sts::123456789:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-xxxxx/xxxx",
"accountId": "123456789",
"accessKeyId": "ASIAR5...",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "AROAR5GKWU...",
"arn": "arn:aws:iam::131421611146:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-...",
"accountId": "123456789",
"userName": "eksctl-myeks-nodegroup-ng1-NodeInstanceRole-..."
},
...
}
},
"eventTime": "2023-06-02T03:51:11Z",
"eventSource": "s3.amazonaws.com",
"eventName": "ListBuckets",
"awsRegion": "ap-northeast-2",
"sourceIPAddress": "3.35.5.21",
"userAgent": "[aws-cli/2.11.24 Python/3.11.3 Linux/5.10.179-166.674.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"
},
...
}
# aws-cli 명령어를 실행하는 pod 생성
$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
# SA를 생성했음에도 Access Denied 확인
$kubectl exec -it eks-iam-test2 -- aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
command terminated with exit code 254
# SA 확인
$SA_TOKEN=$(kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
$echo $SA_TOKEN
eyJhbGciOiJSUzI...
projectedServiceAccountToken 기능으로 토큰에 aud, exp 항목 추가
iss는 EKS OpenID Connect Provider(EKS IdP) 주소로 작성되어있다. 즉, K8S가 발급한 토큰의 유효성 검증은 EKS IdP에서 수행한다.
{
"aud": [
"https://kubernetes.default.svc"
],
"exp": 1717214976,
"iat": 1685678976,
"iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/B4EAA30DD353145BF5DD356107D1A0D4",
"kubernetes.io": {
"namespace": "default",
"pod": {
"name": "eks-iam-test2",
"uid": "11e6d9f8-d0e7-4102-ab4f-0ba5dd37efc9"
},
"serviceaccount": {
"name": "default",
"uid": "24ab5d1a-58cf-487b-9a83-86a3e77e2e3d"
},
"warnafter": 1685682583
},
"nbf": 1685678976,
"sub": "system:serviceaccount:default:default"
}
iss
: 토큰 발행자sub
: 사용자를 구분하기 위한 유니크한 구분자email
: 사용자의 이메일iat
: 토큰이 발행되는 시간을 Unix time으로 표기한 것exp
: 토큰이 만료되는 시간을 Unix time으로 표기한 것aud
: ID Token이 어떤 Client를 위해 발급된 것인지.# IRSA 생성
$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)
# SA 확인
$eksctl get iamserviceaccount --cluster $CLUSTER_NAME
NAMESPACE NAME ROLE ARN
default my-sa arn:aws:iam::131421611146:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-FK6GGUC9B133
kube-system aws-load-balancer-controller arn:aws:iam::131421611146:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-F55Y1OOUV3JW
$kubectl get sa
NAME SECRETS AGE
default 0 3h23m
my-sa 0 13m
$kubectl describe sa my-sa
Name: my-sa
Namespace: default
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::131421611146:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-FK6GGUC9B133
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
# 역할 조회 : sts:AssumeRoleWithWebIdentity > system:serviceaccount:default:my-sa
$aws iam get-role \
--role-name $(aws cloudformation describe-stacks --stack-name eksctl-myeks-addon-iamserviceaccount-default-my-sa --query 'Stacks[*].Outputs[0].OutputValue' --output text | cut -d '/' -f2)
{
"Role": {
"Path": "/",
"RoleName": "eksctl-myeks-addon-iamserviceaccount-default-Role1-FK6GGUC9B133",
"RoleId": "AROAR5G...",
"Arn": "arn:aws:iam::131421611146:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-FK6GGUC9B133",
"CreateDate": "2023-06-02T04:29:24+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/xxxx"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.ap-northeast-2.amazonaws.com/id/xxxx:sub": "system:serviceaccount:default:my-sa",
"oidc.eks.ap-northeast-2.amazonaws.com/id/xxxx:aud": "sts.amazonaws.com"
}
}
}
]
},
...
}
}
# aws-cli 명령어를 실행하는 pod 생성 > SA 값 삽입
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
# 파드 생성 시 작성한 YAML에 없는 내용이 추가되었다. - Env, Volume
$kubectl describe pod eks-iam-test3
...
Containers:
my-aws-cli:
...
Environment:
AWS_STS_REGIONAL_ENDPOINTS: regional
AWS_DEFAULT_REGION: ap-northeast-2
AWS_REGION: ap-northeast-2
AWS_ROLE_ARN: arn:aws:iam::131421611146:role/eksctl-myeks-addon-iamserviceaccount-default-Role1-FK6GGUC9B133
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-7jfkk (ro)
...
Volumes:
aws-iam-token:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 86400
kube-api-access-7jfkk:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
...
# Pod Identity Webhook은 mutating webhook을 통해 Env, Volume 값을 추가함
$kubectl get mutatingwebhookconfigurations pod-identity-webhook -o yaml | kubectl neat | yh
# 파드에서 aws-cli 사용 확인 - AmazonS3ReadOnlyAccess 권한만 부여했으므로 다른 작업은 되지않음!
$kubectl exec -it eks-iam-test3 -- aws s3 ls
2023-04-13 07:11:55 cdk-hnb659fds-assets-131421611146-ap-northeast-2
...
$kubectl exec -it eks-iam-test3 -- aws ec2 describe-vpcs --region ap-northeast-2
An error occurred (UnauthorizedOperation) when calling the DescribeVpcs operation: You are not authorized to perform this operation.
command terminated with exit code 254
# 도전과제 - ReadOnlyAccess 부여
$eksctl create iamserviceaccount \
--name my-sa-readonly \
--namespace default \
--cluster $CLUSTER_NAME \
--approve \
--attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`ReadOnlyAccess`].Arn' --output text)
$kubectl get sa
NAME SECRETS AGE
default 0 3h46m
my-sa 0 36m
my-sa-readonly 0 14s
$cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: eks-iam-test3
spec:
serviceAccountName: my-sa-readonly
containers:
- name: my-aws-cli
image: amazon/aws-cli:latest
command: ['sleep', '36000']
restartPolicy: Never
EOF
$kubectl exec -it eks-iam-test3 -- aws ec2 describe-vpcs --region ap-northeast-2
{
"Vpcs": [
...