VPC와 Subnet, Security Group의 실무 감각
AWS 네트워크의 기본 단위인 VPC, Subnet, Security Group을 CIDR 설계, 라우팅, 상태 추적, NAT와 Endpoint 관점에서 정리한다. 통신 장애와 비용 문제를 실제 운영에서 어떻게 좁혀 볼지 함께 다룬다.
Script Companion
오디오와 함께 스크립트 보기
- 01
AWS에서 EC2, ECS, RDS 같은 리소스는 모두 VPC 안에 놓인다. 그래서 VPC를 모르면 서버끼리 왜 통신하지 못하는지, 외부에서 왜 접속되지 않는지, 보안 설정이 어디서 막히는지 추적하기 어렵다. 큰 그림은 단순하다. VPC는 AWS 안에 만든 격리된 가상 네트워크이고, Subnet은 그 안을 더 작은 구역으로 나눈 것이며, Security Group은 각 리소스에 붙는 가상 방화벽이다.
- 02
VPC를 만들 때 가장 먼저 조심할 부분은 IP 주소 범위인 CIDR이다. 하나의 VPC는 하나의 CIDR을 가지며, 예를 들어 10.0.0.0/16은 10.0.x.x 범위를 쓰겠다는 뜻이다. VPC CIDR은 생성 후 변경할 수 없고, Secondary CIDR 추가는 가능하지만 번거롭다. 그래서 문서는 VPC는 /16처럼 넉넉하게 잡고, Subnet은 /24를 기본 패턴으로 보며, 전체 CIDR의 50퍼센트는 새로운 AZ, 신규 서비스, VPC Peering 확장을 위해 남겨 두라고 설명한다.
- 03
특히 ECS와 Fargate를 쓰면 CIDR 여유가 바로 운영 문제로 이어진다. awsvpc 모드에서는 Task마다 별도 ENI와 Private IP가 할당된다. Task 100개를 운영하면 Subnet에서 IP 100개를 소비한다는 뜻이다. 그래서 /27처럼 작은 Subnet은 금방 부족해질 수 있고, /24의 실제 사용 가능 IP 251개라는 기준이 실무적으로 의미를 갖는다. 네트워크 설계는 처음에는 넉넉해 보여도, Task 수와 AZ 확장 앞에서는 빠르게 좁아질 수 있다.
- 04
Public Subnet과 Private Subnet의 차이는 Security Group이 아니라 Route Table에 있다. Public Subnet은 Route Table에 0.0.0.0/0에서 IGW로 가는 경로가 있어서 인터넷과 직접 통신할 수 있다. Private Subnet은 IGW 경로가 없어 인터넷에서 직접 접근되지 않으며, DB나 내부 서비스가 여기에 놓인다. Private Subnet에서 외부로 나가야 하면 0.0.0.0/0에서 NAT Gateway로 가는 경로를 추가한다. 즉 어떤 Subnet에 배치됐는지 볼 때는 이름보다 라우팅 테이블을 확인해야 한다.
- 05
Security Group은 stateful하게 동작한다. 인바운드를 허용하면 그 연결의 응답 트래픽은 아웃바운드 규칙과 관계없이 자동으로 허용된다. 다만 이 동작은 connection tracking 테이블에 항목이 있을 때 성립한다. 인바운드와 아웃바운드가 모두 0.0.0.0/0에 전체 포트면 untracked flow가 되어 추적에서 제외될 수 있고, 이 상태에서 인바운드 규칙을 좁히면 기존 SSH나 HTTP 연결도 즉시 끊긴다. 반대로 좁은 규칙으로 시작해 tracked 상태가 된 연결은 규칙을 제거해도 timeout 전까지 유지될 수 있다.
- 06
Security Group에서 실무적으로 중요한 패턴은 IP 주소 대신 다른 Security Group ID를 소스로 지정하는 방식이다. 예를 들어 RDS가 ECS Task에서만 접속되도록 할 때, RDS Security Group의 인바운드 소스를 ECS Task의 Security Group으로 둔다. 그러면 ECS Task SG를 달고 있는 컨테이너는 RDS에 접속할 수 있고, Task의 IP가 바뀌어도 규칙을 다시 고칠 필요가 없다. 같은 VPC 안이어도 Security Group에서 명시적으로 허용하지 않으면 통신할 수 없다는 점이 핵심이다.
- 07
운영에서 조용히 터지는 문제로 Nitro v6 인스턴스의 idle timeout도 있다. M7i, C7i 같은 Nitro v6 세대는 TCP established idle timeout 기본값이 350초이고, 이전 세대 기본값 432,000초보다 약 1,234배 짧다. DB 커넥션 풀이나 HTTP keep-alive 세션이 5분 넘게 idle이면 에러 로그 없이 silent drop되고, 다음 요청에서 ECONNRESET 또는 hang으로 드러날 수 있다. 장기 idle 연결이 있는 워크로드라면 TCP keep-alive를 5분 미만으로 두고, 새 인스턴스 타입 도입 전에는 Nitro v6에서 부하 시험을 해야 한다.
- 08
NAT Gateway는 Private Subnet 리소스가 외부 인터넷으로 나갈 때 쓰는 관문이다. Private Subnet의 ECS Task가 NAT Gateway로 패킷을 보내면, NAT Gateway는 출발지 IP를 자신의 Elastic IP로 바꿔 외부로 요청을 보낸다. 응답이 돌아오면 다시 원래 ECS Task IP로 변환해 전달한다. 외부에서 먼저 들어오려 하면 매핑 정보가 없어 차단된다. 반면 ECR, S3, CloudWatch 같은 AWS 서비스 접근은 VPC Endpoint로 내부 통로를 만들 수 있고, NAT Gateway 비용을 줄이는 대안이 된다. 특히 S3용 Gateway Endpoint는 무료라는 점도 문서의 요약에 포함되어 있다.
- 09
장애를 좁힐 때는 증상별로 순서를 잡는 것이 좋다. ECS에서 RDS 연결이 ECONNREFUSED나 Connection timed out으로 실패하면, RDS Security Group의 인바운드에 ECS Task의 Security Group이 허용되어 있는지 본다. Private Subnet의 ECS가 CannotPullContainerError를 내거나 외부 API 호출에 실패하면, Private Subnet Route Table에 NAT Gateway 경로가 있는지 확인한다. 같은 VPC 안 서비스끼리만 통신이 안 되면, 수신 측 Security Group에 발신 측 Security Group이 소스로 허용되어 있는지 확인한다.
- 10
Security Group과 Route Table을 봐도 원인을 모르겠다면 VPC Flow Logs가 다음 단서가 된다. Flow Logs는 VPC를 통과하는 IP 트래픽 정보를 기록하므로, 실제로 패킷이 오고 있는지와 REJECT 로그를 확인할 수 있다. 필요하면 VPC Reachability Analyzer로 경로를 분석할 수 있다. 보안 측면에서는 VPC Block Public Access로 VPC 레벨의 인터넷 트래픽을 차단하고, Flow Logs를 GuardDuty와 연동해 포트 스캔이나 비정상 연결 시도를 탐지할 수 있다. 정리하면, AWS 네트워크 문제는 SG 규칙, Route Table, Flow Logs, Reachability Analyzer 순서로 좁혀 간다.
같은 레이어