Search

CINEBOX

Subject
영화 예매 서비스
Key Tech
AWS
Terraform
EKS
GitHub Actions
ArgoCD
Kustomize
Prometheus
Grafana
Loki
CloudFront
Description
AWS EKS 기반 서비스 운영 환경에서 네트워크 경계, 데이터 계층, 비용 최적화, 배포 재현성, 장애 추적 기반을 정리한 프로젝트
Role: BE, Infra & DevOps Lead — 백엔드 개발 | 아키텍처 설계 | 인프라 구축 | CI/CD | 모니터링 Period: 2025.02 – 2025.03 Team: 4인 Link: [GitHub]

1. 프로젝트 소개

CINEBOX는 실시간 좌석 점유와 예매가 발생하는 영화 예매 서비스를 가정하고 구축한 프로젝트입니다.
서비스 특성을 판단하고 그에 맞는 AWS 기반 클라우드 인프라 구조를 설계하고, 운영 중 발생할 수 있는 환경 차이와 장애 원인을 추적 가능한 구조를 만드는 것을 집중했습니다.
영화 목록, 상영 정보, 좌석 상태 확인과 같은 조회성 요청이 많을 것으로 예상했고, 이에 따라 데이터 계층과 정적 리소스 제공 구조를 별도로 고려했습니다. 또한 부트캠프 프로젝트 특성상 비용 제약이 있었기 때문에, 가용성과 비용 사이의 Trade-off를 고려하며 인프라를 구성했습니다.

2. 어떤 AWS 아키텍처를 설계했는가 — Architecture Overview

CINEBOX는 AWS EKS를 중심으로 애플리케이션 실행 환경을 구성하고, 데이터베이스, 캐시, 정적 리소스 제공 영역을 역할별로 분리했습니다.
[이미지 1] CINEBOX 아키텍처
전채 구조는 다음과 같이 설계했습니다:
컴퓨팅: EKS (Kubernetes 기반 컨테이너 오케스트레이션)
네트워크: VPC Public/Private Subnet 분리
데이터: RDS MySQL Primary + Read Replica, ElastiCache Redis
CDN: CloudFront + S3 (이미지 캐싱
IaC: Terraform
CI/CD: GitHub Actions, ArgoCD GitOps
모니터링: Prometheus, Grafana, Loki
애플리케이션 워크로드는 EKS에서 실행되며, 데이터 계층은 외부에서 직접 접근할 수 없도록 Private 영역에 배치했습니다. 이미지 조회와 같은 정적 리소스 요청은 S3에 직접 접근시키기보다 CloudFront를 앞단에 두어 캐싱과 응답 속도 개선을 함께 고려했습니다.
이 구조를 통해 애플리케이션 계층, 데이터 계층, 정적 리소스 제공 계층을 분리하고, 각 리소스의 역할을 명확히 나누고자 했습니다.

3. 네트워크와 접근 경계를 어떻게 나눴는가 — Network & Access Design

VPC Public / Private 서브넷 분리

VPC를 Public/Private 서브넷으로 나누고, 외부 접근이 필요한 리소스와 내부에서만 사용되는 리소스를 구분했습니다.
Public Subnet — 외부 진입 지점과 Bastion, NAT Instance 등 인터넷 연결이 필요한 리소스 배치
Private Subnet — WAS, 모니터링, RDS, ElastiCache 등 애플리케이션 실행 및 데이터 계층 리소스 배치
이 구조를 통해 외부 요청을 처리하는 영역과 내부 애플리케이션, 데이터 계층을 분리했습니다. 특히 데이터 계층은 외부에서 직접 접근할 수 없도록 Private 영역에 배치하고, 필요한 경로를 통해서만 접근할 수 있도록 구성했습니다.

보안 그룹 계층화

외부 요청이 내부 데이터 계층까지 직접 도달하지 않도록, ALB → EKS Node → RDS/ElastiCache 순서로 허용 트래픽을 명시적으로 제한했습니다.
보안 그룹은 CIDR을 직접 지정하는 것 대신 보안 그룹 참조 방식을 적용해 IP 변경에 덜 민감하고 허용 관계를 계층별로 명시적으로 드러낼 수 있는 구조로 설계했습니다.

Taint + nodeAffinity 기반 워크로드 배치 분리

Public/Private 서브넷 분리에 맞게 각 워크로드가 역할에 맞는 노드에 스케줄링되도록 Taint와 nodeAffinity를 적용했습니다.
Web Server → Public 영역 노드
WAS ∙ Monitoring → Private 영역 노드
이 구조를 통해 외부 노출이 필요한 컴포넌트와 내부에서만 동작해야 하는 컴포넌트의 배치 기준을 분리했습니다.

Bastion EC2 기반 접근 제어

Private Subnet의 EKS 노드와 RDS에 대한 운영 접근은 Public Subnet의 Bastion EC2를 통해서만 가능하도록 제한했습니다. 이를 통해 내부 리소스가 외부에서 직접 접근되는 경로를 차단하고, 운영 접근 지점을 Bastion으로 일원화했습니다.
Bastion 역시 외부에서 접근 가능한 진입점이므로, Security Group을 통해 필요한 포트와 접근 대상을 최소화했습니다.

4. 데이터 계층을 어떻게 설계하고 운영 지표로 검증했는가 — Data Layer & Observability

RDS Primary / Read Replica 분리

영화 예매 서비스에서는 예매∙결제 같은 쓰기 요청보다 영화 목록 조회, 상영 정보 조회, 좌석 상태 확인 등의 조회 요청이 많을 것으로 예상했습니다. 이를 바탕으로 데이터 계층은 단일 DB에 모든 요청을 집중시키기보다, 조회 트래픽을 분산할 수 있는 구조를 고려했습니다.
Primary DB — 예매, 결제, 사용자 정보 변경 등 쓰기 요청 처리
Read Replica — 영화 목록, 상영 정보 등 조회성 API 요청 처리

ElastiCache Redis

Redis는 사용자 세션 저장소로 사용했습니다. 애플리케이션 인스턴스가 늘어나도 세션 상태가 특정 Pod 내부에 종속되지 않도록 외부 세션 저장소를 두는 방향으로 구성했습니다.

운영 지표 기반 설계 타당성 검증

Prometheus, Grafana, Loki를 활용해 인프라와 애플리케이션 상태를 함께 확인할 수 있는 관측 체계를 구성했습니다.
구분
구성
Metric
Prometheus → Grafana
Log
Promtail → Loki → Grafana
 수집 지표
CPU, Memory, Disk I/O 등 시스템 메트릭
HTTP 응답 시간 및 상태값
Method별 요청 빈도
도메인별 요청 패턴
로그 레벨별 애플리케이션 로그
[이미지 2] Node Metrics
[이미지 3] Application Metrics
[이미지 4] Application Logs
영화 예매 서비스는 예매∙결제와 같은 쓰기 요청도 존재하지만, 영화 목록 조회, 상영 정보 조회, 좌석 상태 확인처럼 조회성 요청이 더 자주 발생할 것으로 예상했습니다. 이를 바탕으로 RDS Read Replica를 분리해 조회 트래픽을 Replica에서 처리하도록 설계했습니다.
이후 모니터링을 통해 movie 도메인의 GET 요청이 트래픽이 집중되는 흐름을 확인할 수 있었습니다. 모니터링을 통해 설계 결정의 타당성을 확인하는 수단으로 기능한 경험이었습니다.

5. 비용과 성능을 어떻게 최적화했는가 — Cost & Performance Optimization

NAT Instance

Private Subnet의 리소스가 외부로 나가기 위한 NAT 구성이 필요했지만, NAT Gateway는 프로젝트 규모 대비 비용 부담이 크다고 판단했습니다. 따라서 NAT Gateway 대신 NAT Instance를 선택했습니다.
NAT Instance는 단일 장애 지점이 될 수 있으며, 직접 관리해야 한다는 부담이 있다는 Trade-off가 있지만 트래픽이 크지 않은 프로젝트라는 점과 비용 제약을 고려해 NAT Instance가 더 적절하다고 판단했습니다.

S3 Gateway Endpoint

Private Subnet에서 S3로 접근하는 트래픽은 NAT를 거치지 않도록 S3 Gateway Endpoint를 구성했습니다. 이를 통해 S3 접근 트래픽이 NAT Instance를 경유하지 않기 때문에 다음과 같은 효과를 기대할 수 있었습니다.
NAT 경유 트래픽 감소
S3 접근 비용 절감
외부 노출 경로 최소화

CloudFront + S3

영화 서비스에서는 포스터 이미지와 같은 정적 리소스 조회가 빈번할 수 있다고 보았습니다. 따라서 S3에 직접 접근시키는 방식보다 CloudFront를 통한 엣지 캐싱을 통해 이미지 조회 응답 속도를 개선하고 S3에 대한 직접 요청을 줄이는 설계를 했습니다.
엣지 캐싱으로 이미지 조회 응답속도 개선
S3 요청 횟수 감소로 트래픽 비용 절감

6. 인프라와 배포 환경을 어떻게 재현 가능하게 만들었는가 — Terraform IaC & GitOps

Terraform 기반 인프라 코드화

클라우드 인프라를 안정적으로 운영하기 위해 콘솔로의 직접 구성에 의존하지 않고, Terraform을 통해 코드화했습니다. 또한 AWS 리소스에 대한 제한이 있어 자주 Destroy/Recreate해야 했기 때문에 동일 환경을 반복적으로 재구성할 수 있도록 코드화했습니다.
cinebox-terraform/ ├── vpc.tf # VPC, Subnet, Routing Table, NAT ├── eks.tf # EKS Cluster, Node Group ├── rds.tf # RDS MySQL, Read Replica ├── elasticache.tf # ElastiCache Redis ├── bastion.tf # Bastion EC2 ├── variables.tf ├── outputs.tf └── provider.tf
Plain Text
복사

Kustomize 기반 환경 분리

애플리케이션의 배포 환경은 Dev와 Prod 환경으로 구분하고, 서로의 설정 충돌을 줄이기 위해 Kustomize의 Base/Overlay 구조를 사용했습니다.
k8s-manifests/ ├── base/ # 공통 리소스 정의 └── overlays/ ├── dev/ # Dev 환경 설정 └── prod/ # Prod 환경 설정
Plain Text
복사
Base에는 공통 리소스를 정의하고, Overlay에는 환경별 설정만 덮어쓰도록 구성했습니다. 이를 통해 Dev와 Prod 간 설정 충돌을 줄이고 환경별 차이를 명확히 나눌 수 있었습니다.

GitHub Actions + ArgoCD 역할 분리

CI와 CD의 책임을 분리했습니다.
GitHub Actions: 이미지 빌드, 테스트, ECR Push, Manifest 버전 업데이트
ArgoCD: Git 저장소 변경 감지, Kubernetes 리소스 동기화, 배포 상태 수렴
이를 통해 클러스터에 직접 변경을 반영하는 지점을 줄이고, Git 상태를 기준으로 동일한 배포 상태를 반복적으로 재현할 수 있도록 설계했습니다.

7. 장애를 어떻게 추적해 해결했는가 — RCA

Issue. CoreDNS Taint 충돌로 인한 RDS 연결 실패

 상황
애플리케이션 Pod가 RDS와 연결하지 못하고 CrashLoopBackOff 상태가 반복되는 문제가 발생했습니다.
 원인 추적
문제를 단계적으로 좁혀갔습니다.
1.
RDS 설정, Security Group, 환경변수 확인 → 설정상 문제 발견되지 않음
2.
endpoint 기반 연결 실패에 주목 → DNS 해석 문제 의심
3.
CoreDNS Pod 상태 확인 → Pending 상태 발견
4.
노드 Taint와 CoreDNS Toleration 확인 → 모든 노드에 Taint 적용, CoreDNS에는 해당 Taint에 대한 Toleration이 없음
결과적으로 애플리케이션과 RDS의 직접적인 설정 문제가 아닌, 클러스터 내부의 CoreDNS가 스케줄링되지 못한 것이 원인이었습니다.
 해결
CoreDNS Deployment에 필요한 tolerations를 추가해 CoreDNS가 노드에 정상 스케줄링될 수 있도록 수정했습니다. 이후 애플리케이션과 RDS 간 연결이 정상화되었습니다.
AWS 리소스만의 문제가 아닌 Kubernetes 컴포넌트의 가용성도 함께 확인해야 한다는 점을 배웠습니다.

8. 어떤 결과를 만들었는가

서비스 특성에 맞는 데이터 계층과 정적 리소스 제공 구조를 설계하고, 비용과 성능 사이의 Trade-off를 고려하며, 장애가 발생했을 때 애플리케이션·네트워크·클러스터 레이어를 순서대로 확인하는 과정이 안정적인 클라우드 운영 환경을 만드는 데 중요하다고 생각하게 되었습니다.
영역
결과
AWS 아키텍처
EKS 기반 서비스 실행 환경 구성
네트워크 경계
Public / Private Subnet 분리 및 접근 제어
데이터 계층
RDS Primary / Read Replica, Redis 세션 저장소 구성
설계 검증
모니터링으로 조회 중심 트래픽 패턴 확인
성능 최적화
CloudFront + S3 기반 이미지 조회 성능 개선
비용 최적화
NAT Instance, S3 Gateway Endpoint 활용
인프라 재현성
Terraform 기반 AWS 리소스 코드화
배포 재현성
Kustomize + ArgoCD 기반 Dev/Prod 환경 분리
장애 대응
CoreDNS Taint 충돌 원인 규명 및 RDS 연결 장애 해소