https://dev.classmethod.jp/articles/create-eks-auto-mode-cluster-by-terraform/
Terraform で Auto Mode の EKS クラスターを作成して、Pod Identity で AWS 権限を与えたアプリケーション
© Classmethod, Inc. All rights reserved.
dev.classmethod.jp
이번 포스팅은 EKS Auto Mode에서 Pod Identity를 활용하는 실습을 해봅니다.
Pod Identity란?
지난번 포스팅에서 제가 pod identity와 IRSA에 대해 비교한 내용이 있으니 여기서 자세하게 알아볼 수 있습니다.
https://devops-james.tistory.com/511
[AEWS-3기][6주차-도전과제-2][EKS Workshop] EKS Pod Identity
이번 블로깅은 EKS의 Pod Identity에 대한 워크샵 실습을 정리하였습니다.https://www.eksworkshop.com/docs/security/amazon-eks-pod-identity/ Amazon EKS Pod Identity | EKS WorkshopManage AWS credentials for your applications running on Am
devops-james.tistory.com
IRSA와의 차이는 기본적으로 IRSA는 하나씩 annotation에 작성해야한다는 단점이 있습니다.
반면 Pod Identity를 사용하면 이를 좀 더 간단하게 구성할 수 있습니다. Pod Identity Agent를 기본적으로 설치하게 되는데 이는 Addon으로 사용이 가능합니다.
우리는 EKS Auto Mode를 사용하면 일단 기본적으로 Add-on이 자동으로 관리되는 것을 이미 알고있기 때문에 사실상 바로 사용이 가능하다는 장점이 있습니다.
EKS 콘솔에서도 이미 설치되어있다고 합니다.
따라서 사실상 그냥 이게 잘 존재해서 작동하는지 확인하는 실습이 되겠습니다.
전체 코드는 https://github.com/masutaro99/eks-auto-mode-sample 해당 사이트에서 확인하시기 바랍니다.
ECR 생성
애플리케이션을 담을 ECR을 생성합니다.
resource "aws_ecr_repository" "fastapi_app" {
name = "fastapi-app"
}
애플리케이션 생성
샘플 애플리케이션은 파이썬 기반의 간단한 fast api를 만드는 것입니다.
dynamodb에 요청을 날리는 역할을 합니다.
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install boto3 fastapi uvicorn
COPY . .
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8080"]
# main.py
from fastapi import FastAPI
import boto3
app = FastAPI()
@app.get("/")
def read_root():
dynamodb = boto3.client("dynamodb", region_name="ap-northeast-2")
response = dynamodb.scan(
TableName="test-dynamodb",
)
return response["Items"]
이 둘을 작성하고 docker build를 실시합니다.
docker build -t fastapi-app .
태그를 변경하고, 푸시합니다.
docker tag fastapi-app:latest <account-id>.dkr.ecr.ap-northeast-2.amazonaws.com/fastapi-app:latest
docker push <account-id>.dkr.ecr.ap-northeast-2.amazonaws.com/fastapi-app:latest
DynamoDB와 IAM Role 생성
resource "aws_dynamodb_table" "test-table" {
name = "test-dynamodb"
billing_mode = "PAY_PER_REQUEST"
hash_key = "UserId"
attribute {
name = "UserId"
type = "S"
}
}
data "aws_iam_policy_document" "allow_pod_identity" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["pods.eks.amazonaws.com"]
}
actions = [
"sts:AssumeRole",
"sts:TagSession"
]
}
}
resource "aws_iam_role" "read_dynamodb" {
name = "read-dynamodb-role"
assume_role_policy = data.aws_iam_policy_document.allow_pod_identity.json
}
resource "aws_iam_role_policy_attachment" "read_dynamodb" {
role = aws_iam_role.read_dynamodb.name
policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess"
}
resource "aws_eks_pod_identity_association" "read_dynamodb" {
cluster_name = module.eks.cluster_name
namespace = "app"
service_account = "app-sa"
role_arn = aws_iam_role.read_dynamodb.arn
}
Pod Identity 연결까지 반영된 것을 확인해봅니다.
EKS 매니패스트 생성
apiVersion: v1
kind: Namespace
metadata:
name: app
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: app
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app
name: fastapi-app
spec:
selector:
matchLabels:
app.kubernetes.io/name: fastapi-app
replicas: 2
template:
metadata:
labels:
app.kubernetes.io/name: fastapi-app
spec:
serviceAccountName: app-sa
containers:
- image: <AccountID>.dkr.ecr.ap-northeast-2.amazonaws.com/fastapi-app:latest
imagePullPolicy: Always
name: fastapi-app
ports:
- containerPort: 8080
resources:
requests:
cpu: "0.5"
---
apiVersion: v1
kind: Service
metadata:
namespace: app
name: app-service
spec:
ports:
- port: 8080
targetPort: 8080
protocol: TCP
type: NodePort
selector:
app.kubernetes.io/name: fastapi-app
노드풀은 기본 general-purpose에서 생성되었습니다.
이제 이 애플리케이션을 외부에서 접속할 수 있게 ingress와 ingressClass를 선언하겠습니다.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
namespace: app
labels:
app.kubernetes.io/name: LoadBalancerController
name: alb
spec:
controller: eks.amazonaws.com/alb
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: app
name: app-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 8080
여기서도 사실 신기한 점은 AWS LoadBalancer Controller를 별도로 설치하지 않았는데 LB를 자동으로 생성하고 타겟을 잡는다는 점입니다.
dynamoDB에 샘플 데이터를 넣어보겠습니다.
그냥 보이는대로 다 넣었습니다.
쿼리 조회시 바로 값을 확인할 수 있었습니다.
정말 재미있는건 정말 아무런 설정을 안해도, 알아서 해준다는 점입니다.
한번 service account에 들어가 봤는데요 아무런 설정이 없이 깔끔합니다.
deployment 자체도 service account를 둔거 외에는 어떤 설정도 안보이는 것을 확인할 수 있습니다.
즉 쉽게 말해서 AWS Auto Mode는 각종 Controller부터 Addon까지 관리해준다고 볼 수 있습니다.