온프렘에서는 물리 스위치와 VLAN으로 네트워크를 구성한다. AWS에서는 VPC가 그 역할을 한다. VPC는 클라우드 위에 소프트웨어로 만든 사설 네트워크다. 내 계정 안에서만 존재하고, 다른 계정의 VPC와는 기본적으로 완전히 격리된다.
구성 요소
CIDR 블록
VPC를 만들 때 IP 주소 범위를 지정한다. 이 범위 안에서 서브넷을 나눈다.
VPC CIDR: 10.0.0.0/16 (65,536개 주소)
나중에 VPC CIDR을 바꾸는 것은 어렵다. 처음부터 넉넉하게 /16으로 잡는다.
서브넷
VPC를 더 작은 구역으로 나눈 것이다. 서브넷은 특정 가용 영역(AZ) 에 속한다.
public subnet AZ-a: 10.0.1.0/24 ← 인터넷 직접 접근 가능
public subnet AZ-b: 10.0.2.0/24
private subnet AZ-a: 10.0.11.0/24 ← 인터넷 직접 접근 불가
private subnet AZ-b: 10.0.12.0/24
public 서브넷: Internet Gateway로 향하는 라우팅이 있고, 인스턴스에 공인 IP를 직접 할당할 수 있다. 로드밸런서, NAT Gateway, Bastion Host를 여기 둔다.
private 서브넷: Internet Gateway 라우팅이 없다. 외부에서 직접 접근할 수 없다. 앱 서버, DB, 캐시처럼 외부에 노출하지 않아야 하는 것들을 여기 둔다.
Internet Gateway (IGW)
VPC와 인터넷 사이의 관문이다. VPC 당 하나 붙인다. IGW가 없으면 public 서브넷이어도 인터넷과 통신할 수 없다.
라우팅 테이블
서브넷마다 라우팅 테이블이 붙는다. 패킷의 목적지 IP에 따라 어디로 보낼지 결정한다.
# public 서브넷 라우팅 테이블
목적지 다음 홉
10.0.0.0/16 local ← VPC 내부는 직접 통신
0.0.0.0/0 igw-xxxxx ← 그 외 모든 트래픽은 인터넷 게이트웨이로
# private 서브넷 라우팅 테이블
목적지 다음 홉
10.0.0.0/16 local
0.0.0.0/0 nat-xxxxx ← 아웃바운드는 NAT Gateway로 (인바운드는 불가)
가장 구체적인 경로가 우선 적용된다. 10.0.0.0/16이 0.0.0.0/0보다 더 구체적이므로 VPC 내부 트래픽은 local로 처리된다.
실무 설계 패턴
3-tier 아키텍처
인터넷
↓
[ALB — public 서브넷]
↓
[앱 서버 — private 서브넷]
↓
[DB — private 서브넷 (DB 전용)]
DB 서브넷은 앱 서버 서브넷과도 분리해 별도 라우팅 테이블을 쓰는 경우가 많다. DB는 앱 서버에서만 접근 가능하게 Security Group으로 제한한다.
멀티 AZ
AZ가 하나면 그 AZ에 장애가 생기면 전체가 내려간다. 서브넷을 최소 2개 AZ에 걸쳐 만들고, 로드밸런서와 Auto Scaling Group을 멀티 AZ로 구성한다.
AZ-a: public(10.0.1.0/24) + private(10.0.11.0/24)
AZ-b: public(10.0.2.0/24) + private(10.0.12.0/24)
AZ-c: public(10.0.3.0/24) + private(10.0.13.0/24) ← 선택
NAT Gateway도 AZ마다 하나씩 만들어야 한다. NAT Gateway 하나를 다른 AZ 서브넷이 공유하면, NAT Gateway가 있는 AZ가 죽으면 다른 AZ도 아웃바운드가 끊긴다. 비용이 두세 배 들지만 고가용성 요구사항이 있다면 필수다.
트레이드오프
VPC는 리전 단위다. 서울 리전 VPC와 도쿄 리전 VPC는 기본적으로 격리돼 있다. 리전 간 통신은 VPC Peering이나 Transit Gateway로 연결해야 하고, 이 트래픽은 공인 인터넷을 타지 않는 AWS 백본을 통과하지만 추가 비용이 발생한다.
서브넷 CIDR은 한 번 정하면 변경이 불가능하다. 줄이거나 바꾸려면 서브넷을 삭제하고 다시 만들어야 한다. 실수로 너무 작게 잡으면 IP 부족으로 인스턴스를 추가하지 못하는 상황이 생긴다.