EKS IRSA(IAM Roles for Service Accounts)
기존에는 Worker-Node 즉 EC2에 맵핑된 IAM Role를 Pod가 그대로 사용 할 수 있었다.
따라서 Pod가 탈취되면 그대로 EC2 IAM Role를 사용하여 보안적으로 취약할 수 있다.
이에 노드가 아닌 Pod에 최소한의 IAM 권한을 주는것이 IRSA이다.
실습 1 ( service account Token - false)
1. Pod 생성 시 Service Account Token이 자동 마운트 설정 해제
# 파드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
2. Pod에서 S3를 조회하는 명령어가 작동하는지 확인
# 확인
kubectl get pod
kubectl describe pod
# 로그 확인
kubectl logs eks-iam-test1
# 파드1 삭제
kubectl delete pod eks-iam-test1
실습 2 ( service account Token - True)
1. Pod 생성
# 파드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
2. Pod에서 Service Account Token 확인 및 S3를 조회하는 명령어가 작동하는지 확인
kubectl exec -it eks-iam-test2 -- ls /var/run/secrets/kubernetes.io/serviceaccount
kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ;echo
(yjsong@myeks:default) [root@myeks-bastion ~]# kubectl exec -it eks-iam-test2 -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
# aws 서비스 사용 시도
kubectl exec -it eks-iam-test2 -- aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
실습 3 ( IRSA)
초기 EKS 배포 시 iam 설정 내 withOIDC가 true로 설정되어 있어 IRSA를 사용 할 수 있음
1. IRSA 생성 - Service Account와 IAM Role ARN 맵핑
# 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)
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
2. IRSA 확인 (my-sa Service Account 생성 및 IAM Role 맵핑 확인)
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get sa
kubectl describe sa my-sa
3. Pod 생성 ( Pod 생성 시 my-sa Service Account 지정 )
# 파드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
# 해당 SA를 파드가 사용 시 mutatingwebhook으로 Env,Volume 추가함
kubectl get mutatingwebhookconfigurations pod-identity-webhook -o yaml | kubectl neat | yh
(yjsong@myeks:default) [root@myeks-bastion ~]# kubectl get pod eks-iam-test3 -o yaml | kubectl neat | yh
apiVersion: v1
kind: Pod
metadata:
name: eks-iam-test3
namespace: default
spec:
containers:
- command:
- sleep
- "36000"
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::590183955668:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-WclIR9gNmGm7
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
image: amazon/aws-cli:latest
name: my-aws-cli
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-rpzfw
readOnly: true
- mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
name: aws-iam-token
readOnly: true
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Never
serviceAccountName: my-sa
terminationGracePeriodSeconds: 0
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: aws-iam-token
projected:
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
- name: kube-api-access-rpzfw
projected:
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.namespace
path: namespace
4. Pod에서 S3를 조회하는 명령어가 작동하는지 확인
kubectl exec -it eks-iam-test3 -- aws s3 ls
정리: 실습1, 실습2의 경우 Service Account 사용 또는 미사용과 상관없이 Pod가 S3에 대한 IAM Role이 없기 때문에 명령어를 사용하지 못하고 있다.
실습3경우 Service Account와 S3 IAM Role를 맵핑 후 해당 Service Account로 Pod를 생성하여 정상적으로 S3를 조회하는 것을 확인 할 수 있다. (IRSA)
EKS Pod Identity
IRSA의 경우, OIDC 앤드포인트가 공개( Public )으로 되어 있고, 신뢰 정책을 엄하게 설정하지 않으면 보안에 취약 할 수있음.
실습 - "eks-pod-identity-agent 설치"
1. eks-pod-identity-agent 설치
#
ADDON=eks-pod-identity-agent
aws eks describe-addon-versions \
--addon-name $ADDON \
--kubernetes-version 1.28 \
--query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \
--output text
v1.2.0-eksbuild.1
True
v1.1.0-eksbuild.1
False
v1.0.0-eksbuild.1
False
aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name eks-pod-identity-agent
혹은
eksctl create addon --cluster $CLUSTER_NAME --name eks-pod-identity-agent --version 1.2.0
2. 확인
kubectl get ds -n kube-system eks-pod-identity-agent -o yaml | kubectl neat | yh
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ss -tnlp | grep eks-pod-identit; echo "-----";done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c route; done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c -br -4 addr; done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c addr; done
3. podidentityassociation 설정
eksctl create podidentityassociation \
--cluster $CLUSTER_NAME \
--namespace default \
--service-account-name s3-sa \
--role-name s3-eks-pod-identity-role \
--permission-policy-arns arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--region $AWS_REGION
# 확인
kubectl get sa
eksctl get podidentityassociation --cluster $CLUSTER_NAME
4. SA 생성 및 Pod 생성
kubectl create sa s3-sa
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
5. 확인
kubectl get pod eks-pod-identity -o yaml | kubectl neat| yh
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
# 토큰 정보 확인
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
- 고려사항 - 신규 기능이라 사용하기에는 많은 제약사항이 있음.
- SDK 최신 버전
- 워커노드에 IAM Policy 추가 - eks-auth:AssumeRoleForPodIdentity
- 보안 솔루션으로 링크 로컬 주소 사용 가능 여부 확인
'AEWS Study' 카테고리의 다른 글
7주차 - EKS CI/CD - ArgoCD / ArgoRollouts (1) | 2024.04.18 |
---|---|
6주차 - EKS Security - Kyverno & 보안 위협 시나리오 (0) | 2024.04.14 |
6주차 - EKS Security - 사용자 인증/인가 (0) | 2024.04.09 |
5주차 - EKS Autoscaling - Karpenter (1) | 2024.04.07 |
5주차 - EKS Autoscaling - (Node Autoscaling) (0) | 2024.04.05 |