본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 19. · 7 Views
AWS VPC 기초 개념 완벽 가이드
AWS의 가상 네트워크 환경인 VPC의 핵심 개념을 실무 중심으로 배웁니다. 초급 개발자도 쉽게 이해할 수 있도록 CIDR, 서브넷, 인터넷 게이트웨이부터 라우팅까지 단계별로 설명합니다.
목차
1. VPC란 무엇인가
김개발 씨는 첫 AWS 프로젝트를 맡게 되었습니다. 팀장님이 "먼저 VPC부터 설정해야 해요"라고 말씀하시는데, VPC가 무엇인지 막연하기만 합니다.
클라우드에 서버를 띄우는 건데 왜 네트워크를 먼저 고민해야 할까요?
**VPC(Virtual Private Cloud)**는 AWS 클라우드 내에서 논리적으로 격리된 가상 네트워크 공간입니다. 마치 클라우드 안에 여러분만의 독립적인 사설 네트워크를 만드는 것과 같습니다.
이를 통해 리소스 간의 통신을 제어하고, 보안을 강화하며, 외부 인터넷과의 연결을 관리할 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
# AWS VPC 생성하기
ec2 = boto3.resource('ec2', region_name='ap-northeast-2')
# VPC 생성: 10.0.0.0/16 네트워크 대역 사용
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
# VPC에 이름 태그 지정
vpc.create_tags(Tags=[{"Key": "Name", "Value": "my-first-vpc"}])
# DNS 호스트네임 활성화
vpc.modify_attribute(EnableDnsHostnames={'Value': True})
print(f"VPC 생성 완료: {vpc.id}")
print(f"CIDR 블록: {vpc.cidr_block}")
김개발 씨는 회사에서 첫 AWS 프로젝트 담당자가 되었습니다. 회의실에서 팀장님과 선배 개발자 박시니어 씨가 프로젝트 인프라를 논의하고 있습니다.
"먼저 VPC를 설계해야 합니다"라는 말이 나오자, 김개발 씨는 살짝 당황했습니다. 서버를 띄우는 것만 생각했는데, 왜 네트워크부터 시작해야 할까요?
VPC란 무엇일까요? 박시니어 씨가 화이트보드에 그림을 그리며 설명을 시작합니다. "VPC는 Virtual Private Cloud의 약자입니다.
쉽게 말하면, AWS 클라우드 안에 우리만의 독립적인 네트워크 공간을 만드는 거예요." 마치 큰 아파트 단지를 생각해보면 이해하기 쉽습니다. 아파트 단지 전체가 AWS 클라우드라면, 그 안에 있는 각각의 동이 바로 VPC입니다.
각 동은 독립적인 출입구와 엘리베이터를 가지고 있고, 다른 동과는 분리되어 있습니다. 왜 VPC가 필요할까요? 옛날 온프레미스(자체 서버실) 환경에서는 물리적으로 격리된 네트워크를 구축했습니다.
라우터와 스위치를 직접 설치하고, 케이블을 연결하고, 방화벽을 설정했습니다. 하지만 클라우드에서는 어떻게 할까요?
AWS에는 수많은 고객의 리소스가 함께 존재합니다. 만약 네트워크 격리가 없다면, 다른 고객의 서버와 여러분의 서버가 같은 네트워크에 있게 됩니다.
보안상 큰 문제입니다. VPC의 등장 바로 이런 이유로 VPC가 등장했습니다.
VPC를 생성하면 여러분만의 논리적으로 완전히 격리된 네트워크 공간이 만들어집니다. 이 공간 안에서는 여러분이 네트워크의 모든 것을 제어할 수 있습니다.
IP 주소 범위를 정하고, 서브넷을 만들고, 라우팅 테이블을 구성하고, 네트워크 게이트웨이를 설정합니다. 마치 자신만의 데이터센터를 가진 것처럼 완벽한 제어권을 가집니다.
VPC의 핵심 특징 김개발 씨가 질문합니다. "그럼 VPC를 만들면 뭐가 좋은가요?" 박시니어 씨는 손가락을 펴며 하나씩 설명합니다.
첫째, 보안성입니다. 다른 AWS 고객과 완전히 격리되어 있어 안전합니다.
둘째, 유연성입니다. 네트워크 구조를 자유롭게 설계할 수 있습니다.
셋째, 확장성입니다. 필요에 따라 네트워크를 쉽게 확장할 수 있습니다.
실제 코드로 VPC 만들기 위의 코드를 살펴보겠습니다. boto3는 AWS를 Python에서 제어하는 라이브러리입니다.
create_vpc() 함수로 VPC를 생성할 때 CidrBlock이라는 파라미터를 전달합니다. '10.0.0.0/16'이라는 값은 이 VPC에서 사용할 IP 주소 범위를 의미합니다.
이것은 약 65,000개의 IP 주소를 사용할 수 있는 네트워크입니다. 다음 섹션에서 CIDR에 대해 자세히 배우게 됩니다.
EnableDnsHostnames 옵션을 활성화하면 VPC 내의 인스턴스에 DNS 호스트네임이 자동으로 할당됩니다. 이렇게 하면 IP 주소 대신 이름으로 서버에 접근할 수 있어 편리합니다.
실무에서의 VPC 활용 실제 회사에서는 어떻게 VPC를 사용할까요? 대부분의 기업은 개발 환경, 스테이징 환경, 프로덕션 환경을 별도의 VPC로 분리합니다.
예를 들어 쇼핑몰 서비스를 운영한다면, 개발자들이 테스트하는 개발용 VPC, QA팀이 검증하는 스테이징 VPC, 실제 고객이 사용하는 프로덕션 VPC를 각각 만듭니다. 이렇게 하면 개발 중인 불안정한 코드가 실제 서비스에 영향을 주지 않습니다.
주의할 점 초보 개발자들이 흔히 하는 실수는 모든 리소스를 하나의 VPC에 몰아넣는 것입니다. "어차피 내 것인데 하나면 되지 않나?"라고 생각하기 쉽습니다.
하지만 이렇게 하면 나중에 보안 사고가 발생했을 때 영향 범위가 너무 커집니다. 또한 개발 중 실수로 프로덕션 데이터를 건드리는 사고도 발생할 수 있습니다.
따라서 환경별로 VPC를 분리하는 것이 모범 사례입니다. 김개발 씨의 깨달음 박시니어 씨의 설명을 들은 김개발 씨는 이제 이해가 되었습니다.
"아, VPC는 클라우드 안에 우리만의 독립적인 네트워크를 만드는 거군요!" VPC는 AWS 인프라의 기초입니다. 모든 EC2 인스턴스, RDS 데이터베이스, Lambda 함수 등은 VPC 안에 배치됩니다.
따라서 VPC를 제대로 이해하는 것이 AWS를 마스터하는 첫걸음입니다.
실전 팁
💡 - 실무에서는 환경별(개발/스테이징/프로덕션)로 VPC를 분리하여 보안과 안정성을 확보하세요
- VPC 생성 시 충분히 큰 CIDR 블록을 선택하세요. 나중에 IP가 부족하면 변경이 어렵습니다
- 기본 VPC 대신 커스텀 VPC를 사용하여 네트워크를 명확히 설계하고 제어하세요
2. 기본 VPC 이해
김개발 씨가 AWS 콘솔에 처음 로그인했을 때, 이미 VPC가 하나 존재하고 있었습니다. "어?
제가 만든 적이 없는데요?" 박시니어 씨가 웃으며 말합니다. "그건 AWS가 자동으로 만들어준 기본 VPC예요."
**기본 VPC(Default VPC)**는 AWS 계정을 생성하면 각 리전마다 자동으로 생성되는 VPC입니다. 초보자가 복잡한 네트워크 설정 없이 바로 리소스를 시작할 수 있도록 AWS가 제공하는 편의 기능입니다.
기본 VPC는 이미 인터넷 게이트웨이와 서브넷이 구성되어 있어 즉시 사용 가능합니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 기본 VPC 찾기
response = ec2.describe_vpcs(
Filters=[{'Name': 'isDefault', 'Values': ['true']}]
)
if response['Vpcs']:
default_vpc = response['Vpcs'][0]
print(f"기본 VPC ID: {default_vpc['VpcId']}")
print(f"CIDR 블록: {default_vpc['CidrBlock']}")
print(f"상태: {default_vpc['State']}")
# 기본 VPC의 서브넷 확인
subnets = ec2.describe_subnets(
Filters=[{'Name': 'vpc-id', 'Values': [default_vpc['VpcId']]}]
)
print(f"서브넷 개수: {len(subnets['Subnets'])}")
else:
print("기본 VPC가 없습니다")
김개발 씨는 AWS 콘솔의 VPC 메뉴를 열어봤습니다. 분명 아무것도 만든 적이 없는데, 이미 VPC가 하나 존재하고 있습니다.
이름도 없고, 체크박스에 "기본"이라고 표시되어 있습니다. "이게 뭐죠?" 김개발 씨가 박시니어 씨에게 물었습니다.
기본 VPC란? 박시니어 씨가 설명합니다. "AWS는 사용자 경험을 위해 각 리전마다 기본 VPC를 자동으로 만들어줍니다.
초보자도 복잡한 네트워크 지식 없이 바로 EC2 인스턴스를 띄울 수 있게 하려는 거죠." 마치 새로운 스마트폰을 샀을 때 기본 앱들이 이미 설치되어 있는 것과 같습니다. 카메라, 계산기, 메모장 같은 기본 앱들 말입니다.
사용자가 직접 설치하지 않아도 바로 사용할 수 있도록 제조사가 미리 준비해둔 것입니다. 기본 VPC의 특징 기본 VPC는 특별한 특징들을 가지고 있습니다.
첫째, CIDR 블록이 항상 172.31.0.0/16으로 고정되어 있습니다. 둘째, 각 가용 영역(AZ)마다 자동으로 퍼블릭 서브넷이 생성됩니다.
셋째, 인터넷 게이트웨이가 이미 연결되어 있습니다. 이것이 무슨 의미일까요?
간단히 말하면, 여러분이 EC2 인스턴스를 기본 VPC에 띄우면 자동으로 인터넷에 연결됩니다. 별도 설정이 필요 없습니다.
커스텀 VPC와의 차이 김개발 씨가 질문합니다. "그럼 기본 VPC만 쓰면 되는 거 아닌가요?" 박시니어 씨가 고개를 가로젓습니다.
기본 VPC는 편리하지만 제약이 있습니다. CIDR 블록을 변경할 수 없고, 네트워크 구조를 자유롭게 설계할 수 없습니다.
실무에서는 보통 기본 VPC는 테스트용으로만 사용하고, 실제 서비스는 커스텀 VPC를 만들어 사용합니다. 마치 기본 앱으로는 기본적인 작업만 가능하지만, 전문 작업을 위해서는 전문 앱을 따로 설치하는 것과 같습니다.
기본 VPC 찾기 위의 코드를 보겠습니다. describe_vpcs() 함수에 isDefault 필터를 사용하면 기본 VPC를 찾을 수 있습니다.
각 리전에는 최대 하나의 기본 VPC만 존재합니다. 코드를 실행하면 기본 VPC의 ID와 CIDR 블록이 출력됩니다.
또한 이 VPC에 속한 서브넷들도 확인할 수 있습니다. 보통 리전의 가용 영역 개수만큼 서브넷이 자동 생성되어 있습니다.
기본 VPC가 없다면? 간혹 기본 VPC가 없는 경우도 있습니다. 실수로 삭제했거나, 예전 AWS 계정인 경우입니다.
이럴 때는 AWS 콘솔에서 "기본 VPC 생성" 버튼을 클릭하면 다시 만들 수 있습니다. 하지만 한 번 삭제된 기본 VPC를 복구하면, 예전과 다른 설정으로 생성될 수 있습니다.
따라서 기본 VPC는 함부로 삭제하지 않는 것이 좋습니다. 실무에서의 활용 실무에서 기본 VPC는 어떻게 사용할까요?
대부분의 개발자들은 간단한 테스트나 POC(Proof of Concept)를 할 때 기본 VPC를 사용합니다. 예를 들어 새로운 라이브러리를 테스트하거나, 빠르게 데모를 만들어야 할 때입니다.
네트워크 설정에 시간을 쓰지 않고 바로 인스턴스를 띄워서 작업할 수 있습니다. 하지만 프로덕션 환경에서는 절대 기본 VPC를 사용하지 않습니다.
보안 요구사항을 충족하기 어렵고, 네트워크 구조를 세밀하게 제어할 수 없기 때문입니다. 주의사항 초보자들이 흔히 하는 실수는 모든 것을 기본 VPC에서 작업하는 것입니다.
처음에는 편하게 느껴지지만, 나중에 프로덕션으로 옮길 때 큰 작업이 됩니다. 또 다른 실수는 기본 VPC를 삭제해버리는 것입니다.
"어차피 안 쓸 거니까"라고 생각하고 지웠다가, 나중에 빠른 테스트가 필요할 때 불편함을 겪습니다. 김개발 씨의 정리 박시니어 씨의 설명을 들은 김개발 씨는 노트에 정리합니다.
"기본 VPC는 AWS가 자동으로 만들어주는 편의 기능. 빠른 테스트에는 좋지만, 실제 서비스는 커스텀 VPC를 만들어서 사용하자." 기본 VPC는 AWS 입문자에게는 고마운 존재입니다.
하지만 진지하게 AWS를 다루려면 곧 커스텀 VPC의 세계로 들어가야 합니다.
실전 팁
💡 - 기본 VPC는 빠른 테스트와 학습용으로 활용하고, 실제 서비스는 커스텀 VPC를 설계하세요
- 기본 VPC를 실수로 삭제했다면 AWS 콘솔에서 "기본 VPC 생성" 기능으로 복구할 수 있습니다
- 기본 VPC의 모든 서브넷은 퍼블릭이므로 민감한 데이터베이스를 배치하지 마세요
3. CIDR 블록 개념
김개발 씨는 VPC를 만들려고 하는데, CIDR 블록이라는 입력 필드가 나타났습니다. "10.0.0.0/16이라고 써야 한다는데, 이게 무슨 뜻이죠?" 박시니어 씨가 종이를 꺼내며 말합니다.
"IP 주소 할당의 기본이에요. 차근차근 알려드릴게요."
**CIDR(Classless Inter-Domain Routing)**은 IP 주소 범위를 표현하는 방식입니다. '10.0.0.0/16'처럼 IP 주소와 슬래시 뒤의 숫자로 표기하며, 슬래시 뒤의 숫자는 네트워크 부분의 비트 수를 의미합니다.
이를 통해 사용 가능한 IP 주소의 개수를 결정할 수 있습니다.
다음 코드를 살펴봅시다.
import ipaddress
# CIDR 블록 분석하기
cidr_block = "10.0.0.0/16"
# ipaddress 모듈로 네트워크 정보 파싱
network = ipaddress.ip_network(cidr_block)
print(f"CIDR 블록: {network}")
print(f"네트워크 주소: {network.network_address}")
print(f"브로드캐스트 주소: {network.broadcast_address}")
print(f"서브넷 마스크: {network.netmask}")
print(f"사용 가능한 IP 개수: {network.num_addresses}")
print(f"호스트 IP 범위: {network.network_address + 1} ~ {network.broadcast_address - 1}")
# 다양한 CIDR 비교
for prefix in [8, 16, 24, 28]:
net = ipaddress.ip_network(f"10.0.0.0/{prefix}")
print(f"//{prefix} = {net.num_addresses:,}개 IP 주소")
김개발 씨가 VPC 생성 화면을 보고 있습니다. 'IPv4 CIDR 블록'이라는 필드에 '10.0.0.0/16'이라는 예시가 보입니다.
무슨 암호 같습니다. 박시니어 씨가 옆에서 지켜보다가 설명을 시작합니다.
CIDR이란 무엇인가? "CIDR은 사이더라고 읽어요. Classless Inter-Domain Routing의 약자입니다." 박시니어 씨가 종이에 그림을 그립니다.
마치 전화번호를 생각해보면 이해하기 쉽습니다. 02-1234-5678이라는 전화번호가 있다면, 02는 서울을 나타내고, 1234는 지역 교환국, 5678은 개별 번호입니다.
CIDR도 비슷하게 IP 주소를 나눕니다. 슬래시 뒤의 숫자 '10.0.0.0/16'에서 슬래시(/) 뒤의 16은 무엇을 의미할까요?
이것은 IP 주소 중 앞의 16비트가 네트워크 부분이라는 뜻입니다. IP 주소는 총 32비트입니다.
16비트를 네트워크에 쓰면, 나머지 16비트는 호스트 부분으로 사용할 수 있습니다. 2의 16승은 65,536이므로, 약 65,000개의 IP 주소를 이 네트워크에서 사용할 수 있습니다.
숫자가 클수록 작은 네트워크 김개발 씨가 질문합니다. "그럼 /24는 어떻게 되나요?" 박시니어 씨가 대답합니다.
"/24는 앞의 24비트가 네트워크 부분이에요. 그럼 호스트 부분은 8비트만 남죠." 2의 8승은 256입니다.
따라서 /24 네트워크는 256개의 IP 주소를 가집니다. /16보다 훨씬 작습니다.
여기서 중요한 원칙을 기억하세요. 슬래시 뒤의 숫자가 클수록 네트워크는 작아집니다. /8은 매우 큰 네트워크이고, /28은 매우 작은 네트워크입니다.
VPC에서 사용 가능한 CIDR AWS VPC에서는 /16부터 /28까지 사용할 수 있습니다. /16이 가장 크고(65,536개 IP), /28이 가장 작습니다(16개 IP).
대부분의 회사는 /16을 선택합니다. 충분히 큰 IP 공간이 필요하기 때문입니다.
작게 시작했다가 나중에 IP가 부족해지면 변경하기 어렵습니다. 코드로 CIDR 분석하기 위의 코드를 보겠습니다.
Python의 ipaddress 모듈을 사용하면 CIDR 블록을 쉽게 분석할 수 있습니다. ip_network() 함수에 CIDR 문자열을 전달하면 네트워크 객체가 생성됩니다.
이 객체에서 네트워크 주소, 브로드캐스트 주소, 서브넷 마스크, 사용 가능한 IP 개수 등을 확인할 수 있습니다. 코드 마지막 부분에서는 /8, /16, /24, /28의 IP 개수를 비교합니다.
숫자가 커질수록 사용 가능한 IP가 급격히 줄어드는 것을 볼 수 있습니다. 프라이빗 IP 대역 김개발 씨가 또 질문합니다.
"10.0.0.0은 왜 10으로 시작하나요?" 박시니어 씨가 설명합니다. 인터넷에서 사용하지 않는 프라이빗 IP 대역이 있습니다.
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 이 세 가지입니다. VPC에서는 반드시 이 대역 중 하나를 사용해야 합니다.
집에서 사용하는 공유기도 보통 192.168.x.x를 사용합니다. 이것도 프라이빗 IP 대역입니다.
실무에서의 CIDR 선택 실제 회사에서는 어떤 CIDR을 선택할까요? 대부분 10.0.0.0/16을 기본으로 사용합니다.
충분히 크고, 관리하기도 편합니다. 만약 여러 VPC를 운영한다면 각각 다른 대역을 할당합니다.
개발 VPC는 10.0.0.0/16, 스테이징 VPC는 10.1.0.0/16, 프로덕션 VPC는 10.2.0.0/16 이런 식입니다. 나중에 VPC 피어링(연결)을 할 때 IP가 겹치지 않아야 하기 때문입니다.
주의사항 초보자들이 흔히 하는 실수는 너무 작은 CIDR 블록을 선택하는 것입니다. "어차피 서버 10대면 /28로 충분하지 않나?"라고 생각합니다.
하지만 나중에 서비스가 커지면서 서버가 늘어나고, Lambda 함수가 추가되고, RDS가 생기면 IP가 금방 부족해집니다. VPC의 CIDR 블록은 한 번 정하면 변경하기 매우 어렵습니다.
따라서 여유있게 /16을 선택하는 것이 좋습니다. 김개발 씨의 이해 박시니어 씨의 설명을 들은 김개발 씨는 이제 명확해졌습니다.
"아, CIDR은 IP 주소 범위를 정하는 거고, 슬래시 뒤의 숫자가 작을수록 더 많은 IP를 쓸 수 있군요!" CIDR을 이해하면 VPC 설계의 기초를 다진 것입니다. 다음은 이 IP 범위를 어떻게 나누어 사용할지, 즉 서브넷에 대해 배울 차례입니다.
실전 팁
💡 - VPC 생성 시 넉넉하게 /16을 선택하세요. 나중에 IP 부족으로 고생하지 않습니다
- 여러 VPC를 사용한다면 각각 다른 CIDR 대역을 할당하여 나중에 피어링 시 충돌을 방지하세요
- AWS에서 권장하는 프라이빗 IP 대역(10.x, 172.16.x, 192.168.x)을 반드시 사용하세요
4. 서브넷 이해
김개발 씨는 VPC를 만들었지만, 아직 EC2 인스턴스를 띄울 수 없었습니다. "서브넷을 먼저 만들어야 합니다"라는 에러 메시지가 나타났습니다.
박시니어 씨가 설명합니다. "VPC는 큰 땅이고, 서브넷은 그 땅을 구획으로 나눈 것이에요."
**서브넷(Subnet)**은 VPC의 IP 주소 범위를 더 작은 단위로 나눈 것입니다. 각 서브넷은 특정 가용 영역(AZ)에 속하며, 퍼블릭 서브넷과 프라이빗 서브넷으로 구분할 수 있습니다.
서브넷을 통해 리소스를 논리적으로 분리하고, 보안과 가용성을 향상시킬 수 있습니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.resource('ec2', region_name='ap-northeast-2')
# VPC 가져오기 (이미 생성된 VPC 사용)
vpc = ec2.Vpc('vpc-xxxxx') # 실제 VPC ID로 교체
# 퍼블릭 서브넷 생성 (가용영역 A)
public_subnet = vpc.create_subnet(
CidrBlock='10.0.1.0/24', # 256개 IP 주소
AvailabilityZone='ap-northeast-2a'
)
public_subnet.create_tags(Tags=[{"Key": "Name", "Value": "public-subnet-a"}])
# 프라이빗 서브넷 생성 (가용영역 A)
private_subnet = vpc.create_subnet(
CidrBlock='10.0.2.0/24',
AvailabilityZone='ap-northeast-2a'
)
private_subnet.create_tags(Tags=[{"Key": "Name", "Value": "private-subnet-a"}])
print(f"퍼블릭 서브넷: {public_subnet.id} ({public_subnet.cidr_block})")
print(f"프라이빗 서브넷: {private_subnet.id} ({private_subnet.cidr_block})")
김개발 씨는 VPC를 성공적으로 만들었습니다. 이제 EC2 인스턴스를 띄우려고 하는데, 인스턴스 생성 화면에서 "서브넷을 선택하세요"라는 드롭다운이 비어있습니다.
"왜 안 될까요?" 김개발 씨가 당황합니다. 박시니어 씨가 화면을 보고 말합니다.
"아, 서브넷을 아직 안 만드셨네요." 서브넷이란 무엇인가? 박시니어 씨가 화이트보드에 큰 사각형을 그립니다. "이게 VPC예요.
10.0.0.0/16이라는 큰 IP 범위를 가지고 있죠." 그리고 그 안에 여러 개의 작은 사각형을 그립니다. "이 작은 네트워크들이 바로 서브넷입니다.
VPC라는 큰 땅을 여러 구획으로 나눈 거예요." 마치 큰 아파트 단지를 상상해보세요. 단지 전체가 VPC라면, 그 안의 각 동이 서브넷입니다.
1동, 2동, 3동처럼 구역을 나누는 것입니다. 각 동은 독립적으로 관리되지만, 모두 같은 아파트 단지에 속해 있습니다.
왜 서브넷이 필요한가? VPC를 나누지 않고 그냥 사용하면 안 될까요? 이론적으로는 가능하지만, 실무에서는 절대 그렇게 하지 않습니다.
서브넷을 나누면 보안을 강화할 수 있습니다. 웹 서버는 인터넷에서 접근 가능한 퍼블릭 서브넷에 두고, 데이터베이스는 외부에서 접근 불가능한 프라이빗 서브넷에 둡니다.
또한 가용성도 높아집니다. 서로 다른 가용 영역에 서브넷을 만들면, 한 데이터센터에 장애가 나도 다른 데이터센터의 리소스는 정상 작동합니다.
퍼블릭 서브넷 vs 프라이빗 서브넷 김개발 씨가 질문합니다. "퍼블릭 서브넷과 프라이빗 서브넷의 차이가 뭔가요?" 박시니어 씨가 설명합니다.
퍼블릭 서브넷은 인터넷과 직접 통신할 수 있는 서브넷입니다. 인터넷 게이트웨이로 향하는 라우팅이 설정되어 있고, 퍼블릭 IP를 가진 리소스가 외부와 통신할 수 있습니다.
웹 서버, API 서버 같이 외부에서 접근해야 하는 리소스를 배치합니다. 프라이빗 서브넷은 인터넷과 직접 통신할 수 없는 서브넷입니다.
외부에서 접근이 불가능하고, 내부 리소스들끼리만 통신합니다. 데이터베이스, 캐시 서버, 내부 API 같이 보안이 중요한 리소스를 배치합니다.
가용 영역(AZ) 서브넷을 만들 때 반드시 **가용 영역(Availability Zone)**을 지정해야 합니다. 가용 영역은 AWS 리전 내의 물리적으로 분리된 데이터센터입니다.
서울 리전(ap-northeast-2)에는 ap-northeast-2a, 2b, 2c, 2d 네 개의 가용 영역이 있습니다. 고가용성을 위해 서로 다른 AZ에 서브넷을 만들고, 각 서브넷에 리소스를 분산 배치하는 것이 좋습니다.
코드로 서브넷 만들기 위의 코드를 살펴보겠습니다. create_subnet() 함수로 서브넷을 생성할 때 세 가지 정보가 필요합니다.
첫째, CidrBlock입니다. VPC의 CIDR 범위 안에서 더 작은 범위를 할당합니다.
VPC가 10.0.0.0/16이라면, 서브넷은 10.0.1.0/24, 10.0.2.0/24 같은 식으로 나눕니다. 둘째, AvailabilityZone입니다.
이 서브넷이 어느 AZ에 속할지 지정합니다. 셋째, 태그로 이름을 붙여서 관리하기 쉽게 합니다.
실무에서의 서브넷 설계 실제 회사에서는 어떻게 서브넷을 설계할까요? 일반적인 패턴은 다음과 같습니다.
각 가용 영역마다 퍼블릭 서브넷 하나, 프라이빗 서브넷 하나를 만듭니다. 예를 들어 두 개의 AZ를 사용한다면 총 4개의 서브넷이 필요합니다.
10.0.1.0/24(퍼블릭-A), 10.0.2.0/24(프라이빗-A), 10.0.3.0/24(퍼블릭-B), 10.0.4.0/24(프라이빗-B) 이런 식입니다. 서브넷 CIDR 계산 김개발 씨가 고민합니다.
"10.0.1.0/24, 10.0.2.0/24는 어떻게 정한 건가요?" 박시니어 씨가 설명합니다. VPC가 10.0.0.0/16이면 10.0.0.0부터 10.0.255.255까지 사용할 수 있습니다.
이것을 /24 단위로 나누면 256개의 서브넷을 만들 수 있습니다. 10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24...
이런 식으로 증가시킵니다. 각 서브넷은 256개의 IP 주소를 가지지만, AWS가 5개를 예약하므로 실제로는 251개만 사용 가능합니다.
주의사항 초보자들이 흔히 하는 실수는 모든 리소스를 퍼블릭 서브넷에 두는 것입니다. "어차피 접속해야 하니까 다 퍼블릭이면 편하지 않나?"라고 생각합니다.
하지만 이것은 심각한 보안 문제입니다. 데이터베이스가 인터넷에 노출되면 공격 대상이 됩니다.
반드시 퍼블릭과 프라이빗을 구분하고, 민감한 리소스는 프라이빗 서브넷에 배치해야 합니다. 김개발 씨의 정리 박시니어 씨의 설명을 들은 김개발 씨는 이제 서브넷의 개념을 이해했습니다.
"VPC를 더 작은 네트워크로 나누는 거고, 퍼블릭과 프라이빗으로 구분해서 보안을 지키는 거군요!" 서브넷은 VPC 설계의 핵심입니다. 제대로 설계하면 안전하고 확장 가능한 인프라를 만들 수 있습니다.
실전 팁
💡 - 고가용성을 위해 최소 두 개의 가용 영역에 서브넷을 만드세요
- 퍼블릭과 프라이빗 서브넷을 명확히 구분하고, 데이터베이스는 반드시 프라이빗 서브넷에 배치하세요
- 서브넷 CIDR을 계획할 때 미래의 확장을 고려하여 충분한 IP 범위를 남겨두세요
5. 인터넷 게이트웨이
김개발 씨는 퍼블릭 서브넷에 웹 서버를 띄웠지만, 외부에서 접속이 되지 않았습니다. "퍼블릭 서브넷인데 왜 안 되죠?" 박시니어 씨가 VPC 설정을 확인하며 말합니다.
"인터넷 게이트웨이를 연결하지 않으셨네요."
**인터넷 게이트웨이(Internet Gateway)**는 VPC와 인터넷을 연결하는 관문입니다. VPC 내부의 리소스가 인터넷과 통신하려면 반드시 인터넷 게이트웨이가 필요합니다.
퍼블릭 IP를 가진 리소스는 인터넷 게이트웨이를 통해 외부와 양방향 통신이 가능합니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# VPC ID (이미 생성된 VPC 사용)
vpc_id = 'vpc-xxxxx'
# 인터넷 게이트웨이 생성
response = ec2.create_internet_gateway(
TagSpecifications=[{
'ResourceType': 'internet-gateway',
'Tags': [{'Key': 'Name', 'Value': 'my-igw'}]
}]
)
igw_id = response['InternetGateway']['InternetGatewayId']
print(f"인터넷 게이트웨이 생성: {igw_id}")
# VPC에 인터넷 게이트웨이 연결
ec2.attach_internet_gateway(
InternetGatewayId=igw_id,
VpcId=vpc_id
)
print(f"인터넷 게이트웨이를 VPC {vpc_id}에 연결 완료")
# 상태 확인
igw_info = ec2.describe_internet_gateways(InternetGatewayIds=[igw_id])
print(f"연결 상태: {igw_info['InternetGateways'][0]['Attachments'][0]['State']}")
김개발 씨는 신나게 웹 서버를 퍼블릭 서브넷에 배포했습니다. 퍼블릭 IP도 할당받았습니다.
이제 브라우저에서 접속하면 될 것 같습니다. 하지만 브라우저에 IP를 입력해도 "연결할 수 없음"이라는 메시지만 나타납니다.
"왜 안 되는 거죠?" 김개발 씨가 당황합니다. 인터넷 게이트웨이란? 박시니어 씨가 VPC 설정을 확인합니다.
"아, 인터넷 게이트웨이를 연결하지 않으셨네요." 김개발 씨는 또 낯선 용어에 고개를 갸우뚱합니다. "인터넷 게이트웨이는 VPC와 인터넷 세계를 연결하는 문입니다." 박시니어 씨가 화이트보드에 그림을 그립니다.
VPC라는 큰 성이 있고, 그 성의 대문이 바로 인터넷 게이트웨이입니다. 마치 아파트 단지의 정문과 같습니다.
아무리 퍼블릭 서브넷(1동)에 살아도, 아파트 정문이 잠겨 있으면 외부 손님이 들어올 수 없습니다. 인터넷 게이트웨이가 바로 그 정문인 것입니다.
VPC는 기본적으로 격리되어 있다 중요한 사실 하나를 기억해야 합니다. VPC는 기본적으로 인터넷과 완전히 격리되어 있습니다. 이것은 보안을 위한 기본 설정입니다.
따라서 의도적으로 인터넷 게이트웨이를 생성하고 VPC에 연결해야만 인터넷 통신이 가능해집니다. "나는 외부와 통신하겠다"는 명시적인 선언이 필요한 것입니다.
인터넷 게이트웨이의 역할 인터넷 게이트웨이는 두 가지 중요한 역할을 합니다. 첫째, NAT(Network Address Translation) 기능을 수행합니다.
VPC 내부의 프라이빗 IP를 퍼블릭 IP로 변환해줍니다. 예를 들어 EC2 인스턴스의 내부 IP가 10.0.1.5라면, 이것을 퍼블릭 IP인 52.78.123.45로 변환합니다.
둘째, 라우팅 타겟 역할을 합니다. 라우팅 테이블에서 "인터넷으로 가는 트래픽은 인터넷 게이트웨이로 보내라"고 설정할 수 있습니다.
다음 섹션에서 자세히 배우게 됩니다. 코드로 인터넷 게이트웨이 만들기 위의 코드를 살펴보겠습니다.
인터넷 게이트웨이를 만드는 것은 두 단계입니다. 첫 번째 단계는 create_internet_gateway() 함수로 인터넷 게이트웨이를 생성하는 것입니다.
이렇게 생성된 게이트웨이는 아직 어떤 VPC에도 연결되지 않은 상태입니다. 두 번째 단계는 attach_internet_gateway() 함수로 게이트웨이를 VPC에 연결하는 것입니다.
이제 이 VPC는 인터넷과 통신할 수 있는 문이 열린 것입니다. 하나의 VPC, 하나의 인터넷 게이트웨이 중요한 제약사항이 있습니다.
하나의 VPC에는 하나의 인터넷 게이트웨이만 연결할 수 있습니다. 여러 개를 연결하려고 하면 에러가 발생합니다. 하지만 걱정하지 마세요.
인터넷 게이트웨이는 수평 확장되고 고가용성이 보장되는 AWS 관리형 서비스입니다. 트래픽이 아무리 많아도 자동으로 처리하고, 장애가 발생하지 않습니다.
퍼블릭 서브넷의 완성 김개발 씨가 질문합니다. "그럼 인터넷 게이트웨이만 연결하면 퍼블릭 서브넷이 되나요?" 박시니어 씨가 손가락을 펴며 설명합니다.
퍼블릭 서브넷이 되려면 세 가지 조건이 필요합니다. 첫째, VPC에 인터넷 게이트웨이가 연결되어 있어야 합니다.
둘째, 서브넷의 라우팅 테이블에 인터넷 게이트웨이로 향하는 경로가 설정되어 있어야 합니다. 셋째, 인스턴스에 퍼블릭 IP가 할당되어 있어야 합니다.
이 세 가지가 모두 갖춰져야 진정한 퍼블릭 서브넷입니다. 하나라도 빠지면 외부와 통신할 수 없습니다.
실무에서의 활용 실제 회사에서는 모든 VPC에 인터넷 게이트웨이를 연결할까요? 아닙니다.
완전히 격리된 VPC도 있습니다. 예를 들어 내부 관리용 VPC나 데이터 처리 전용 VPC는 인터넷 게이트웨이가 없을 수 있습니다.
보안을 극대화하기 위해 외부와의 연결을 완전히 차단하는 것입니다. 대신 VPN이나 Direct Connect로 회사 네트워크와만 연결합니다.
비용은? 김개발 씨가 궁금해합니다. "인터넷 게이트웨이는 비용이 얼마나 드나요?" 박시니어 씨가 웃으며 대답합니다.
좋은 소식입니다. 인터넷 게이트웨이 자체는 무료입니다.
단지 생성하고 연결하는 것만으로는 비용이 발생하지 않습니다. 다만 인터넷 게이트웨이를 통해 데이터를 전송하면 비용이 발생합니다.
특히 외부로 데이터를 내보내는(Egress) 비용이 있습니다. 주의사항 초보자들이 흔히 하는 실수는 인터넷 게이트웨이를 연결했는데도 접속이 안 된다고 당황하는 것입니다.
인터넷 게이트웨이는 필요조건이지 충분조건이 아닙니다. 라우팅 테이블 설정, 보안 그룹 설정, 퍼블릭 IP 할당 등 다른 조건들도 함께 확인해야 합니다.
하나라도 빠지면 통신이 불가능합니다. 김개발 씨의 성공 박시니어 씨의 도움으로 김개발 씨는 인터넷 게이트웨이를 생성하고 연결했습니다.
그리고 라우팅 테이블도 설정했습니다. 이제 브라우저에서 퍼블릭 IP로 접속하니 웹 페이지가 나타납니다!
"드디어 되네요!" 김개발 씨가 환호합니다. 인터넷 게이트웨이는 작지만 강력한 컴포넌트입니다.
VPC와 세상을 연결하는 핵심 요소입니다.
실전 팁
💡 - 인터넷 게이트웨이는 VPC당 하나만 연결 가능하며, AWS가 관리하므로 가용성 걱정이 없습니다
- 인터넷 게이트웨이만으로는 부족하며, 라우팅 테이블 설정과 퍼블릭 IP 할당도 함께 필요합니다
- 보안이 중요한 VPC는 인터넷 게이트웨이 없이 VPN이나 Direct Connect만 사용하는 것도 고려하세요
6. 라우팅 테이블 기초
김개발 씨는 인터넷 게이트웨이를 연결했지만 여전히 인터넷이 안 됩니다. "뭐가 또 빠진 거죠?" 박시니어 씨가 라우팅 테이블을 확인하며 말합니다.
"게이트웨이는 문이고, 라우팅 테이블은 그 문으로 가는 길을 알려주는 이정표예요."
**라우팅 테이블(Route Table)**은 네트워크 트래픽이 어디로 가야 하는지 알려주는 규칙 모음입니다. 각 서브넷은 반드시 하나의 라우팅 테이블과 연결되어야 하며, 라우팅 테이블은 목적지 IP 범위와 타겟(게이트웨이, 다른 인스턴스 등)을 정의합니다.
퍼블릭 서브넷의 라우팅 테이블에는 인터넷 게이트웨이로 향하는 경로가 필수입니다.
다음 코드를 살펴봅시다.
import boto3
ec2 = boto3.client('ec2', region_name='ap-northeast-2')
# 기존 리소스 ID
vpc_id = 'vpc-xxxxx'
igw_id = 'igw-xxxxx'
subnet_id = 'subnet-xxxxx'
# 라우팅 테이블 생성
response = ec2.create_route_table(
VpcId=vpc_id,
TagSpecifications=[{
'ResourceType': 'route-table',
'Tags': [{'Key': 'Name', 'Value': 'public-route-table'}]
}]
)
route_table_id = response['RouteTable']['RouteTableId']
print(f"라우팅 테이블 생성: {route_table_id}")
# 인터넷으로 가는 경로 추가 (0.0.0.0/0 → 인터넷 게이트웨이)
ec2.create_route(
RouteTableId=route_table_id,
DestinationCidrBlock='0.0.0.0/0', # 모든 인터넷 트래픽
GatewayId=igw_id
)
print("인터넷 경로 추가 완료")
# 서브넷에 라우팅 테이블 연결
ec2.associate_route_table(
RouteTableId=route_table_id,
SubnetId=subnet_id
)
print(f"라우팅 테이블을 서브넷 {subnet_id}에 연결 완료")
김개발 씨는 점점 혼란스러워집니다. VPC도 만들었고, 서브넷도 만들었고, 인터넷 게이트웨이도 연결했습니다.
그런데 왜 아직도 인터넷이 안 될까요? 박시니어 씨가 VPC 콘솔에서 라우팅 테이블 메뉴를 엽니다.
"여기가 문제예요." 라우팅 테이블이란? "라우팅 테이블은 네트워크 트래픽의 내비게이션입니다." 박시니어 씨가 설명을 시작합니다. "차를 타고 어딘가 가려면 내비게이션이 길을 알려주잖아요?
라우팅 테이블도 마찬가지예요." 마치 공항의 안내판을 생각해보세요. "국내선은 왼쪽, 국제선은 오른쪽, 면세점은 위층"처럼 목적지별로 어느 방향으로 가야 하는지 알려줍니다.
라우팅 테이블도 "이 IP 범위로 가는 트래픽은 이쪽 게이트웨이로 보내라"고 알려주는 안내판입니다. 라우팅 규칙의 구조 라우팅 테이블은 여러 개의 **라우팅 규칙(Route)**으로 구성됩니다.
각 규칙은 두 가지 정보를 담고 있습니다. 첫째, Destination(목적지)입니다.
CIDR 블록으로 표현됩니다. 예를 들어 10.0.0.0/16은 VPC 내부 트래픽, 0.0.0.0/0은 모든 외부 트래픽을 의미합니다.
둘째, Target(대상)입니다. 이 트래픽을 어디로 보낼지 지정합니다.
인터넷 게이트웨이(igw-xxxxx), NAT 게이트웨이, 다른 VPC, 로컬 등이 될 수 있습니다. 기본 라우팅 규칙 VPC를 생성하면 자동으로 메인 라우팅 테이블이 만들어집니다.
이 테이블에는 기본 규칙이 하나 있습니다. "10.0.0.0/16 → local"입니다.
이것은 "VPC 내부로 가는 트래픽은 로컬에서 처리하라"는 의미입니다. 즉, 같은 VPC 안의 리소스끼리는 자동으로 통신할 수 있다는 뜻입니다.
하지만 인터넷으로 가는 경로는 없습니다. 그래서 추가해야 합니다.
퍼블릭 서브넷의 라우팅 김개발 씨가 질문합니다. "그럼 퍼블릭 서브넷은 어떤 규칙이 필요한가요?" 박시니어 씨가 대답합니다.
퍼블릭 서브넷의 라우팅 테이블에는 두 가지 규칙이 필요합니다. 첫째, "10.0.0.0/16 → local" (VPC 내부 통신).
둘째, "0.0.0.0/0 → igw-xxxxx" (모든 외부 트래픽을 인터넷 게이트웨이로). 0.0.0.0/0은 "모든 IP 주소"를 의미합니다.
즉, VPC 내부가 아닌 모든 트래픽은 인터넷 게이트웨이로 보내라는 뜻입니다. 바로 이 규칙이 퍼블릭 서브넷을 진정한 퍼블릭으로 만듭니다.
프라이빗 서브넷의 라우팅 반대로 프라이빗 서브넷은 어떨까요? 프라이빗 서브넷의 라우팅 테이블에는 "0.0.0.0/0 → igw" 규칙이 없습니다.
오직 "10.0.0.0/16 → local"만 있습니다. 따라서 프라이빗 서브넷의 리소스는 VPC 내부끼리만 통신할 수 있고, 인터넷과는 통신할 수 없습니다.
이것이 프라이빗 서브넷의 정의입니다. 코드로 라우팅 테이블 설정하기 위의 코드를 살펴보겠습니다.
라우팅 테이블을 설정하는 것은 세 단계입니다. 첫 번째, create_route_table()로 새 라우팅 테이블을 생성합니다.
두 번째, create_route()로 인터넷으로 가는 경로를 추가합니다. DestinationCidrBlock을 '0.0.0.0/0'으로, GatewayId를 인터넷 게이트웨이 ID로 설정합니다.
세 번째, associate_route_table()로 이 라우팅 테이블을 서브넷에 연결합니다. 이제 이 서브넷의 모든 리소스는 이 라우팅 규칙을 따릅니다.
라우팅의 우선순위 김개발 씨가 질문합니다. "만약 여러 규칙이 겹치면 어떻게 되나요?" 박시니어 씨가 설명합니다.
라우팅은 가장 구체적인 규칙이 우선됩니다. 예를 들어 "10.0.1.0/24"와 "10.0.0.0/16" 두 규칙이 있다면, 10.0.1.5로 가는 트래픽은 더 구체적인 /24 규칙을 따릅니다.
또한 "local" 규칙은 항상 최우선입니다. 0.0.0.0/0 규칙이 있어도, VPC 내부 트래픽은 로컬로 처리됩니다.
실무에서의 라우팅 설계 실제 회사에서는 어떻게 라우팅을 설계할까요? 보통 퍼블릭용 라우팅 테이블 하나, 프라이빗용 라우팅 테이블 하나를 만듭니다.
퍼블릭 라우팅 테이블은 모든 퍼블릭 서브넷에 연결하고, 프라이빗 라우팅 테이블은 모든 프라이빗 서브넷에 연결합니다. 이렇게 하면 관리가 간편합니다.
프라이빗 서브넷에서도 인터넷 접속이 필요한 경우(예: 소프트웨어 업데이트)에는 NAT 게이트웨이를 사용합니다. 이것은 고급 주제이므로 나중에 배우게 됩니다.
주의사항 초보자들이 흔히 하는 실수는 라우팅 테이블 설정을 깜빡하는 것입니다. 인터넷 게이트웨이를 연결했으니 자동으로 될 거라고 생각합니다.
하지만 AWS는 명시적 설정을 요구합니다. 인터넷 게이트웨이를 연결했다면, 라우팅 테이블에도 그 게이트웨이로 가는 경로를 명시적으로 추가해야 합니다.
자동으로 설정되지 않습니다. 김개발 씨의 완성 박시니어 씨의 도움으로 김개발 씨는 마침내 라우팅 테이블을 올바르게 설정했습니다.
퍼블릭 서브넷에 "0.0.0.0/0 → igw" 규칙을 추가하니, 드디어 EC2 인스턴스에서 인터넷이 됩니다! "이제 모든 퍼즐이 맞춰졌네요!" 김개발 씨가 감탄합니다.
VPC, 서브넷, 인터넷 게이트웨이, 라우팅 테이블. 이 네 가지가 조화롭게 작동하면 완벽한 네트워크가 완성됩니다.
실전 팁
💡 - 퍼블릭 서브넷은 반드시 "0.0.0.0/0 → IGW" 규칙이 있어야 인터넷 통신이 가능합니다
- 라우팅 규칙은 가장 구체적인 것이 우선이므로, 특정 IP 범위에 대한 예외 처리가 가능합니다
- 실수 방지를 위해 퍼블릭용과 프라이빗용 라우팅 테이블을 명확히 구분하여 관리하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.