본문으로 건너뛰기

EKS + RDS Blueprint

EKS + RDS Blueprint

EKS 클러스터와 RDS (Single Instance) 통합 배포를 위한 일반화된 가이드임.

목차

플레이스홀더 목록

이 문서를 사용하기 전에 다음 플레이스홀더를 실제 값으로 치환하여 사용함.

플레이스홀더설명예시
<REGION>AWS 리전ap-northeast-2
<ACCOUNT_ID>AWS 계정 ID123456789012
<CLUSTER_NAME>EKS 클러스터 이름my-cluster
<K8S_VERSION>Kubernetes 버전1.35
<NODE_TYPE>노드 인스턴스 유형t3.medium
<NODEGROUP_NAME>노드그룹 이름my-nodegroup-1
<ECR_REPO_API>ECR 리포지토리 이름 (API)my-project/api
<ECR_REPO_WEB>ECR 리포지토리 이름 (Web)my-project/web
<DB_ID>DB 식별자my-db
<DB_USER>DB 마스터 사용자admin
<DB_PASSWORD>DB 마스터 암호my-secret-password

구성 프로세스

단계작업설명도구/서비스
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 <CLUSTER_NAME> \
--region <REGION> \
--zones <REGION>a,<REGION>b \
--version <K8S_VERSION> \
--nodegroup-name <NODEGROUP_NAME> \
--node-type <NODE_TYPE> \
--nodes 2 \
--nodes-min 1 \
--nodes-max 3 \
--managed \
--asg-access \
--with-oidc \
--node-private-networking

클러스터 접속 설정:

aws eks update-kubeconfig --region <REGION> --name <CLUSTER_NAME>

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

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

DB 연결 정보 확인

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

3. 애플리케이션 배포

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

예제 애플리케이션 소스

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

ECR 연동 및 이미지 준비

# 1. 리포지토리 생성 (API & Web)
aws ecr create-repository --repository-name <ECR_REPO_API> --region <REGION>
aws ecr create-repository --repository-name <ECR_REPO_WEB> --region <REGION>

# 2. 이미지 빌드 및 푸시

# ECR 로그인
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com

# API 빌드 & 푸시
cd aws/BLUE_PRINT/examples/team1-project/images/fastapi-mysql
docker build -t <ECR_REPO_API> .
docker tag <ECR_REPO_API>:latest <ECR_URI_API>
docker push <ECR_URI_API>

# Web 빌드 & 푸시
cd nginx
docker build -t <ECR_REPO_WEB> .
docker tag <ECR_REPO_WEB>:latest <ECR_URI_WEB>
docker push <ECR_URI_WEB>

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: <ECR_URI_API>
ports:
- containerPort: 3000
env:
- name: DB_HOST
value: "<RDS_ENDPOINT_HERE>"
- name: DB_USER
value: "<DB_USER>"
- name: DB_PASSWORD
value: "<DB_PASSWORD>"
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: <ECR_URI_WEB>
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 <ECR_REPO_API> --region <REGION> --force
aws ecr delete-repository --repository-name <ECR_REPO_WEB> --region <REGION> --force

# 4. EKS 클러스터 삭제
eksctl delete cluster --name <CLUSTER_NAME> --region <REGION>

트러블슈팅

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

관련 문서

그래프 뷰

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