EKS + RDS Pistachio Blueprint
EKS + RDS Pistachio Blueprint
Pistachio 서비스 구성을 위한 EKS 클러스터와 RDS (Single Instance) 통합 배포 가이드임.
목차
플레이스홀더 목록
이 문서는 다음 설정값을 사용하여 구성됨.
| 플레이스홀더 | 설명 | 예시 |
|---|---|---|
pistachio | 리소스 접두사 | pista, team1 |
ap-southeast-1 | AWS 리전 | ap-northeast-2 |
1.35 | Kubernetes 버전 | 1.35 |
t3.medium | 노드 인스턴스 유형 | t3.medium |
pistachio-nodegroup-1 | 노드그룹 이름 | my-nodegroup-1 |
team1/project | ECR 리포지토리 이름 | my-app-repo |
61203794945... | ECR 이미지 URI | (AWS Account ID 포함) |
pistachio-db | DB 식별자 | my-db |
admin | DB 마스터 사용자 | admin |
password1234 | DB 마스터 암호 | password1234 |
구성 프로세스
| 단계 | 작업 | 설명 | 도구/서비스 |
|---|---|---|---|
| 1 | 사전 준비 | AWS CLI, kubectl, eksctl 설치 및 자격증명 설정 | Terminal |
| 2 | EKS 클러스터 생성 | VPC, 노드그룹(Private) 포함 클러스터 배포 | eksctl |
| 3 | RDS 생성 | 보안 그룹, 서브넷 그룹, MySQL 인스턴스 생성 | AWS Console / CLI |
| 4 | ECR 리포지토리 구성 | API, Web 이미지 저장소 생성 | ECR |
| 5 | 이미지 빌드 & 푸시 | Dockerfile 빌드 및 ECR 이미지 푸시 | Docker |
| 6 | Kubernetes 배포 | 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 확인 및 해제.