AWS Cloud 네트워크의 기본, AWS VPC
AWS VPC는 사설 네트워크를 제공하는 서비스이다. VPC는 하나 이상의 서브넷으로 구성되어 있다. 서브넷은 IP 주소 범위를 의미하고, 이는 VPC 내에 특정 구역을 나타낸다. 각 서브넷은 패킷 전송을 위한 라우팅 테이블을 가지고 있다. 연결된 라우팅 테이블에 따라 서브넷의 성격이 달라진다. 인터넷 게이트웨이가 연결되어 있다면, 외부와 양방향 소통이 가능한 Public 서브넷이다. NAT 게이트웨이를 통해 인터넷과 아웃바운드 통신만 가능하다면 Private 서브넷이라 부른다.
AWS VPC(Virtual Private Cloud)는 사설 네트워크를 제공하는 서비스이다. 네트워크는 서버 간 통신을 위해서 반드시 필요한 요소이다. 사용자는 AWS VPC를 통해 자신만의 네트워크를 직접 정의할 수 있다. 사용자는 직접 네트워크를 만들고 라우팅을 설정하며, 그 위에 서버를 올린다. 이 네트워크에 올라간 서버들은 고유하게 IP를 하나씩 할당받는다. 따라서 같은 네트워크에서는 서로를 고유하게 인식할 수 있다. 마치 한 가족에서 두 명이 같은 이름을 사용하지 않는 것과 같다.
여기서 중요한 건, AWS VPC는 사설 네트워크를 제공한다는 점이다. 사설 네트워크는 회사가 내부에서만 사용하는 네트워크를 뜻한다. 회사는 자신이 사용하는 서버끼리만 통신하도록 네트워크를 구성한다. 서버는 사설 네트워크 대역 안에서 고유한 IP를 할당받는다. 이를 사설 IP라고 한다. 사설 IP를 받은 서버는 사설 네트워크 안에서만 다른 서버와 통신할 수 있다. 하지만 사설 네트워크 밖과는 직접 통신할 수 없다.
사설 네트워크 말고 공용 네트워크도 있다. 공용 네트워크는 우리가 흔히 알고 있는 인터넷 네트워크이다. 인터넷은 전 세계가 공통으로 사용한다. 인터넷을 통하면 전 세계 어느 곳이든 닿을 수 있다. 우리가 구글에서 검색할 수 있는 이유도 구글이 인터넷상에 서비스를 올렸기 때문이다. 만약 구글에서 자사만 쓰겠다고 사설 네트워크에만 서비스를 올리면, 우리는 더 이상 구글을 사용할 수 없다.
사설 네트워크와 공용 네트워크는 서로 다른 두 네트워크이다. 공용과 사설을 구분하는 건 어떠한 특성 때문이 아니다. 그저 서로 다른 두 네트워크일 뿐이다. 공용 네트워크는 인터넷을 통해서 서비스를 연결하기 위한 네트워크이다. 공용 네트워크 상에 올라간 서버는 전 세계에서 유일한 IP 주소를 할당받는다. 예컨대, 100.20.10.0/32라는 IP를 가진 서버가 있다면, 다른 서버는 같은 IP를 사용할 수 없다. 그래야 인터넷상에서 해당 서버를 고유하게 식별하고 그 서버와 통신할 수 있기 때문이다.
사설 네트워크도 마찬가지다. 사설 네트워크는 회사나 집처럼 특정 공간에서만 사용하기 위한 네트워크일 뿐이다. 사설 네트워크에 올라간 서버는 사설 IP를 할당받는다. 사설 IP를 가진 서버는 자신과 같은 네트워크에 속한 서버만 인식할 수 있다. 왜냐하면 같은 네트워크 안에서 사설 IP는 고유하게 사용되기 때문이다. 만약 서로 다른 서버가 같은 IP를 가진다면, 라우터(Router)는 트래픽을 누구에게 보내야 할지 알 수가 없다. 이러한 사태를 막기 위해 사설 네트워크 상에서 사설 IP는 모두 고유하게 하나의 서버에만 할당된다.
그러면 네트워크 간 통신은 어떻게 이루어질까?
네트워크 통신은 출발지와 목적지를 기반으로 이루어진다. 출발지는 통신을 시도하는 서버이고, 목적지는 통신하고자 하는 서버이다. 출발지 서버는 자신이 통신하고 싶은 목적지 서버의 IP를 패킷에 적어서 라우터에 보낸다. 라우터는 자신이 식별하고 있는 네트워크를 라우팅 테이블로 관리한다. 라우터는 라우팅 테이블에서 목적지 서버 IP에 해당하는 네트워크를 찾는다. 만약 테이블에 있으면 다음 목적지로 네트워크 패킷을 전달한다. 아니라면, 라우터는 해당 패킷을 그냥 버린다.
아무런 설정을 하지 않으면, 라우터는 자신이 속한 네트워크만 관리한다. 다시 말해, 라우팅 테이블에 자신이 속한 네트워크에 대한 설정만 유지한다. 공용 네트워크나 다른 사설 네트워크의 존재는 알 수가 없다.
만약 서로 다른 네트워크 간 통신을 하고 싶으면, 라우터를 연결해야 한다. 먼저, A 네트워크와 B 네트워크에 각각 라우터를 둔다. 이 상태에서 두 라우터는 아직 소통할 수가 없다. 하지만 두 라우터를 위해서 별도의 C 네트워크를 구성하면 통신이 가능하다. A 라우터와 B 라우터가 서로를 식별할 수 있는 IP를 C 네트워크 상에서 받을 수 있기 때문이다. 이제야 A 네트워크 서버는 B 네트워크 서버와 통신할 수 있다.
사설 네트워크과 공용 네트워크도 이와 비슷한 방법으로 연결된다. 사설 네트워크 대역과 공용 네트워크 대역이 다르므로 중간에 중개자가 필요하다. 하지만 이 때는 중간에 별도의 네트워크를 두지 않는다. 사설 네트워크에 라우터와 비슷한 서버를 하나 설치하고, 공용 네트워크에 속한 IP 하나를 할당한다. 즉, 해당 서버는 사설 네트워크, 공용 네트워크 모두와 소통이 가능하다. 이러한 서버를 우리는 NAT 서버라고 한다.
NAT 서버는 서로 다른 네트워크에서 통신을 할 때 IP를 변환해 주는 서버이다. 출발지와 목적지 서버는 모두 NAT 서버와 통신할 수 있다. 출발지 서버는 목적지 서버와 통신하기 위해 패킷을 NAT 서버로 전송한다. NAT 서버는 NAT 테이블에 출발지와 목적지 매핑 정보를 저장한다. 그리고 목적지로 패킷을 보낼 때, 출발지 IP를 자신의 공인 IP로 교체한다. 왜냐하면 목적지가 패킷을 받았을 때 출발지가 누군지 알아야 하기 때문이다.
목적지 서버 입장에서는 패킷을 받았을 때, 출발지 서버의 존재를 모른다. 그저 NAT 서버가 보냈다고 생각하고, 응답을 줄 뿐이다. 응답을 받은 NAT 서버는 NAT 테이블을 보고 원래 출발지로 응답을 전달한다. 이렇게 하면 출발지와 목적지 서버는 서로 통신할 수 있다.
AWS에서 NAT 서버라고 하면, 보통 인터넷 통신에 사용하는 NAT 게이트웨이를 의미한다. 그렇지만 NAT라는 용어가 꼭 인터넷 연결을 의미하는 건 아니다. 사설 네트워크 간 통신을 하더라도, 중간에서 IP를 변환하여 통신을 가능하게 하면 NAT라고 부른다. 상황에 맞게 용어를 구분해 이해할 필요가 있다.
AWS VPC는 서브넷, 라우팅 테이블 등 다양한 구성요소들을 포함한다. VPC의 구성요소는 사설 네트워크를 구축하는데 필요한 기능을 수행한다.
VPC만 생성하면 특정 CIDR 대역을 가진 네트워크가 생성된다. 이 네트워크에는 아무도 들어가지 못하고, 아무도 나가지 못한다. 이 VPC는 다른 네트워크와 완전히 격리되어 있다.
VPC에 서버를 올리기 위해서는 서브넷이 필요하다. 서브넷은 VPC의 IP 주소 범위이다. 사용자는 VPC 전체 대역을 용도에 맞게 나누어 서브넷을 구성한다. 예컨대, 공용 네트워크와 통신할 서버 구역, 데이터베이스를 올릴 서버 구역처럼 서브넷을 구분할 수 있다. 이때 서브넷 간 IP 대역이 겹치면 안 된다.
보통은 아래와 같이 3개의 구간을 만든다.
1. 인터넷과 인바운드/아웃바운드 통신이 모두 가능한 구간: 인바운드 트래픽을 받을 수 있는 로드밸런서(Load Balancer)나 아웃바운드 트래픽을 위한 NAT 서버를 올리기 위한 서브넷
2. 인터넷으로 아웃바운드 통신만 가능한 구간: 일반 웹, 앱 애플리케이션을 위한 서브넷
3. 인터넷과 아예 소통이 불가한 구간: 데이터베이스를 위한 서브넷
일반적인 서비스를 위해 네트워크를 구성한다면, 위와 같이 3가지 구역만으로 충분하다. 위 3가지 구분은 AWS에서 지원하는 기능이 아니다. 사용자가 직접 설계하는 것이다. 사용자는 라우팅 테이블을 통해 기능을 구분할 수 있다. 라우팅 테이블에 인터넷 게이트웨이를 연결하면 1번 구간이 된다. 만약, NAT 게이트웨이를 연결하면 2번 구간, 아무것도 연결하지 않으면 3번 구간이 된다. 이처럼 사용자가 라우팅테 이블에 어떤 규칙을 넣느냐에 따라 서브넷의 용도는 달라진다.
서브넷은 하나의 가용영역만 선택할 수 있다. 가용영역은 물리적인 데이터센터를 의미한다. 즉, 서브넷 구역을 정할 때 하나의 데이터센터를 지정한다. 서브넷을 하나만 만들면 하나의 가용영역만 사용할 수 있다. 같은 용도로 여러 가용영역을 사용하고 싶다면, 서브넷을 가용영역 수만큼 생성해야 한다.
여러 가용영역을 사용하는 이유는 사용 가능성을 높이기 위함이다. 이는 데이터센터에 언제든지 장애가 발생할 수 있기 때문이다. 만약 관리자가 실수로 서버 전원을 끄면 그 서버 위에 있는 모든 서비스는 죽는다. 최악의 경우, 데이터센터에 불이 나면 아예 통신이 마비가 될 수도 있다. 이러한 경우에도 우리는 고객에게 서비스를 제공할 수 있어야 한다. 그래서 여러 데이터센터에 같은 서비스를 올려서 가용성을 높이는 것이다.
안정적인 서비스를 위해서는 3개의 가용영역을 두는 것이 좋다. 왜냐하면 가용영역 1개가 사용할 수 없는 상황에서도 이중화가 가능하기 때문이다. 설령 데이터센터 2개가 장애를 겪어도, 고객은 서비스를 이용할 수 있다.
위 그림처럼 서브넷을 총 9개로 구분한다고 가정하자. VPC대역이 /16 대역으로 큰 편이므로, 서브넷에도 큰 CIDR대역을 부여할 수 있다. 서브넷당 /20 대역을 부여해도 총 16개 서브넷을 만들 수 있다. 만약 /20보다 작게 설정한다면 더 많은 서브넷을 구성할 수 있다. 혹은 서브넷 용도에 맞게 서브넷의 IP 대역을 다르게 줄 수도 있다.
다만, 서브넷 대역을 설계할 때는 다음의 사항을 주의해야 한다.
- 특별한 경우라면, 서비스별도 서브넷을 구분하지 않는다. AWS에서는 보안 그룹을 통해서 서비스를 안전하게 보호할 수 있기 때문에 라우팅을 분리할 필요가 없다. 차라리 여러 개를 합쳐서 하나의 큰 서브넷을 만드는 편이 좋다.
- 확장성을 고려해서 서브넷은 가능한 크게 만든다. AWS 관리형 서비스를 사용해도 VPC 내에 배포해야 하는 서비스는 IP를 할당받기 때문에 금방 부족해질 수 있다. 예컨대, 로드밸런서도 서브넷에서 사설 IP를 할당받는다.
- 서브넷 IP 대역 중 5개 IP는 AWS에서 예약하므로 사용할 수 없다.
아래는 /20으로 서브넷 대역을 설계한 예시이다. /20이면 서브넷 당 4096개 IP를 할당할 수 있다.(정확하게는 4096 - 5 = 4091개이다.)
라우팅 테이블은 서브넷에서 네트워크 통신이 발생할 때 적용되는 라우팅 규칙이다. 라우팅 테이블에 등록한 목적지 대역이 있어야 해당 대역으로 패킷을 전달할 수 있다. 앞서 언급했듯이, 라우팅 테이블 규칙에 따라 서브넷 목적이 달라진다.
라우팅을 정교하게 관리하려면 서브넷당 라우팅 테이블을 하나씩 만드는 걸 권장한다. 그러면 라우팅을 변경할 때 영향받는 서브넷 영역이 줄어든다. 하지만 똑같은 라우팅 규칙을 여러 곳에 추가해야 하는 부담이 있다. 만약 이 관리 비용이 많이 든다면, 같은 성격을 가진 서브넷 간에는 하나의 라우팅 테이블을 사용해도 무방하다. 예컨대, 목적은 동일하고 가용영역만 다른 서브넷끼리 같은 라우팅 테이블을 사용할 수 있다. 이때, 라우팅 테이블 규칙을 수정하면 연결된 모든 서브넷이 영향을 받으니 주의해야 한다. 만약 라우팅을 잘못 설정하면, 여러 서비스가 동시에 통신하지 못하는 상황이 발생할 수도 있다.
라우팅 테이블을 생성하면 기본으로 VPC IP 대역에 대한 라우팅 규칙이 추가된다. VPC IP대역은 local이라는 타깃을 사용하는데, 이는 VPC 내부 통신을 의미한다. 즉, 같은 VPC 안에 있는 서버끼리는 패킷을 주고받을 수 있다. 하지만 다른 대역에 대한 라우팅을 추가하지 않으면 VPC 외부와 통신할 수 없다.
Public 서브넷은 인터넷과 통신이 가능한 서브넷이다. 인터넷과 통신을 하려면 인터넷으로 나가는 창구가 필요하다. AWS는 인터넷 통신을 위해 인터넷 게이트웨이를 제공한다. 인터넷 게이트웨이를 사용하면 외부로 트래픽을 보낼 수 있고, 반대로 외부에서 트래픽을 받을 수도 있다.
인터넷 게이트웨이를 설치해도 인터넷과 바로 연결되지 않는다. Public 서브넷이 사용하는 라우팅 테이블에 인터넷 게이트웨이를 추가해야 한다. 이때 목적지 대상은 0.0.0.0/0을 사용한다. 0.0.0.0/0은 실제로 모든 IP 대역을 의미하지만, 라우팅 테이블에서는 "다른 설정에 해당하지 않는" 트래픽을 의미한다. 이는 라우팅 테이블이 구체적인 IP 대역에 우선순위를 부여하기 때문이다. /0 보다 /24가 더 범위가 좁고 구체적이기 때문에 우선순위를 높게 적용한다. 그래서 만약 0.0.0.0/0 말고 다른 라우팅 규칙 조건에 부합한다면, 그 대상으로 패킷을 전달한다.
아래는 인터넷 게이트웨이를 설정한 화면 예시이다.
Private 서브넷은 Public 서브넷과 다르게 아웃바운드만 인터넷과 통신할 수 있다. 아웃바운드는 서버 안에서 외부 인터넷을 호출하는 경우를 의미한다. 아웃바운드 트래픽이 인터넷으로 나가기 위해서는 라우팅 테이블 설정이 필요하다. Public 서브넷에는 인터넷 게이트웨이를 연동했는데, Private 서브넷에는 인터넷 게이트웨이를 사용하면 안 된다. 인터넷 게이트웨이는 인바운드/아웃바운드가 모두 가능하기 때문이다. 따라서 아웃바운드만을 위한 NAT 서버를 사용해야 한다.
AWS는 관리형 NAT 서비스로 NAT 게이트웨이를 제공한다. NAT 게이트웨이는 AWS가 직접 관리하는 완전 관리형 서비스이다. 완전 관리형이므로, 고객은 NAT 서버를 운영할 필요가 없다. NAT 게이트웨이는 인터넷과 통신해야 하므로 공인 IP가 필요하다. 사용자는 Elastic IP를 통해 공인 IP를 할당받을 수 있다. 다시 한번 강조하면, NAT 게이트웨이는 아웃바운드 전용이다. 외부에서 NAT 게이트웨이를 통해서 서버로 들어올 수는 없다.
아래는 NAT 게이트웨이를 생성한 예시이다. 표시된 부분을 보면, NAT 게이트웨이는 사설 IP와 공인 IP를 둘 다 가지고 있다. VPC 내부에서는 사설 IP로 통신하고, 인터넷으로 트래픽을 보낼 때는 공인 IP를 사용한다.
이렇게 하면 기본적인 사설 네트워크 구성은 끝났다. 특이사항이 없다면 위 구성으로 글로벌 규모의 서비스도 운영할 수 있다. 하지만 AWS에서는 더욱 안전하고 빠르게 서비스를 운영하기 위한 다양한 추가 기능들을 제공한다.
다음 편에서는 여러 VPC 간 통신을 설계하는 방법과 AWS 서비스를 안전하게 사용하는 방법에 대해 알아보고자 한다.
어색한 표현이나, 잘못된 내용을 댓글로 지적해 주시면 정정하겠습니다.