VPC란?
VPC는 Virtual Private Cloud의 약자로 클라우드 구성을 가상화된 private 공간에 두는 방식을 의미합니다. AWS의 인스턴스 상품군(EC2, RDS 등)은 기본적으로 VPC를 지정하게 되어있으며, AWS 계정을 처음 생성하면 default-vpc
가 생성되어 있습니다.
VPC가 왜 의무적으로 구성되어있는지 알아보려면 VPC가 구성되는 형태를 알아야 합니다. VPC는 서버 자원들로 구성된 네트워크입니다. 즉, 기본적으로 서버 자원간 연결의 기본이 되는 공간으로, 같은 네트워크에 속한 자원끼리는 자유롭게 통신할 수 있습니다. 여기에 VPC의 특성 2가지가 적용됩니다.
- 독립적인 가상의 네트워크 공간
- 사용자의 설정에 따라 자유롭게 구성 가능한 네트워크
독립적인 가상의 네트워크
독립적인 가상 네트워크라는 특성은 서버 자원들의 물리적 위치에 따른 네트워크 특성을 제거한다는 의미로 이해할 수 있습니다. 하나의 데이터센터에 존재하는 여러 가상 서버들을 독립된 데이터센터처럼 운영할수 있도록 데이터센터 망에서 분리시켜주는 형태로 이해하면 좋습니다. 이러한 독립적인 특성은 같은 데이터센터에 존재하는 여러 가상 서버들이 서로 침범하지 못하게 막아주는 역할을 기본적으로 수행합니다.
하지만, 독립적인 가상 네트워크여도 물리적인 제약을 완전히 분리해낼수는 없습니다. 쉽게말하면 복수의 데이터센터에 있는 여러 가상서버들을 하나의 VPC로 운영할 수는 없다는 의미입니다. (리전간 VPC-peering 으로 해결 가능 = https://docs.aws.amazon.com/ko_kr/vpc/latest/peering/what-is-vpc-peering.html)
물리적인 제약이 남아있는 특성은 AWS의 가용 영역(Availability Zone)과 리전(Region)을 이해하고 넘어가는 것이 좋습니다.
리전 – Region
리전이란 AWS의 데이터센터 여러개의 묶음을 의미합니다. 예를 들어 AWS 서울 리전은 AWS가 서울에 배치한 데이터센터들의 묶음을 의미하며, 국내에는 서울 1개, 일본에는 도쿄와 오사카 2개가 존재합니다.
가용 영역 – Availability Zone
가용 영역이란 하나의 리전(Region) 안에 구성된 물리적으로 분리된 데이터 센터입니다. 각각의 리전은 최소 2개의 가용 영역으로 구성되어, 단일 리전이라도 물리적으로 분리된 여러 데이터센터를 둠으로써 자연재해 등의 발생에도, 하나의 리전 전체가 중단되는 상황을 방지합니다. 서울 리전에는 총 4개의 가용 영역이 있으며, 각각의 가용 영역은 물리적으로 분리되어 장애에 독립적입니다.
물리적으로 분리된 가용 영역간에는 고성능의 네트워크가 연결되어 있어, 하나의 데이터센터처럼 작동하도록 구성되어 있습니다. 즉 하나의 리전은 하나의 데이터센터처럼 작동하되, 물리적으로 분리되어 있어 장애 상황에는 독립적으로 이용할 수 있도록 되어있습니다.
사용자의 설정에 따라 자유롭게 구성 가능한 네트워크
VPC는 데이터센터에서 논리적으로 분리된 네트워크 공간이기 때문에, 사용자가 자유롭게 IP 설정, 트래픽 제한, 라우팅, 엔드포인트 지정등을 수행할 수 있습니다. VPC를 생성할때는 기본적으로 CIDR 블록을 설정하게 되있는데, VPC내의 인스턴스들은 지정된 CIDR 블록 내의 로컬 IP를 할당받게 됩니다.
이렇게 할당한 CIDR 블록 범위내의 IP주소들을 대상으로 VPC의 세부 기능들을 활용해, 아웃바운드/인바운드 트래픽을 제한하거나, 특정 IP로의 접근을 모두 리다이렉트하거나, 특정 IP를 외부와 연결된 NAT 게이트웨이와 연결하여 VPC 외부와의 통신을 허가할 수 있습니다.
CIDR 블록이란?
IPv4 방식의 IP 주소를 지정하는 구조에서는 8개의 비트로 구성된 숫자 4개를 주소로 사용합니다.
127.0.0.1 = 01111111.00000000.00000000.00000001
IP주소의 범위를 표현하기 위해, 이러한 8비트 숫자 4개의 구성을 /16, /24, /32 와 같은 /n의 방식으로 IP뒤에 표시하고 이를 앞에서 n개의 비트는 고정이고, 이후는 범위다.라고 표현하는 방식입니다.
예시로 확인해보면 0.0.0.0/0
은 0.0.0.0부터 255.255.255.255까지 모든 IP를 의미하고, 127.0.0.1/24
는 127.0.0.0부터 127.0.0.255까지의 IP를 의미합니다. 더 나아가 10.0.0.175/28
은 00000110.00000000.00000000.10101111 에서 28번째 자리까지는 고정이고, 이후 4자리인 1111만 범위로 전환하여 10100000(160)부터 10101111(175)까지 총 16개의 IP를 의미합니다.
VPC의 구성
VPC는 논리적으로 분리된 영역인 만큼, AWS 내의 설정값만으로 자유롭게 열고/닫고/자를 수 있습니다. 이러한 과정에 필요로 하는 것들을 중요한 기능적 설정을 4가지로 볼 수 있는데 이는 서브넷, 네트워크 ACL, 라우팅 테이블, 게이트웨이입니다.
서브넷
서브넷은 VPC를 가용영역별로 나누어 구성하는 설정입니다. 하나의 VPC는 여러개의 가용 영역(데이터 센터)에 나누어져 있는 인스턴스들을 논리적으로 연결한 집합체이기 때문에, VPC내의 구성요소들에 대한 다양한 설정(트래픽/차단/라우팅 등)을 VPC 단위로 수행할 경우 장애 상황에 자유롭게 대응할 수 없습니다.
VPC 전체를 묶어 로드밸런서를 연결한다면, 특정 가용영역에 장애가 발생했을때, 해당 가용영역만 트래픽을 바로 제한하기 어렵습니다. VPC는 전체 네트워크를 묶어놓은 큰 덩어리이기 때문입니다.
이러한 상황을 방지하기 위해, AWS에서는 가용 영역별로 구성할 수 있는 서브넷을 제공하고, VPC내의 대부분의 설정이 서브넷을 타겟으로 구성하도록 되어있습니다. 이러한 방식을 통해, 가용 영역내에 있는 인스턴스들을 역할 단위로 묶어 각각의 독립적인 서브넷을 만들 수 있고, 이러한 서브넷마다 역할에 맞는 네트워크 설정을 적용할 수 있습니다.
예를 들어, Web 서버 역할을 수행할 인스턴스들을 가용 영역별로 1개씩 배치하고, 해당 인스턴스들 마다 서브넷을 1개씩 생성해줍니다. 이러한 방식은, 로드 밸런서 등을 적용한 실 서비스 운영 과정에서 발생할 수 있는 문제 상황에 빠르게 대처할 수 있도록 도와줍니다.
서브넷은 가용 영역 단위로 크게 만들기 보다는, 가용 영역 내에서도 각각의 인스턴스들의 역할에 따라 독립적으로 생성해주는 것이 좋습니다. VPC의 설정들은 대부분 서브넷 단위로 수행되기 때문에, Web 서버들의 서브넷과 DB 서버들의 서브넷을 분리하여, DB 서버는 3306 포트만 inbound를 허가하고, web 서버들은 80, 433 포트만 허가하도록 함으로써 보안성을 챙겨갈 수 있습니다. (네트워크 ACL 또는 보안그룹 등 다양한 설정 방법이 존재)
즉, 서브넷을 통해 우리는 동일한 역할을 수행하는 인스턴스들을 묶어 동일한 네트워크 설정을 적용할 수 있습니다. 이를 위해 처음 프로젝트를 시작할 때 부터 Web, API, DB, LoadBalancer 등 AWS의 인스턴스 단위별로 서브넷을 만들어두는 것이 좋습니다.
네트워크 ACL
VPC 내부에 구성된 서브넷을 실질적으로 AWS 내의 인스턴스들이 외부와 커뮤니케이션하는 과정에서 보안을 담당하는 기능입니다. 반대로, 보안 그룹(Security Gruop)은 네트워크 내부 간 통신을 담당하는 보안 기능으로 인스턴스 단위로 설정이 가능합니다. 즉 네트워크 ACL은 창문 역할을, 보안 그룹은 각 방의 방문 역할을 수행하는 것이라 이해하면 좋습니다.
외부와의 트래픽을 보호하는 보안 기능이기 때문에 모든 서브넷은 1개의 네트워크 ACL을 반드시 구성하도록 되어있으며, VPC가 생성되면 기본 네트워크 ACL이 생성됩니다. 네트워크 ACL은 기본적으로 모든 In/Out Bound를 차단하며, 최초 생성되는 기본 네트워크 ACL은 모든 트래픽을 허용하도록 추가 설정이 적용되어 있습니다.
직접 새로운 네트워크 ACL을 만들 경우, 허용할 규칙을 직접 설정해주어야 외부와 정상적인 통신이 가능합니다. 특히 네트워크 ACL은 동일한 포트에 대해 Inbound와 Outbound가 모두 열려있어야만 정상 작동하도록 설계되어 있습니다. (Stateless 한 특성 = 세션을 기억하지 않아, 최초 요청이 inbound인지 아닌지 판단하지 않음)
따라서, 80포트를 열어주고 싶다면, 인바운드 규칙만 열어주지 말고 아웃바운드 규칙에서도 80포트를 열어주어야, 인바운드로 요청된 네트워크가 서브넷을 거쳐 다시 바깥으로 나갈 수 있습니다. 만일 인바운드 규칙만 설정하게 되면, 서버에 요청한 트래픽이 되돌아나오지 못해 결과값을 받지 못합니다.
라우팅 테이블
라우팅 테이블이란 IP주소에 트래픽 라우팅 경로를 설정하고 이를 통해 in/out bound 트래픽에 대한 경로를 설정해주는 기능입니다. 들어오는 트래픽과 나가는 트래픽 모두를 목적지에 따라 적당한 경로로 전달시켜주는 역할입니다.
서브넷이 VPC 외부와 연결되기 위해 인터넷 게이트웨이에 연결하고자 할때도, 이 라우팅 테이블을 통해 모든 대상(목적지)를 인터넷 게이트웨이로 돌려주도록 경로 설정을 해야만 서브넷 내부의 인스턴스가 바깥으로 나갈 수 있습니다. 또한, 서브넷 내부의 IP 경로에 대해서는 서브넷 내부에서 처리되도록 그 경로를 지정할 수 있습니다.
일반적으로는 서브넷마다 독립적인 라우팅 테이블을 만들어주거나, 동일한 역할을 수행하는 서브넷끼리 같은 라우팅 테이블을 연결시켜주어 일괄적으로 관리할 수 있습니다. 라우팅 테이블은 AWS의 모든 게이트웨이와 인터페이스, 피어링 연결을 포함해 네트워크 경로를 모두 지정할 수 있기 때문에, 라우팅 테이블을 잘 설계해두면 상황에 따라 능동적으로 네트워크 상황을 변경할 수 있습니다.
게이트웨이
게이트웨이는 크게 Internet Gateway와 NAT gateway를 이해할 필요가 있습니다.
Internet Gateway는 VPC 내부의 리소스(특히 서브넷)이 인터넷과 연결될 수 있도록 하는 AWS 요소입니다. AWS 내에서 IGW로 표기되며, 인터넷 게이트웨이가 서브넷에 연결되어 있지 않으면, 단순히 sudo apt update
마저 정상적으로 작동하지 않습니다. (서브넷, VPC 외부로 트래픽이 나가지 못해 ubuntu update 항목 조회를 수행하지 못합니다.)
서브넷 외부로 트래픽이 발생해야 하는 경우는 항상 Internet Gateway가 연결되어야 하는데, 외부와 단절된 Private Subnet인 경우 IGW 대신 NAT Gateway를 사용하기도 합니다.
NAT은 Network Address Translation의 약자로 요청된 패킷의 주소/포트/정보 등에 대해 지정된 규칙에 맞추어 변환하는 기능을 의미합니다. NAT 게이트웨이는 주로 외부에 내부망의 IP 정보를 전달하지 않기 위해 사용하는데, 이를 위해 NAT 게이트웨이에는 Public IP(Elastic IP)를 지정하여, 외부로 나온 트래픽의 패킷은 모두 EIP에서 발송된 것으로 변환합니다.
또한 서브넷간 통신이 이루어질때에도 NAT 게이트웨이를 거쳐 여러 인스턴스들의 IP주소를 모두 허가해줄 필요 없이, 단일 IP만을 허가(DB 권한 등)하여 관리할 수 있도록 하는 편의성을 충족할 수 있습니다.
VPC 돌아보기.
VPC는 VPC 자체로써는 큰 의미가 없는 기능입니다. 실제로 인스턴스를 구성하고, 인스턴스 간 통신/외부-인스턴스 간 통신 등을 구성할때 비로소 기능적 설정을 하게 됩니다. 이때문에 처음 AWS를 셋팅할때는 인스턴스 생성과정에서 자동으로 생성되는 서브넷, 게이트웨이 등을 이용하게 되어 왜 인스턴스에 접속이 안되는지 잘 모를때가 많습니다.
처음부터 인스턴스를 바로 생성해서 나중에 VPC를 셋팅하기 보다는, 클라우드 설계 과정에서는 외부망/내부망/인스턴스 순으로 순차적인 네트워크 흐름을 고려하며 설계하는 것이 더욱 효과적입니다. 따라서, 인스턴스부터 빠르게 만들기보다는 VPC에 대해 충분히 이해하고, VPC와 서브넷, 게이트웨이와 라우팅 테이블 등을 어떻게 구성할지 구상한 뒤 인스턴스를 그에 맞추어 셋팅하는 것이 좋겠습니다.