본문으로 건너뛰기

EKS + RDS Pistachio Blueprint

EKS + RDS Pistachio Blueprint

Pistachio 서비스 구성을 위한 EKS 클러스터와 RDS (Single Instance) 통합 배포 가이드임.

목차

플레이스홀더 목록

이 문서는 다음 설정값을 사용하여 구성됨.

플레이스홀더설명예시
pistachio리소스 접두사pista, team1
ap-southeast-1AWS 리전ap-northeast-2
1.35Kubernetes 버전1.35
t3.medium노드 인스턴스 유형t3.medium
pistachio-nodegroup-1노드그룹 이름my-nodegroup-1
team1/projectECR 리포지토리 이름my-app-repo
61203794945...ECR 이미지 URI(AWS Account ID 포함)
pistachio-dbDB 식별자my-db
adminDB 마스터 사용자admin
password1234DB 마스터 암호password1234

구성 프로세스

단계작업설명도구/서비스
1사전 준비AWS CLI, kubectl, eksctl 설치 및 자격증명 설정Terminal
2EKS 클러스터 생성VPC, 노드그룹(Private) 포함 클러스터 배포eksctl
3RDS 생성보안 그룹, 서브넷 그룹, MySQL 인스턴스 생성AWS Console / CLI
4ECR 리포지토리 구성API, Web 이미지 저장소 생성ECR
5이미지 빌드 & 푸시Dockerfile 빌드 및 ECR 이미지 푸시Docker
6Kubernetes 배포Manifest(Deployment, Service) 작성 및 적용kubectl
7서비스 점검로드밸런서 접속 및 DB 연동 확인Browser / Terminal

--- 사전 설정

도구 설치 및 설정 (kubectl, eksctl, aws CLI 등).

# kubectl 자동완성 (bash)
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k

1. EKS 클러스터 생성

eksctl을 사용하여 클러스터를 생성함.

eksctl create cluster \
--name pistachio-cluster \
--region ap-southeast-1 \
--zones ap-southeast-1a,ap-southeast-1b \
--version 1.35 \
--nodegroup-name pistachio-nodegroup-1 \
--node-type t3.medium \
--nodes 2 \
--nodes-min 1 \
--nodes-max 3 \
--managed \
--asg-access \
--with-oidc \
--node-private-networking

클러스터 접속 설정:

aws eks update-kubeconfig --region ap-southeast-1 --name pistachio-cluster

2. RDS (Single) 인스턴스 생성

단일 RDS (MySQL) 인스턴스 생성은 RDS 가이드를 참고하여 진행함. (참고: RDS 가이드 내부의 값도 환경에 맞게 변경하여 사용해야 합니다) 가이드를 따라 RDS를 생성한 후, Endpoint 주소를 확인해야 함.

DB 연결 정보 확인

# RDS 엔드포인트 확인
aws rds describe-db-instances \
--db-instance-identifier pistachio-db \
--region ap-southeast-1 \
--query "DBInstances[0].Endpoint.Address" \
--output text
# 출력된 엔드포인트 주소를 복사하여 배포 파일(deployment.yaml)에 입력함.

3. 애플리케이션 배포

Backend(FastAPI)와 Frontend(Nginx) 두 개의 컨테이너를 배포함.

예제 애플리케이션 소스

이 가이드에서 사용하는 예제 애플리케이션의 소스 코드는 다음 경로를 참고하세요: aws/BLUE_PRINT/examples/team1-project/images/fastapi-mysql

fastapi-mysql/
├── Dockerfile # Backend (FastAPI) 이미지 빌드
├── main.py # FastAPI 소스 코드
├── nginx/
│ ├── Dockerfile # Frontend (Nginx) 이미지 빌드
│ └── default.conf # Nginx 설정 (Reverse Proxy)
└── ...

ECR 연동 및 이미지 준비

# 1. 리포지토리 생성 (API & Web)
aws ecr create-repository --repository-name team1/project-api --region ap-southeast-1
aws ecr create-repository --repository-name team1/project-web --region ap-southeast-1

# 2. 이미지 빌드 및 푸시
# (주의: 123456789012 부분을 실제 AWS Account ID로 변경하여 사용하세요)

# ECR 로그인
aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com

# API 빌드 & 푸시
cd aws/BLUE_PRINT/examples/team1-project/images/fastapi-mysql
docker build -t team1/project-api .
docker tag team1/project-api:latest 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-api:latest
docker push 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-api:latest

# Web 빌드 & 푸시
cd nginx
docker build -t team1/project-web .
docker tag team1/project-web:latest 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-web:latest
docker push 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-web:latest

Kubernetes 배포 (API & Web)

1. Backend (FastAPI) 배포 Nginx가 http://fastapi:3000으로 접근하므로 Service 이름을 fastapi로 설정함.

cat <<EOF > api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
labels:
app: api
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-api:latest
ports:
- containerPort: 3000
env:
- name: DB_HOST
value: "<RDS_ENDPOINT_HERE>"
- name: DB_USER
value: "admin"
- name: DB_PASSWORD
value: "password1234"
resources:
requests:
cpu: "250m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
name: fastapi
spec:
type: ClusterIP
selector:
app: api
ports:
- port: 3000
targetPort: 3000
EOF

# (중요) 생성된 api-deployment.yaml 파일을 열어 <RDS_ENDPOINT_HERE> 부분을 실제 RDS 엔드포인트 주소로 변경함.
kubectl apply -f api-deployment.yaml

2. Frontend (Nginx) 배포 외부에서 접근할 수 있도록 LoadBalancer로 노출함.

Note: LoadBalancer 타입의 Service 생성 시, AWS Load Balancer Controller(또는 Cloud Provider)가 자동으로 필요한 보안 그룹(Security Group)을 생성하고 노드 보안 그룹을 업데이트하므로 별도의 수동 설정이 필요하지 않음.

cat <<EOF > web-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team1/project-web:latest
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80
EOF

kubectl apply -f web-deployment.yaml

4. 리소스 정리

역순으로 삭제하여 의존성 문제를 방지함.

# 1. K8s 리소스 삭제
kubectl delete service web-service
kubectl delete deployment web-deployment
kubectl delete service fastapi
kubectl delete deployment api-deployment

# 2. RDS 삭제
# [RDS 가이드](./rds_pistachio.md)의 리소스 정리 섹션을 참고하여 삭제함.

# 3. ECR 삭제
aws ecr delete-repository --repository-name team1/project-api --region ap-southeast-1 --force
aws ecr delete-repository --repository-name team1/project-web --region ap-southeast-1 --force

# 4. EKS 클러스터 삭제
eksctl delete cluster --name pistachio-cluster --region ap-southeast-1

트러블슈팅

  • RDS 연결 실패: 보안 그룹(Inbound 3306)이 VPC CIDR 또는 노드 그룹 SG를 허용하는지 확인.
  • ImagePullBackOff: 노드 역할에 ECR 읽기 권한(AmazonEC2ContainerRegistryReadOnly) 확인.
  • EIP 한도 초과: aws ec2 describe-addresses로 미사용 IP 확인 및 해제.

관련 문서

그래프 뷰

그래프 데이터 로딩 중…
현재: EKS + RDS Pistachio Blueprint
노드 클릭 → 이동 · 드래그 → 위치 조정