728x90
반응형
개요
Amazon EKS는 Pod Identity 기능을 통해 IAM 역할을 특정 Pod에 안전하게 연결할 수 있게 해준다. 이는 IAM Role for Service Accounts (IRSA) 의 발전된 형태로, Pod에서 직접 IAM 역할을 assume하여 AWS 리소스에 접근할 수 있다.
이 문서는 다음을 자동화하는 Bash 스크립트에 대한 설명
- EKS Pod Identity용 IAM Role 생성 (필요 시)
- IAM 정책 연결 (예: AmazonS3ReadOnlyAccess)
- eks-pod-identity-agent Addon 설치
- Pod Identity Association 생성 (ServiceAccount와 IAM Role 연결)
활성화 스크립트
#!/bin/bash
# === EKS Pod Identity 설정 스크립트 ===
# 1. 지정한 IAM Role이 없으면 신뢰 정책 포함 생성
# 2. 지정한 정책 연결 (예: AmazonS3ReadOnlyAccess)
# 3. eks-pod-identity-agent addon 설치
# 4. PodIdentityAssociation 생성 (ServiceAccount와 Role 연결)
# 변수 설정
CLUSTER_NAME="mh-eks-cluster"
SERVICE_ACCOUNT_NAME="my-service-account"
NAMESPACE="default"
ROLE_NAME="S3ReadOnlyPodIdentityTestRole"
POLICY_ARN="arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
export AWS_PROFILE=timf-dev-2
export AWS_PAGER=""
# 계정 ID 추출
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
ROLE_ARN="arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}"
# 1. IAM Role이 없으면 생성
if ! aws iam get-role --role-name "$ROLE_NAME" >/dev/null 2>&1; then
echo "IAM Role이 존재하지 않아 새로 생성합니다: $ROLE_NAME"
cat > trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
EOF
aws iam create-role \
--role-name "$ROLE_NAME" \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
--role-name "$ROLE_NAME" \
--policy-arn "$POLICY_ARN"
rm -f trust-policy.json
else
echo "이미 존재하는 IAM Role입니다: $ROLE_NAME"
fi
# 2. eks-pod-identity-agent addon 설치
echo "eks-pod-identity-agent addon 설치 중..."
eksctl create addon \
--name eks-pod-identity-agent \
--cluster "$CLUSTER_NAME" \
--force
# 3. Pod Identity Association 생성
echo "Pod Identity Association 생성 중..."
eksctl create podidentityassociation \
--cluster "$CLUSTER_NAME" \
--namespace "$NAMESPACE" \
--service-account-name "$SERVICE_ACCOUNT_NAME" \
--role-arn "$ROLE_ARN" \
--create-service-account
echo "완료: ServiceAccount '$SERVICE_ACCOUNT_NAME' in namespace '$NAMESPACE' is now associated with IAM Role '$ROLE_NAME'"
1. 기본 변수
CLUSTER_NAME="mh-eks-cluster" # 사용할 EKS 클러스터 이름
SERVICE_ACCOUNT_NAME="my-service-account" # 연결할 Kubernetes ServiceAccount 이름
NAMESPACE="default" # ServiceAccount가 존재할 네임스페이스
ROLE_NAME="S3ReadOnlyPodIdentityTestRole" # 생성할 IAM Role 이름
POLICY_ARN="arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess" # 연결할 정책 (S3 읽기 전용)
2. AWS 환경설정
export AWS_PROFILE=""
export AWS_PAGER=""
- AWS_PROFILE은 사용 중인 AWS CLI 프로파일을 지정
- AWS_PAGER는 AWS CLI 출력이 less로 페이지 분할되지 않도록 설정
3. IAM Role 존재 여부 확인 및 생성
if ! aws iam get-role --role-name "$ROLE_NAME" >/dev/null 2>&1; then
- 해당 Role이 존재하지 않으면 아래의 신뢰 정책(trust policy) 을 사용해 Role을 생성한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
- 이 신뢰 정책은 pods.eks.amazonaws.com 서비스가 Role을 Assume할 수 있도록 허용한다.
역할 생성 및 정책 연결:
aws iam create-role \
--role-name "$ROLE_NAME" \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
--role-name "$ROLE_NAME" \
--policy-arn "$POLICY_ARN"
- 이후 생성된 정책 파일은 삭제
4. eks-pod-identity-agent Addon 설치
eksctl create addon \
--name eks-pod-identity-agent \
--cluster "$CLUSTER_NAME" \
--force
- 이 addon은 EKS에서 Pod Identity를 사용할 수 있도록 설정
- EKS 클러스터당 한 번만 설치하면 된다.
- -force: 기존에 설치되어 있어도 재설치
5. Pod Identity Association 생성
eksctl create podidentityassociation \
--cluster "$CLUSTER_NAME" \
--namespace "$NAMESPACE" \
--service-account-name "$SERVICE_ACCOUNT_NAME" \
--role-arn "$ROLE_ARN" \
--create-service-account
- 지정된 네임스페이스에 ServiceAccount를 자동 생성하고,
- 해당 SA에 위에서 생성한 IAM Role을 연결한다.
이후 이 ServiceAccount를 사용하는 Pod는 자동으로 Role을 Assume하게 되며, AWS SDK를 통해 S3에 접근할 수 있게 된다.
Pod Identity 검증 테스트
Pod identity에 생성한 권한은 S3ReadOnly권한을 추가해두었다. 테스트시 사용될 코드는 아래와 같다.
- /buckets: AWS SDK를 사용해 S3 버킷 목록을 JSON으로 반환
- 권한이 없다면 에러를 발생
- /: 헬스 체크용, 단순히 "ok" 문자열 반환
- 서버는 :8080 포트에서 실행
package main
import (
"context"
"encoding/json"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"log"
"net/http"
)
func listBucketHandler(w http.ResponseWriter, r *http.Request) {
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"error": "Failed to load AWS config",
"details": err.Error(),
})
return
}
s3Client := s3.NewFromConfig(cfg)
result, err := s3Client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"error": "Failed to list S3 buckets",
"details": err.Error(),
})
return
}
var bucketNames []string
for _, v := range result.Buckets {
bucketNames = append(bucketNames, *v.Name)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"buckets": bucketNames,
})
}
func main() {
http.HandleFunc("/buckets", listBucketHandler)
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
writer.Write([]byte("ok"))
})
log.Println("Server running on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatalf("Server failed: %v", err)
}
}
1. EKS Pod Identity 연동 예제
sa 적용시
apiVersion: apps/v1
kind: Deployment
metadata:
name: s3-test
spec:
selector:
matchLabels:
app.kubernetes.io/name: s3-test
replicas: 5
template:
metadata:
labels:
app.kubernetes.io/name: s3-test
spec:
serviceAccountName: my-service-account
containers:
- image: 178339389771.dkr.ecr.ap-northeast-2.amazonaws.com/sa:s3-pod
imagePullPolicy: Always
name: s3-test
ports:
- containerPort: 80
- Pod identity로 생성한 SA를 사용하기위해서는 Depoyment 오브젝트의
spec.template.spec.serviceAccountName
에 생성한 SA의 이름을 부여해주면 해당 Pod는 S3ReadOnly 권한을 사용할 수 있게된다.
- 이미지를 보면 의도대로 버킷리스트 들을 확인할 수 있다.
sa 미적용시
미적용은 간단하게 spec.template.spec.serviceAccountName
를 빼면 된다.
SA를 제외하게되면 당연하게 AWS S3의 읽을 권한이 없으므로 조회가 불가능하다.
2. pod 내부 크레덴셜
sa가 적용된 pod의 경우 Describe로 조회했을때 AWS_ 접두사로 시작하는 환경변수들을 확인 할 수있다.
EKS Pod Identity를 사용하면, Pod에 ServiceAccount를 설정했을 때 내부적으로 다음이 이루어진다.
- eks-pod-identity-agent 가 동작하며
- 해당 Pod의 메타데이터에 연결된 IAM Role 정보를 읽고
- Pod 내부에 필요한 인증 정보를 환경변수로 주입한다.
당연하게도 SA를 지정하지 않는 pod의 경우 환경변수를 찾아볼 수 없다.
참고
728x90
반응형
'DevOps > K8s' 카테고리의 다른 글
[EKS] AWS Load Balancer Controller 설치 및 사용 방법 (0) | 2025.04.17 |
---|---|
[K8s] 쿠버네티스 livenessProbe로 파드 헬스 체크 (0) | 2023.02.14 |
[K8s] 쿠버네티스 Service 개념 (0) | 2022.12.30 |
[K8s] 쿠버네티스 Deployment를 이용한 RollingUpdate (0) | 2022.12.27 |
[K8s] 쿠버네티스 Deployment의 개념 (2) | 2022.12.22 |