본문 바로가기
카테고리 없음

[AEWS-3기][7주차 도전과제] Pod Identity에서 AWS 권한을 부여한 파드(애플리케이션)을 배포

by james_janghun 2025. 3. 23.

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까지 관리해준다고 볼 수 있습니다.