AWS 3-Tier 아키텍처 설계 예시: Web, App, DB 계층 분리와 운영 전략

2026. 6. 1. 07:14Cloud/AWS

반응형

"EC2 하나에 웹 서버, 애플리케이션, 데이터베이스를 모두 올려서 운영하고 있습니다. 트래픽이 늘면 어떻게 확장하죠?" — 이 질문에 대한 답이 3-Tier 아키텍처입니다.

핵심 요약

  • 3-Tier 아키텍처는 Web(프레젠테이션), App(비즈니스 로직), DB(데이터) 계층을 분리하여 각 계층을 독립적으로 확장하고 보호하는 설계 패턴입니다.
  • AWS에서는 ALB + Auto Scaling Group + RDS Multi-AZ 조합이 가장 일반적인 구현 방식입니다.
  • 각 계층을 별도 Subnet에 배치하고, Security Group으로 계층 간 통신만 허용하는 것이 보안 설계의 핵심입니다.
  • 단일 인스턴스 구성 대비 비용은 증가하지만, 장애 격리, 독립 확장, 보안 강화라는 운영 이점을 얻습니다.
  • 모든 설계 선택에는 trade-off가 있으며, 서비스 규모와 요구사항에 따라 구성을 조정해야 합니다.

1. 설계 배경과 시나리오

1.1 시나리오: 스타트업 B2B SaaS 서비스

월간 활성 사용자 5,000명 규모의 B2B SaaS 서비스를 운영한다고 가정합니다.

현재 상태: - EC2 1대에 Nginx + Spring Boot + PostgreSQL을 모두 설치 - 트래픽 증가 시 수직 확장(인스턴스 타입 변경)으로 대응 - DB 백업은 수동으로 진행

문제점: - 애플리케이션 배포 시 전체 서비스 중단 - DB 장애 시 복구까지 수 시간 소요 - 트래픽 급증 시 단일 인스턴스 한계로 서비스 지연 - 웹 서버 취약점이 DB까지 직접 영향을 줄 수 있음

1.2 설계 목표

항목 요구사항
가용성 단일 AZ 장애 시에도 서비스 유지
확장성 트래픽 증가 시 App 계층 수평 확장
보안 계층 간 최소 권한 통신, DB 인터넷 노출 차단
배포 무중단 배포 가능한 구조
비용 월 $500~$1,000 범위 내 운영

1.3 왜 3-Tier인가

단일 서버 구성과 3-Tier 구성의 차이를 정리합니다.

기준 단일 서버 3-Tier
장애 영향 범위 전체 서비스 중단 해당 계층만 영향
확장 방식 수직 확장만 가능 계층별 수평 확장
보안 격리 불가능 계층별 네트워크 분리
배포 전체 재시작 필요 계층별 독립 배포
비용 낮음 (초기) 높음 (인프라 분리 비용)
운영 복잡도 낮음 중간~높음

트래픽이 적고 장애 허용 범위가 넓은 초기 단계에서는 단일 서버가 합리적일 수 있습니다. 다만 서비스가 성장하면서 가용성, 보안, 확장성 요구가 높아지면 계층 분리가 필요합니다.

2. 전체 아키텍처 구조

AWS 3-Tier 아키텍처 전체 구조
AWS 3-Tier 아키텍처 전체 구조

3-Tier 아키텍처의 전체 구조는 다음과 같습니다.

Web Tier (Public Subnet) - ALB(Application Load Balancer)가 인터넷 트래픽을 수신 - 사용자 요청을 App Tier로 분배 - HTTPS 종료(TLS Termination) 처리

App Tier (Private Subnet) - Auto Scaling Group으로 EC2 인스턴스 관리 - 비즈니스 로직 처리 (Spring Boot, Node.js 등) - 외부 인터넷 접근 시 NAT Gateway 경유

DB Tier (Private Subnet) - RDS Multi-AZ로 고가용성 확보 - App Tier에서만 접근 가능 - 자동 백업, 스냅샷, 장애 조치(Failover) 지원

3. 네트워크 설계

AWS 3-Tier 네트워크 설계
AWS 3-Tier 네트워크 설계

3.1 VPC와 Subnet 구성

VPC CIDR: 10.0.0.0/16 (65,536 IP)

Public Subnet (Web Tier):
  - AZ-a: 10.0.1.0/24 (256 IP)
  - AZ-c: 10.0.2.0/24 (256 IP)

Private Subnet (App Tier):
  - AZ-a: 10.0.11.0/24 (256 IP)
  - AZ-c: 10.0.12.0/24 (256 IP)

Private Subnet (DB Tier):
  - AZ-a: 10.0.21.0/24 (256 IP)
  - AZ-c: 10.0.22.0/24 (256 IP)

설계 의도: - /24 서브넷은 소규모 서비스에 충분한 IP 범위를 제공합니다. 향후 확장이 필요하면 /20으로 변경할 수 있지만, 서브넷 CIDR은 생성 후 변경이 불가능하므로 초기 설계가 중요합니다. - 2개 AZ에 걸쳐 배치하여 단일 AZ 장애에 대비합니다. 3개 AZ를 사용하면 가용성은 높아지지만 비용도 비례하여 증가합니다. - 계층별로 서브넷을 분리하여 Security Group과 NACL을 계층 단위로 적용할 수 있습니다.

3.2 Route Table 설계

Public Subnet Route Table:

Destination Target 용도
10.0.0.0/16 local VPC 내부 통신
0.0.0.0/0 Internet Gateway 인터넷 인바운드/아웃바운드

Private Subnet Route Table (App/DB Tier):

Destination Target 용도
10.0.0.0/16 local VPC 내부 통신
0.0.0.0/0 NAT Gateway 아웃바운드 인터넷 (패치, API 호출)

DB Tier에 NAT Gateway가 필요한가?

DB Tier는 일반적으로 외부 인터넷 접근이 불필요합니다. RDS 관리형 서비스는 AWS가 패치를 처리하므로 NAT Gateway 없이 운영할 수 있습니다. 다만 DB에서 외부 API를 호출해야 하는 경우(예: Lambda 트리거로 외부 알림 전송)에는 NAT Gateway 또는 VPC Endpoint가 필요합니다.

3.3 NAT Gateway 배치 전략

NAT Gateway는 AZ당 1개를 배치하는 것이 고가용성 관점에서 권장됩니다.

구성 장점 단점
NAT Gateway 1개 (단일 AZ) 비용 절감 (~$45/월) 해당 AZ 장애 시 Private Subnet 전체 인터넷 차단
NAT Gateway 2개 (AZ별) AZ 장애 격리 비용 2배 (~$90/월)

비용이 제한적인 초기 단계에서는 NAT Gateway 1개로 시작하고, 서비스 안정성 요구가 높아지면 AZ별로 분리하는 것이 현실적인 접근입니다.

4. 보안 설계

AWS 3-Tier 보안 설계
AWS 3-Tier 보안 설계

4.1 Security Group 설계

3-Tier 아키텍처에서 Security Group은 계층 간 통신만 허용하는 체인 구조로 설계합니다.

ALB Security Group (sg-alb):

방향 프로토콜 포트 소스/대상 용도
Inbound TCP 443 0.0.0.0/0 HTTPS 트래픽 수신
Inbound TCP 80 0.0.0.0/0 HTTP → HTTPS 리다이렉트
Outbound TCP 8080 sg-app App Tier로 전달

App Security Group (sg-app):

방향 프로토콜 포트 소스/대상 용도
Inbound TCP 8080 sg-alb ALB에서만 트래픽 수신
Outbound TCP 5432 sg-db DB 접근
Outbound TCP 443 0.0.0.0/0 외부 API 호출 (NAT 경유)

DB Security Group (sg-db):

방향 프로토콜 포트 소스/대상 용도
Inbound TCP 5432 sg-app App Tier에서만 DB 접근
Outbound 필요 시에만 허용

핵심 원칙: Security Group의 소스를 IP 대신 다른 Security Group ID로 지정합니다. 이렇게 하면 App Tier 인스턴스가 Auto Scaling으로 추가/제거되어도 별도의 규칙 변경 없이 통신이 유지됩니다.

4.2 NACL 설계 (선택적 추가 방어)

Security Group만으로도 기본 보안은 충족되지만, 규정 준수(Compliance)나 심층 방어(Defense in Depth)가 필요한 경우 NACL을 추가합니다.

Subnet 허용 Inbound 허용 Outbound 차단
Public 80, 443 (Any) Ephemeral ports 불필요한 포트 전체
App Private 8080 (Public Subnet CIDR) 5432 (DB Subnet CIDR) 인터넷 직접 접근
DB Private 5432 (App Subnet CIDR) Ephemeral ports App 외 모든 접근

4.3 데이터 암호화

구간 방법 비고
클라이언트 → ALB TLS 1.2+ (ACM 인증서) ACM 무료, 자동 갱신
ALB → App HTTP 또는 TLS 내부 통신이므로 HTTP 허용 가능, 규정에 따라 TLS 적용
App → DB TLS (RDS SSL) rds.force_ssl 파라미터로 강제
DB 저장 데이터 AES-256 (KMS) RDS 암호화 활성화 시 자동 적용

5. 각 계층별 상세 설계

5.1 Web Tier: ALB 설계

AWS 3-Tier 트래픽 흐름
AWS 3-Tier 트래픽 흐름

ALB를 선택한 이유:

선택지 적합한 경우 이 시나리오에서의 판단
ALB HTTP/HTTPS 라우팅, 경로 기반 분배 ✅ 웹 애플리케이션에 적합
NLB TCP/UDP, 초저지연, 고정 IP 필요 ❌ L7 기능 불필요
CLB 레거시 ❌ 신규 설계에서 사용하지 않음

ALB 설정 포인트:

# Target Group 설정
Health Check:
  Path: /health
  Interval: 30s
  Healthy Threshold: 2
  Unhealthy Threshold: 3
  Timeout: 5s

# Listener Rules
- HTTPS:443 → Default: App Target Group
- HTTP:80 → Redirect to HTTPS:443

# Sticky Session
- 비활성화 (Stateless 설계 권장)
- 세션이 필요하면 ElastiCache(Redis)로 외부화

Sticky Session을 비활성화하는 이유: Sticky Session을 사용하면 특정 인스턴스에 트래픽이 집중될 수 있고, 해당 인스턴스 장애 시 세션이 유실됩니다. 세션을 Redis로 외부화하면 어떤 인스턴스가 요청을 처리해도 동일한 세션 데이터에 접근할 수 있습니다.

5.2 App Tier: Auto Scaling Group 설계

Launch Template 구성:

Instance Type: t3.medium (2 vCPU, 4GB RAM)
AMI: Amazon Linux 2023 (최신 패치 적용)
IAM Role: app-tier-role (S3 읽기, CloudWatch 쓰기, Secrets Manager 읽기)
User Data: 애플리케이션 시작 스크립트

Auto Scaling 정책:

정책 조건 동작
Scale Out CPU 평균 70% 이상 (5분) 인스턴스 1개 추가
Scale In CPU 평균 30% 이하 (10분) 인스턴스 1개 제거
최소 인스턴스 2개 (AZ별 1개)
최대 인스턴스 6개

왜 Target Tracking이 아닌 Step Scaling인가?

Target Tracking(목표 추적)은 설정이 간단하지만, 트래픽 패턴이 급격히 변하는 경우 반응이 느릴 수 있습니다. 이 시나리오에서는 B2B SaaS로 트래픽 패턴이 비교적 예측 가능하므로 Target Tracking도 적합합니다. 다만 Scale In 속도를 세밀하게 제어하고 싶다면 Step Scaling이 더 유연합니다.

배포 전략:

# Rolling Update 설정
MinInstancesInService: 1
MaxBatchSize: 1
PauseTime: PT5M
WaitOnResourceSignals: true

이 설정은 인스턴스를 1개씩 교체하면서 최소 1개는 항상 서비스 중인 상태를 유지합니다. 배포 중에도 서비스가 중단되지 않습니다.

5.3 DB Tier: RDS Multi-AZ 설계

RDS 구성:

Engine: PostgreSQL 15
Instance Class: db.t3.medium (2 vCPU, 4GB RAM)
Storage: gp3, 100GB, 3000 IOPS
Multi-AZ: Enabled (Standby in AZ-c)
Backup:
  Retention: 7일
  Window: 03:00-04:00 UTC (한국 시간 12:00-13:00)
Encryption: AES-256 (AWS KMS)

Multi-AZ 동작 방식: - Primary 인스턴스(AZ-a)와 Standby 인스턴스(AZ-c)가 동기식으로 복제됩니다. - Primary 장애 시 자동으로 Standby가 승격됩니다 (일반적으로 60~120초). - 애플리케이션은 RDS Endpoint(DNS)를 사용하므로 Failover 시 코드 변경이 불필요합니다.

Read Replica를 추가해야 하는 시점: - 읽기 트래픽이 전체의 80% 이상일 때 - 리포트/분석 쿼리가 운영 DB 성능에 영향을 줄 때 - 이 시나리오(5,000 MAU)에서는 아직 불필요합니다. 트래픽이 10배 이상 증가하면 검토합니다.

6. 고가용성과 장애 대응

6.1 장애 시나리오별 대응

장애 시나리오 영향 범위 자동 복구 복구 시간
App 인스턴스 1개 장애 없음 (ALB가 제외) ✅ Health Check → 새 인스턴스 2~5분
AZ-a 전체 장애 용량 50% 감소 ✅ AZ-c에서 계속 서비스 즉시
RDS Primary 장애 DB 일시 중단 ✅ Multi-AZ Failover 60~120초
ALB 장애 서비스 전체 중단 ✅ AWS 관리형 (자동 복구) 수 초
NAT Gateway 장애 App 외부 통신 차단 ❌ AZ별 NAT 필요 수동 전환 필요

6.2 모니터링 설계

각 계층에서 감시해야 할 핵심 메트릭:

Web Tier (ALB): - HTTPCode_Target_5XX_Count: App 서버 오류 감지 - TargetResponseTime: 응답 지연 감지 - HealthyHostCount: 정상 인스턴스 수

App Tier (EC2/ASG): - CPUUtilization: Auto Scaling 트리거 - MemoryUtilization: CloudWatch Agent 필요 - StatusCheckFailed: 인스턴스 하드웨어 장애

DB Tier (RDS): - DatabaseConnections: 커넥션 풀 고갈 감지 - FreeStorageSpace: 디스크 부족 사전 경고 - ReadLatency / WriteLatency: 쿼리 성능 저하

7. 비용 분석

7.1 월간 예상 비용 (서울 리전 기준)

리소스 사양 월 예상 비용
ALB 1개 ~$18 + LCU 비용
EC2 (App) t3.medium × 2 ~$76
RDS Multi-AZ db.t3.medium (PostgreSQL) ~$105
NAT Gateway 1개 ~$33 + 데이터 처리 비용
EBS (gp3) 20GB × 2 (App) + 100GB (RDS 포함) ~$15
Data Transfer 월 100GB 가정 ~$10
합계   ~$260~$350/월

비용은 서울 리전(ap-northeast-2) 기준 On-Demand 가격이며, 트래픽 규모와 LCU 사용량에 따라 변동됩니다. 정확한 견적은 AWS Pricing Calculator로 확인할 수 있습니다.

7.2 비용 최적화 옵션

방법 절감 효과 적용 조건
Reserved Instance (1년) EC2 ~40%, RDS ~40% 12개월 이상 운영 확정 시
Savings Plan EC2 ~30% 사용량 예측 가능 시
NAT Gateway → VPC Endpoint NAT 비용 제거 AWS 서비스만 접근하는 경우
Graviton 인스턴스 (t4g) ~20% 절감 ARM 호환 애플리케이션
단일 NAT Gateway ~$45 절감 가용성 요구가 낮은 경우

비용 vs 가용성 trade-off:

이 시나리오에서 가장 큰 비용 항목은 RDS Multi-AZ입니다. Single-AZ로 변경하면 약 $70/월을 절감할 수 있지만, DB 장애 시 복구에 수십 분이 소요될 수 있습니다. B2B SaaS에서 업무 시간 중 DB 장애는 고객 이탈로 이어질 수 있으므로, Multi-AZ 비용은 보험으로 간주하는 것이 일반적입니다.

8. 확장 시 고려사항

8.1 트래픽 10배 증가 시

서비스가 성장하여 MAU 50,000명 규모가 되면 다음을 검토합니다.

영역 현재 확장 방안
App Tier t3.medium × 2~6 c6g.large × 4~12 + Graviton 전환
DB db.t3.medium Single Writer db.r6g.large + Read Replica 2개
캐시 없음 ElastiCache Redis (세션 + 쿼리 캐시)
CDN 없음 CloudFront (정적 자산 오프로드)
NAT 1개 AZ별 1개 (고가용성)

8.2 마이크로서비스 전환 시

3-Tier 아키텍처는 모놀리식 애플리케이션에 적합한 구조입니다. 서비스가 더 커지면 다음 단계를 고려할 수 있습니다.

  • ECS/EKS 전환: App Tier를 컨테이너 기반으로 변경하여 서비스별 독립 배포
  • API Gateway 추가: 서비스 간 라우팅, 인증, Rate Limiting 중앙화
  • 서비스별 DB 분리: 각 마이크로서비스가 자체 데이터 저장소를 소유

다만 마이크로서비스 전환은 조직 규모와 개발 속도가 뒷받침되어야 합니다. 5~10명 규모의 팀에서는 3-Tier 모놀리식이 오히려 생산성이 높을 수 있습니다.

9. 설계 체크리스트

네트워크

  • [ ] VPC CIDR이 향후 확장을 고려한 크기인가
  • [ ] 최소 2개 AZ에 걸쳐 서브넷을 배치했는가
  • [ ] DB Subnet은 인터넷 접근이 차단되어 있는가
  • [ ] Route Table이 계층별로 분리되어 있는가

보안

  • [ ] Security Group이 계층 간 체인 구조로 설계되었는가
  • [ ] DB는 App Tier에서만 접근 가능한가
  • [ ] HTTPS가 강제되고 있는가 (HTTP → HTTPS 리다이렉트)
  • [ ] RDS 암호화가 활성화되어 있는가
  • [ ] IAM Role이 최소 권한으로 설정되어 있는가

가용성

  • [ ] ALB가 Multi-AZ로 배포되어 있는가
  • [ ] Auto Scaling 최소 인스턴스가 2개 이상인가
  • [ ] RDS Multi-AZ가 활성화되어 있는가
  • [ ] Health Check가 적절히 설정되어 있는가

운영

  • [ ] CloudWatch 알람이 핵심 메트릭에 설정되어 있는가
  • [ ] 자동 백업이 활성화되어 있는가
  • [ ] 배포 파이프라인이 무중단 배포를 지원하는가
  • [ ] 로그가 중앙 집중화되어 있는가 (CloudWatch Logs)

10. 정리

3-Tier 아키텍처는 웹 서비스의 가장 기본적이면서도 실무에서 가장 많이 사용되는 설계 패턴입니다.

이 설계가 적합한 경우: - 모놀리식 웹 애플리케이션을 운영하는 경우 - 팀 규모가 5~15명이고, 인프라 복잡도를 낮추고 싶은 경우 - 가용성과 보안 요구가 있지만, 마이크로서비스까지는 불필요한 경우

이 설계가 부적합한 경우: - 서비스별 독립 배포와 확장이 필요한 대규모 시스템 - 이벤트 드리븐 아키텍처가 필요한 경우 - 서버리스 우선 전략을 채택한 경우

핵심은 "계층을 분리하는 것 자체"가 아니라, 각 계층을 독립적으로 확장하고, 장애를 격리하고, 보안 경계를 명확히 하는 것입니다. 이 원칙을 이해하면 3-Tier를 넘어 어떤 아키텍처를 설계하든 동일한 사고 방식을 적용할 수 있습니다.

관련 글

반응형