DevOps/AWS

[AWS] VPC(Virtual Private Cloud)

seungwook_TIL 2025. 4. 30. 21:20

이 글은 인프런의 지식 공유자 박재성님의 강의를 듣고 개인적으로 정리하는 글임을 알립니다.


VPC의 개념

VPC를 쓰는데 여러가지 이유가 있지만, 핵심적인 이유는 딱 한가지 보안 때문이다.

  • VPC란 가상의 네트워크 공간을 의미한다. 
  • VPC를 활용하면 외부에서 직접 접근할 수 없는 독립적인 네트워크 환경을 구성할 수 있어서, 보안적으로 안전하게 리소스(EC2, RDS 등)를 사용할 수 있다. 
  • 예를 들어, EC2 인스턴스 2대가 있다고 가정하자. 그런데 1대의 인스턴스는 인터넷에 자유롭게 접근하면서 사용하고 싶고, 나머지 1대는 좀 더 안전하고 비공개로 사용하고 싶을 수 있다. 이럴 때 VPC를 활용하면 된다.

 

VPC는 가상의 네트워크 공간이다.

따라서 네트워크 공간의 크기를 정해야한다.

AWS에서 EC2, RDS, ELB의 리소스를 생성하는 순간 VPC 안에 배치한다. 그럼과 동시에 각각의 자원에 IP 주소를 할당한다.

VPC의 크기를 정할 때는 IP 주소의 범위로 정한다.

위 예시는 10.10.0.0 ~ 10.10.0.31 범위인데 이를 CIDR 표기법으로 10.10.0.0/27 로 표기한다.

또한 VPC는 반드시 사설 IP 주소 범위 내에서 생성되어야 한다.

VPC만 생성해서는 EC2 인스턴스를 생성할 수 없다. VPC 뿐만 아니라 서브넷도 같이 생성해야 EC2 인스턴스를 생성할 수 있다.

 

 

아래 더보기를 클릭하면 VPC를 생성하는 방법을 확인할 수 있다.

더보기

1. VPC 페이지로 들어가기

 

2. VPC 생성 페이지로 들어가기

 

3. VPC 생성하기

 

서브넷(Subnet)

서브넷이란 하나의 큰 네트워크(VPC, 회사 네트워크 등)를 작은 네트워크 단위로 나눈 것을 의미한다.

  • 하나의 은 여러 개의 단락으로 나뉘어진다. 
  • 하나의 아파트는 여러 개의 으로 나뉘어진다. 

이와 비슷하게, 하나의 VPC는 여러 개의 서브넷으로 나뉘어진다.

 

위 그림과 같이 서브넷은 큰 네트워크의 일부분을 뜻한다. 

그렇기 때문에 서브넷의 IP CIDR은 VPC IP CIDR에 속해있어야 한다.

서브넷은 1개의 가용 영역에 종속
VPC는 리전 단위로 생성된다. 서브넷은 가용 영역 단위로 생성된다.
즉, 서브넷을 만들 때 어떤 AZ에 위치할지 반드시 지정해야 한다.
따라서 하나의 서브넷은 여러 AZ에 걸쳐 있을 수 없고, 오직 하나의 AZ에만 속한다.

 

 

서브넷을 사용하는 이유

  • 서브넷을 사용하는 이유는 용도에 따라 네트워크를 분리해서 사용하고 싶기 때문이다. 
  • 예를 들어, 하나의 VPC에서 데이터베이스끼리만 모아놓은 네트워크와 백엔드 서버끼리만 모아놓은 네트워크를 분리해서 관리하고 싶을 수 있다. 이럴 때 서브넷을 활용한다.

 

 

퍼블릭 서브넷(Public Subnet) / 프라이빗 서브넷(Private Subnet)

VPC를 여러개의 서브넷으로 나눌 때 가장 많이 활용하는 방식이 외부에서 접근이 가능한 네트워크와 외부에서 접근이 불가능한 네트워크로 나누는 방식이다.

  • 퍼블릭 서브넷(Public Subnet) : 외부에서 접근이 가능한 서브넷
  • 프라이빗 서브넷(Private Subnet) : 외부에서 접근이 불가능한 서브넷

 

VPC와 서브넷을 세팅하고 해당 서브넷에 EC2를 배치할 수 있지만 EC2에 접속을 할수는 없다.

이는 인터넷 게이트웨이를 설정하지 않았기 때문이다.

 

아래 더보기를 클릭하면 서브넷을 생성하는 방법을 확인할 수 있다.

더보기

1. 서브넷 생성 페이지로 들어가기

  

2. 서브넷 생성하기

 

3. 서브넷 생성 완료

 

아래 더보기를 클릭하면 퍼블릭 서브넷에 EC2를 배치하는 방법을 확인할 수 있다.

더보기

1. EC2 인스턴스 생성 페이지로 이동

 

2. EC2 인스턴스 옵션 선택하기

 

3. 키 페어 생성하기 

 

4. 나머지 EC2 인스턴스 옵션 설정하기

 

인터넷 게이트웨이(Internet Gateway)

인터넷 게이트웨이(Internet Gateway)란 VPC와 외부 인터넷 간에 통신할 수 있게 해주는 장치이다.

인터넷 게이트웨이는 아래 그림과 같이 외부 인터넷과 소통할 수 있는 출입구라고 생각하면 이해하기가 편하다.

마지막으로 라우팅 테이블까지 잘 세팅해주어야 외부 인터넷과 통신을 할 수 있게 된다.

 

아래 더보기를 클릭하면 인터넷 게이트웨이를 생성하는 방법을 확인할 수 있다.

더보기

1. 인터넷 게이트웨이 생성 페이지로 이동하기

 

2. 인터넷 게이트웨이 생성하기

 

3. 인터넷 게이트웨이 연결하기

 

라우팅 테이블(Routing Table)

라우팅 테이블(Routing Table)은 트래픽을 어디로 전송해야 하는 지 경로를 알려주는 테이블이다.

Routing Table에서 Routing이 ‘길을 정하다’라는 의미를 내포하고 있는 걸 보면, 이름에서도 그 의미를 유추할 수 있다.

 

VPC 내부에 EC2 인스턴스가 있고, 이 인스턴스가 VPC 외부에 있는 특정 컴퓨터와 통신을 하고 싶다고 가정하자. 그럼 EC2 인스턴스 입장에서는 외부 인터넷에 있는 컴퓨터와 통신을 해야 하기 때문에 인터넷 게이트웨이를 거쳐가야 한다. 

하지만 EC2 인스턴스가 특정 컴퓨터로 통신을 보내려고 해도 어떤 방향으로 트래픽을 보내야 하는 지 모르기 때문에, EC2 인스턴스가 어떤 경로로 트래픽을 전송해야 되는 지 알려주는 장치가 바로 라우팅 테이블(Routing Table)이다. 

 

아래 더보기를 클릭하면 라우팅 테이블을 생성하는 방법을 확인할 수 있다.

더보기

1. 라우팅 테이블 생성 페이지로 들어가기

 

2. 라우팅 테이블 생성하기

VPC 내부에서 10.0.0.0/16로 보내는 트래픽은 local로 보내라는 뜻이다.

local로 보낸다는 건 Prviate IP를 활용해 내부에서 통신을 하겠다는 의미이다. 

 

3. 라우팅 테이블에 서브넷 연결하기

 

4. 라우팅 편집하기

0.0.0.0/0은 “모든 IPv4 주소”를 의미한다.

따라서 VPC 내부에서 IPv4 주소로 보내는 모든 트래픽은 인터넷 게이트웨이로 보내라는 뜻이다. 

 

모순적인 부분이 있다.

10.0.0.0/16으로 보내는 트래픽을 local로 보내라고 하지만, 0.0.0.0/0은 모든 IPv4 주소의 모든 트래픽을 인터넷 게이트웨이로 보내라고 한다.

그런데 두 조건을 둘 다 만족하는 IP 주소일 경우(ex. 10.0.0.5)에는 0.0.0.0/0의 주소보다 10.0.0.0/16의 주소가 더 구체적이기 때문에, 10.0.0.5로 트래픽을 보내는 경우에는 local로 보내게 된다.

 

여기까지 완료했다면 VPC의 서브넷에 배치되어 있는 AWS 리소스가 외부 인터넷과 통신을 할 수 있을 것이다.

 

여기까지 세팅했다면 아래와 같은 인프라 아키텍쳐가 된다.

 

NAT 게이트웨이

  • 프라이빗 서브넷에서는 퍼블릭 서브넷과 달리 인터넷 게이트웨이를 셋팅하면 안 된다.
  • 왜냐하면 인터넷 게이트웨이는 VPC와 외부 인터넷 간에 통신할 수 있게 해주는 장치이기 때문이다. 프라이빗 서브넷은 보안을 위해 외부에서 접근이 불가능하게 만들어야 한다.
  • 따라서 프라이빗 서브넷은 인터넷 게이트웨이 대신에 NAT 게이트웨이를 셋팅해야 한다.

 

NAT 게이트웨이는 내부에서 외부로만 나갈 수 있는 출입구라고 생각하면 이해하기 편하다. 

 

NAT 게이트웨이는 외부 인터넷에서 서브넷으로 접근할 수는 없지만 서브넷에서 외부 인터넷으로 접근할 수 있게 해주는 장치다. 

인터넷 게이트웨이는 외부 인터넷 → 서브넷의 방향으로도 통신이 가능했고, 서브넷 → 외부 인터넷의 방향으로도 통신이 가능하다.

반면 NAT 게이트웨이는 서브넷 → 외부 인터넷의 방향으로만 통신이 가능하다는 뜻이다.

 

외부 인터넷 → 서브넷 방향의 통신

  • 서브넷에 포함된 EC2 인스턴스의 백엔드 서버로 API 요청
  • 서브넷에 포함된 EC2 인스턴스에 SSH로 접속

 

서브넷 → 외부 인터넷 방향의 통신

  • 서브넷에 포함된 EC2 인스턴스에서 외부 API(ex. 날씨 API, OpenAI API 등) 호출
  • 서브넷에 포함된 EC2 인스턴스에서 소프트웨어(ex. Nginx, git 등) 설치

 

 

NAT 게이트웨이는 VPC에 연결하는 것도 아니고, 프라이빗 서브넷에 연결하는 것도 아니다. NAT 게이트웨이는 퍼블릭 서브넷에 연결을 한다. 

 

NAT 게이트웨이 생성

위 그림까지 아키텍쳐가 구성되었다고 가정.

 

1. NAT 게이트웨이 생성 페이지로 이동하기

 

 

2. NAT 게이트웨이 생성하기

  • 연결 유형 : 외부 인터넷과 통신할 수 있게 만들기 위해 퍼블릭을 선택

 

NAT 게이트웨이는 생성되는 데 1~2분 정도의 시간이 걸리니 조금만 기다리면 된다.

 

3. 라우팅 테이블 생성하기

라우팅 테이블을 만들어서 트래픽이 프라이빗 서브넷 → NAT 게이트웨이의 방향으로 이동할 수 있게 경로를 설정해야한다.

 

4. 라우팅 테이블에 서브넷 연결하기

 

5. 라우팅 편집하기

이 페이지가 ‘어떤 경로로 트래픽을 전송해야 하는 지’를 직접 정의해야 하는 페이지다.

  • VPC 내부에서 10.0.0.0/16로 보내는 트래픽은 local로 보내라는 뜻이다. local로 보낸다는 건 Private IP를 활용해 내부에서 통신을 하겠다는 의미이다.
  • 0.0.0.0/0은 “모든 IPv4 주소”를 의미한다. 따라서 ‘VPC 내부에서 IPv4 주소로 보내는 모든 트래픽은 NAT 게이트웨이로 보내라는 뜻이다.

그리고 AWS 공식 문서에 따르면 ‘IP 주소 범위가 더 구체적인 조건을 우선 적용한다’고 적혀 있다.

즉, 0.0.0.0/0의 주소보다 10.0.0.0/16의 주소가 더 구체적이기 때문에, 10.0.0.5로 트래픽을 보내는 경우에는 local로 보내게 된다.

또한 10.0.0.0/16에 해당하지 않는 IP 주소로 요청을 보내면 NAT 게이트웨이로 트래픽을 보낸다.

 

프라이빗 서브넷에 EC2 배치

1. EC2 인스턴스 생성 페이지로 이동

 

2. EC2 인스턴스 옵션 선택하기

 

3. 키 페어 생성하기

 

4. 나머지 EC2 인스턴스 옵션 설정하기

 

5. EC2 인스턴스에 접속하기

  • 위 캡쳐 화면에서 퍼블릭 IPv4가 할당되지 않았고, 인스턴스가 퍼블릭 서브넷에 없어서 접속이 안 된다고 경고한다.
  • 집에 있는 컴퓨터로 EC2 인스턴스에 접속하는 것도 ‘외부 인터넷 → 서브넷’ 방향의 요청이기 때문에 접속이 안 된다.
  • 즉, 프라이빗 서브넷이 제 역할을 하고 있다는 뜻이기도 하다. 

 

이제 아래와 같이 아키텍쳐가 구성되었다.

현재 구성에서 인터넷에서 프라이빗 서브넷에 있는 EC2 인스턴스로 접근할 수 있는 경로 자체가 없다. 이 때문에 외부에서 접속할 수가 없다. 

 

프라이빗 서브넷의 EC2에 접속

  • 프라이빗 서브넷(Private Subnet)은 외부에서 접근이 불가능하다.
  • 하지만 같은 VPC 내부에서는 퍼블릭 서브넷의 리소스와 프라이빗 서브넷의 리소스가 자유자재로 통신이 가능하다.

 

1. 로컬 컴퓨터에서 퍼블릭 서브넷에 존재하는 EC2 인스턴스에 접속

$ cd [키 페어 파일이 존재하는 경로]
$ chmod 400 "web-server.pem" # 키 페어 파일 보안을 위한 권한 설정
$ ssh -i "web-server.pem" ubuntu@[EC2 인스턴스의 Public IP]

 

2. 퍼블릭 서브넷에 위치한 EC2 인스턴스로 키 페어 파일 보내기

  • 퍼블릭 서브넷에 위치한 EC2 인스턴스(web-server)에서 프라이빗 서브넷에 위치한 EC2 인스턴스(instagram-server)로 접속할 것이다. web-server 인스턴스에서 instagram-server 인스턴스로 접속하는 게 가능한 이유는 같은 VPC에 존재하기 때문이다. 
  • web-server 인스턴스에 접속할 때 web-server의 키 페어가 필요했던 것처럼, instagram-server 인스턴스에 접속할 때는 instagram-server의 키 페어가 필요하다. 따라서 instagram-server의 키 페어를 web-server 인스턴스로 전송해야 한다.

$ cd [키 페어 파일이 존재하는 경로]

# scp -i [EC2 접근을 위한 키 페어 파일] [전송할 파일명] [서버 username]@[EC2 인스턴스의 Public IP]:[전송 받을 파일 위치]
$ scp -i web-server.pem instagram-server.pem ubuntu@[EC2 인스턴스의 Public IP]:~/

 

3. web-server 인스턴스로 키 페어 파일이 잘 전송됐는지 확인

 

4. instagram-server로 접속해보기

$ cd [키 페어 파일이 존재하는 경로]
$ chmod 400 "instagram-server.pem" # 키 페어 파일 보안을 위한 권한 설정
$ ssh -i "instagram-server.pem" ubuntu@[EC2 인스턴스의 프라이빗 IP]

  • ubuntu@ 뒤에 보면 각 인스턴스의 Private IP가 작성되어 있다. @ 뒤에 적혀있는 부분이 각 컴퓨터에 붙여놓은 닉네임을 뜻한다.
  • 이걸 보고 리눅스에서는 hostname이라고 부른다. instagram-server에 접속하기 전후의 hostname을 비교해보니 잘 접속이 됐다는 걸 확실하게 확인할 수 있다. 

 

Bastion Host
프라이빗 서브넷에 있는 AWS 리소스인 EC2 인스턴스에 접근하기 위해, 퍼블릭 서브넷에 있는 EC2 인스턴스를 활용했다.
이와 같이 프라이빗 서브넷의 AWS 리소스에 접근하기 위해 앞단에 배치한 EC2(퍼블릭 서브넷에 위치한 EC2)를 보고 Bastion Host라고 부른다.
Bastion Host를 활용해 외부에서 접근할 수 있는 경로는 딱 하나만 만들면 외부에서 접근할 수 있는 경로는 단 하나이기 때문에 보안적인 조치를 하기도 쉽고 관리도 쉬워진다.

호스트 네임은 아래의 명령어로 수정할 수 있다.
$ sudo vi /etc/hostname​


호스트 네임을 바꾸었다면 재부팅 후에 적용이 된다.

$ sudo reboot # EC2 인스턴스 재시작하기​