EKS + RDS Blueprint
EKS + RDS Blueprint
EKS 클러스터와 RDS (Single Instance) 통합 배포를 위한 일반화된 가이드임.
목차
플레이스홀더 목록
이 문서를 사용하기 전에 다음 플레이스홀더를 실제 값으로 치환하여 사용함.
| 플레이스홀더 | 설명 | 예시 |
|---|---|---|
<REGION> | AWS 리전 | ap-northeast-2 |
<ACCOUNT_ID> | AWS 계정 ID | 123456789012 |
<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 |
| 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 <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 확인 및 해제.