25๋ ๋ AWS EKS Hands-on Study ์คํฐ๋ ์ ๋ฆฌ ๋ด์ฉ์ ๋๋ค.
IRSA
IRSA๋ ์ฟ ๋ฒ๋คํฐ์ค์ ์๋น์ค ์ด์นด์ดํธ(Service Account, SA)์ AWS IAM ์ญํ (Role)์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฟ ๋ฒ๋คํฐ์ค์ ํ๋๋ AWS ๋ฆฌ์์ค(S3, DynamoDB ๋ฑ)์ ์ง์ ์ ๊ทผํ ์ ์์ผ๋ฉฐ, AWS์ ๋ณด์ ์ ์ฑ
์ ๋ฐ๋ผ IAM ๊ถํ์ ๋ถ์ฌํด์ผ ํ๋ค.
๊ธฐ์กด์๋ EC2 ์ธ์คํด์ค์ IAM Role์ ๋ถ์ด๋ ๋ฐฉ์์ ์ฌ์ฉํ์ง๋ง ์ด๋ ์ธ๋ถํ๋ ๊ถํ ๊ด๋ฆฌ๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
IRSA๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ ๋จ์๋ก IAM ๊ถํ์ ๋ถ์ฌํ ์ ์์ด ๋ณด์์ฑ๊ณผ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํ๋ค.
- ๋ถํ์ํ ๊ถํ์ ์ค์ผ ์ ์์ โ ํน์ Pod์๋ง ํ์ํ AWS ๋ฆฌ์์ค ์ ๊ทผ ๊ถํ์ ๋ถ์ฌ ๊ฐ๋ฅ
- ๋ฉํฐํ ๋์ ํ๊ฒฝ์์ ๋ณด์ ๊ฐํ โ ๋์ผํ ํด๋ฌ์คํฐ ๋ด์์๋ ์ ํ๋ฆฌ์ผ์ด์ (ํ๋)๋ณ๋ก ๋ค๋ฅธ IAM ์ ์ฑ ์ ์ ์ฉ ๊ฐ๋ฅ
- IAM ์ ์ฑ ์ ์ฉ์ด ํ๋ ์์ค์ผ๋ก ๋ด๋ ค๊ฐ โ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ด๋ฆฌ ๊ฐ๋ฅ
sa ๊ณ์ ์์ฑ
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)
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::~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
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
kubectl get pod eks-iam-test3 -o yaml
...
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-dccvr
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
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::~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP
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-dccvr (ro)
kubectl exec -it eks-iam-test3 -- aws sts get-caller-identity --query Arn
"arn:aws:sts::~~:assumed-role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP/botocore-session-1742074654"
eks-iam-test3 ํ๋๋ my-service-account๋ผ๋ ์๋น์ค ์ด์นด์ดํธ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ณ AWS IAM Role๊ณผ ์ฐ๊ฒฐ๋์ด ์๋ค.
ํ๋๊ฐ ์คํ๋๋ฉด AWS IAM STS(Security Token Service)์์ ํ ํฐ์ ๋ฐ์์ IAM Role์ Assumeํ ์ ์๊ณ ์ด ๊ณผ์ ์ ํตํด ํ๋๋ IAM Role์ ๊ถํ์ ์ฌ์ฉํ์ฌ AWS ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋ค.
IAM ์ธ์ฆ ํ ํฐ ์ค์ ๊ณผ Mutating Webhook ํ์ธ
kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].volumeMounts'
[
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "kube-api-access-dccvr",
"readOnly": true
},
{
"mountPath": "/var/run/secrets/eks.amazonaws.com/serviceaccount",
"name": "aws-iam-token",
"readOnly": true
}
]
kube-api-access-dccvr:
- ์ฟ ๋ฒ๋คํฐ์ค ๊ธฐ๋ณธ ์๋น์ค ์ด์นด์ดํธ(SA) ํ ํฐ์ ์ ์ฅํ๋ ๋๋ ํ ๋ฆฌ(/var/run/secrets/kubernetes.io/serviceaccount)
- ํ๋๊ฐ ์ฟ ๋ฒ๋คํฐ์ค API ์๋ฒ์ ํต์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
aws-iam-token:
- IRSA๋ฅผ ํตํด AWS STS ํ ํฐ์ ์ ์ฅํ๋ ๋๋ ํ ๋ฆฌ(/var/run/secrets/eks.amazonaws.com/serviceaccount)
- ์ด ํ ํฐ์ ์ฌ์ฉํ์ฌ IAM Role์ Assumeํ์ฌ AWS ๋ฆฌ์์ค์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
kubectl get pod eks-iam-test3 -o json | jq -r '.spec.volumes[] | select(.name=="aws-iam-token")'
{
"name": "aws-iam-token",
"projected": {
"defaultMode": 420,
"sources": [
{
"serviceAccountToken": {
"audience": "sts.amazonaws.com",
"expirationSeconds": 86400,
"path": "token"
}
}
]
}
}
IAM STS ํ ํฐ ์ค์
- audience: "sts.amazonaws.com" โ AWS STS(Security Token Service)์์ ์ฌ์ฉํ IAM ์ธ์ฆ ํ ํฐ
- expirationSeconds: 86400 โ ํ ํฐ ๋ง๋ฃ ์๊ฐ(24์๊ฐ)
- path: "token" โ Pod ๋ด๋ถ์์ /var/run/secrets/eks.amazonaws.com/serviceaccount/token ๊ฒฝ๋ก์ ํ ํฐ์ด ์ ์ฅ๋๋ค.
kubectl get MutatingWebhookConfiguration
NAME WEBHOOKS AGE
pod-identity-webhook 1 6h37m
vpc-resource-mutating-webhook 1 6h37m
์ฟ ๋ฒ๋คํฐ์ค์์ ํ๋๊ฐ ์์ฑ๋ ๋ ์๋์ผ๋ก ํน์ ์ค์ ์ ์ถ๊ฐํ ์ ์๋๋ก ํ๋ ์นํ ์ด๋ค.
๋ง์ฝ ํ๋ ์์ฑ ์์ฒญ์ด ๋ค์ด์ค๋ฉด Mutating Webhook์ด ์ด๋ฅผ ๊ฐ๋ก์ฑ์ ๋ณผ๋ฅจ ๋ง์ดํธ, ํ๊ฒฝ ๋ณ์ ์ถ๊ฐ์ ๊ฐ์ ์ถ๊ฐ ์ค์ ์ ์ ์ฉํ๋ค.
ํ๋์ IAM ๋กค ์ค์ ํ์ธ
kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].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::~~:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-3OtbVkhc7PHP"
},
{
"name": "AWS_WEB_IDENTITY_TOKEN_FILE",
"value": "/var/run/secrets/eks.amazonaws.com/serviceaccount/token"
}
]
- IAM Role (AWS_ROLE_ARN)์ด ํ ๋น๋์ด ์๋ค.
- STS ํ ํฐ ํ์ผ (AWS_WEB_IDENTITY_TOKEN_FILE)์ด /var/run/secrets/eks.amazonaws.com/serviceaccount/token์ ์กด์ฌํ๋ค.
- ํ๋ ๋ด๋ถ์์ STS ํ ํฐ์ ์ด์ฉํ์ฌ AWS IAM Role์ Assumeํ ์ ์์
ํ๋ ๋ด๋ถ STS ์ธ์ฆ ํ ํฐ ํ์ธ
IAM_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
echo $IAM_TOKEN
ํ๋ ๋ด๋ถ์์ ์ด ํ ํฐ์ AWS STS์ ์ ์ถํ์ฌ ํด๋น IAM Role๋ก AWS API๋ฅผ ํธ์ถํ ์ ์๋ค.
OIDC ์ค์ ์ ๋ณด ํ์ธ
curl -s $IDP/.well-known/openid-configuration | jq -r '.'
{
"issuer": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/XXXXXXXXX",
"jwks_uri": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/XXXXXXXXX/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"
]
}
EKS๋ OIDC๋ฅผ ์ง์ํ๋ฉฐ OIDC ๊ธฐ๋ฐ ์ธ์ฆ์ ํตํด AWS IAM ์ญํ ์ ํ๋์ ๋ถ์ฌํ ์ ์๋ค.
JWKS URL์ ํตํด ๊ณต๊ฐ ํค๋ฅผ ์ ๊ณตํ๋ฉฐ AWS STS๋ ์ด๋ฅผ ์ฌ์ฉํ์ฌ OIDC ํ ํฐ์ ์ ํจ์ฑ์ ๊ฒ์ฆํ๋๋ฐ, ์ด ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก EKS์ IRSA ๊ฐ ๋์ํ์ฌ ํ๋๊ฐ AWS ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋๋ก ํ๋ค.
๋ฆฌ์์ค ์ญ์
kubectl delete pod eks-iam-test3
pod "eks-iam-test3" deleted
eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --name my-sa --namespace default
2025-03-16 06:48:14 [โน] 1 iamserviceaccount (default/my-sa) was included (based on the include/exclude rules)
2025-03-16 06:48:14 [โน] 1 task: {
2 sequential sub-tasks: {
delete IAM role for serviceaccount "default/my-sa" [async],
delete serviceaccount "default/my-sa",
} }2025-03-16 06:48:15 [โน] will delete stack "eksctl-myeks-addon-iamserviceaccount-default-my-sa"
2025-03-16 06:48:15 [โน] deleted serviceaccount "default/my-sa"
'Infra > AWS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[AEWS] #7์ฃผ์ฐจ Fargate ๋ฐฐํฌ ์ค์ต (1) | 2025.03.23 |
---|---|
[AEWS] #6์ฃผ์ฐจ Kyverno ์ค์ต (5) (0) | 2025.03.16 |
[AEWS] #6์ฃผ์ฐจ EKS ์ธ์ฆ/์ธ๊ฐ (3) (1) | 2025.03.16 |
[AEWS] #6์ฃผ์ฐจ ์๋น์ค ์ด์นด์ดํธ, role ๊ถํ ํ์ธ ์ค์ต (2) (0) | 2025.03.16 |
[AEWS] #6์ฃผ์ฐจ x.509 ์ธ์ฆ์ ๊ตฌ์กฐ ๋ฐ ๊ฒ์ฆ ์ค์ต (1) (0) | 2025.03.16 |