brunch

You can make anything
by writing

C.S.Lewis

by 이권수 Aug 06. 2023

2. 여러 VPC 간 통신망 구성

서비스가 커지게 되면 어떻게 네트워크를 확장할 수 있을까?

요약

서비스가 커지면서 자연스럽게 네트워크 구성도 복잡해진다. 이때 하나의 서비스를 위해 여러 VPC 사설 네트워크 간 통신이 발생할 수 있다. 사용자는 VPC Peering, Transit 게이트웨이(TGW) 서비스를 통해 이러한 요구사항을 해결할 수 있다.


VPC Peering은 두 VPC 간 직접 통신을 지원한다. 먼저, Peering을 요청하고 수락하는 과정을 통해 연결을 맺는다. 연결을 통해 생성된 Peering ID를 통해 직접 통신이 가능하다. TGW는 Peering과 다르게 중간에서 패킷을 전달해 준다. TGW는 별도의 라우팅 테이블을 통해 라우팅을 제어한다. 사설 네트워크는 Attachment를 통해 TGW와 연결을 맺는다. 라우팅 테이블에 경로를 추가할 때 어떤 Attachment로 패킷을 전송할지 선택한다.


언제 VPC 간 통신이 필요할까?

서비스가 커지면 자연스럽게 조직이 커지고, 그에 따라 새롭게 등장하는 서비스도 많아진다. 새롭게 등장하는 서비스는 독립적인 환경을 보장하기 위해 별도의 사설 네트워크를 요구할 수 있다. 하나의 서비스를 글로벌로 확장하는 경우에도 VPC가 별도로 필요하다. 물리적으로 가까운 데이터센터에 서비스를 올리면 속도를 개선할 수 있기 때문이다. 마지막으로, 인수합병을 하는 경우도 있다. AWS를 사용한다고 가정하면, 합병하고자 하는 서비스는 자신만의 VPC를 가지고 있다.


어떤 경우든 서로 다른 VPC끼리 통신할 수 있어야 한다. 이는 서비스 간 통신일수도 있고, 같은 서비스 내에서 지역 간 통신일수도 있다. 변하지 않는 건, 두 사설 네트워크 간 통신이 필요하다는 점이다. 간편하게 통신하는 방법은 인터넷을 사용하는 것이다. 이전 글에서 언급했던 NAT 게이트웨이를 사용하면 인터넷 네트워크를 통해 통신할 수 있다.


A VPC와 B VPC 사이에서 인터넷을 통해 통신하는 구조는 다음과 같다. 이 시나리오에서는 A 서버에서 B 서버를 호출하고 있다.

두 서비스가 서로 인터넷을 통해 연결하는 경우

1. 먼저 A 서버와 B 서버는 서로를 인지할 수 없다. 왜냐하면 서로 다른 사설 네트워크에 있기 때문이다.

2. B 서버를 호출할 수 있도록 로드밸런서(Load Balancer)를 앞단에 설치한다. 로드밸런서는 뒷단에 서버에 요청을 분산시켜 주는 역할을 한다. 즉, 외부 요청을 먼저 받은 후에 뒤로 흘려준다. 외부 요청을 받아야 하므로 공인 IP가 필요하다. 외부에서는 B 서버에 요청을 보내기 위해 로드밸런서를 호출한다.

3. A 서버는 로드밸런서 IP를 목적지로 설정하고 통신을 시도한다. 하지만 로드밸런서는 인터넷 네트워크이므로 A 서버가 직접 통신할 수 없다.

4. A 서버는 NAT 서버로 트래픽을 보내고, NAT 서버는 자신의 공인 IP로 출발지를 변경한 후에 로드밸런서와 통신을 시도한다.

5. 로드밸런서는 NAT 서버로부터 온 요청을 B 서버로 전달한다.


이 방식은 인터넷을 통해 간편하게 통신할 수 있지만, 속도가 느리고 보안에 취약하다. 인터넷 네트워크는 공유자원인만큼 네트워크 혼잡도가 높다. 다른 사람이 대량으로 패킷을 전송할 때 동시에 요청을 보내면, 내 패킷이 늦게 전달될 수도 있다. 또한 인터넷 네트워크에서는 누구나 패킷을 볼 수 있다. 물론 HTTPS 프로토콜을 사용하면 패킷 자체는 암호화되어 있지만, 그래도 패킷을 중간에서 가로챌 수 있다는 건 변하지 않는다. 혹여나 HTTP로 통신하는 상황이 발생하면 해커는 패킷의 내용까지 낱낱이 볼 수 있다.


AWS는 속도와 보안을 동시에 챙기기 위해 AWS 자체 네트워크를 사용한다. 이를 AWS Global Backbone 네트워크라고 한다. AWS Global Backbone 네트워크를 활용하면, AWS에 올라간 서비스끼리 통신할 수도 있고, 인터넷 네트워크와 연결도 가능하다. 만약 회사가 자체 데이터센터를 가지고 있다면, 그 데이터센터와도 통신할 수 있다.


출처 | AWS 공식 블로그


 


AWS는 각 상황에 맞는 인프라를 구성할 수 있도록 다양한 서비스를 제공하고 있다.

이 중에서 VPC 간 통신을 지원하는 서비스에 대해서 먼저 알아보고자 한다.


VPC Peering

VPC Peering은 서로 다른 두 VPC 간에 내부 통신 연결을 지원하는 서비스이다. VPC는 사설 네트워크이므로, 원래는 다른 VPC를 인식할 수 없다. 즉, 다른 VPC에 있는 서버에 대해 알 수 있는 방법이 없다. 하지만 VPC Peering을 통해 구간이 생기면 비로소 서로를 인식할 수 있다.


VPC Peering은 연결에 앞서 두 VPC가 서로를 알아가는 과정을 거친다.


먼저, Peering을 맺고자 하는 VPC가 상대편 VPC에 Peering 요청을 보낸다. “나는 당신과 통신하고 싶습니다.”라고 요청하는 과정이다. 이때, 어떤 소유주의 VPC인지 확인하기 위해 VPC의 IP대역과 계정 ID를 전달한다. 이를 Peering Request라고 부른다.


요청을 받은 VPC는 먼저 상대방의 VPC IP가 자신과 겹치는지 확인한다. 만약 VPC IP대역이 겹치면 서로를 고유하게 식별할 수 없다. 예컨대, A VPC와 B VPC에 같은 IP를 가진 서버가 있다고 가정해 보자. 이 상태에서 Peering 연결을 맺으면 이제 같은 IP를 가진 서버가 2대가 된다. 서로를 인식할 수 있는 네트워크 안에서 같은 이름을 가진 서버가 2개라면 다른 서버들은 요청을 보낼 때 혼란을 겪는다. 그렇다고 요청을 두 서버에 모두 보낼 수도 없는 노릇이다. 그래서 두 VPC는 겹치지 않는 IP 대역을 사용해야 한다.


VPC IP대역이 겹치지 않으면 요청받은 VPC는 Peering 연결 요청을 수락할 수 있다. 수락하면 Peering ID가 생긴다. Peering ID는 두 VPC끼리 통신할 때만 사용할 수 있는 일종의 키와 같다. 서로 통신할 때는 해당 VPC Peering ID를 명시하여 트래픽을 전송한다. 그러면 AWS는 패킷을 서로에게 전달한다. 다만, 중간에 별도의 네트워크 장비가 생기는 건 아니다. 즉, 서로 Peering을 맺었다고 해서 NAT가 발생하지는 않는다. 두 VPC 간 서버는 NAT 과정 없이 직접 통신한다.


한 가지 주의할 점은 Peering을 맺는다고 바로 통신이 되지 않는다는 것이다. Peering은 서로를 인식할 수 있는 협약을 맺는 과정일 뿐이다. 실제 Peering을 사용할지는 각 VPC의 라우팅 테이블에 달려있다. 서버에서 트래픽이 나갈 때는 반드시 서브넷의 라우팅 테이블을 거친다. 라우팅 테이블에 목적지 IP 대역을 등록하지 않으면 라우터는 패킷을 버린다.


따라서 Peering 연결을 맺은 후에 Peering 맺은 상대방 IP 대역이 목적지인 경우 Peering 연결을 사용하도록 라우팅 테이블에 등록한다. 그러면 라우터는 해당 대역으로 나가는 패킷을 Peering 맺은 상대방 VPC로 전달한다.


VPC Peering을 통한 네트워크 통신은 AWS 네트워크 상에서만 이루어진다. 즉, 외부 인터넷 네트워크를 사용하지 않는다. 따라서 패킷이 외부로 유출될 우려가 없고, 별도의 공인 IP도 필요 없다.

VPC Peering을 맺은 후 A 서버가 B 서버를 호출하는 경우



VPC Peering의 한계

VPC Peering을 통해 서로 다른 VPC 간 통신하는 방법에 대해 알아보았다. VPC Peering은 인터넷 네트워크를 통하지 않고 서로 다른 사설 네트워크끼리 통신을 할 수 있는 유용한 서비스이다. 중간에 네트워크 장비가 불필요하기 때문에 속도도 상당히 빠르다.


하지만 VPC Peering은 협의 당사자간에만 통신할 수 있다는 단점이 있다. Peering을 맺을 때 요청하고 수락하는 과정을 거친다. 이 과정을 거쳐 서로를 고유하게 식별할 수 있다. 하지만 하나의 VPC가 중간에서 중개하는 건 불가하다. 예컨대, A와 B가 Peering을 맺고, B와 C가 Peering을 맺었다고 하자. 그러면 B 입장에서는 A와 C 모두 고유하게 식별할 수 있다. 그렇다고 A에서 받은 패킷을 C로 전달해주지는 않는다. 만약 A와 C가 통신을 하려면 A와 C가 직접 Peering을 맺어야 한다.


이 단점은 VPC가 많아질 때 여실히 드러난다. VPC가 10개이고, 모든 VPC가 서로 통신해야 한다고 가정하면, 하나의 VPC는 9개의 서로 다른 VPC와 Peering을 맺어야 한다. 그러면 10 x 9 = 90개의 Peering 연결이 필요하다. VPC가 늘어날 때마다 Peering 연결은 급속도로 증가한다. 이를 Full Mesh 네트워크 구조라고도 하는데, 모든 네트워크가 서로 연결을 맺는 구조를 의미한다.


출처 | AWS 공식 블로그


보기만 해도 복잡하지 않은가!


AWS는 이러한 한계를 극복하기 위해서 중간에서 패킷을 전달해 줄 수 있는 Transit 게이트웨이를 지원한다. 지금부터는 Transit 게이트웨이 통해서 어떻게 Full Mesh 구조의 문제를 해결할 수 있는지 알아보고자 한다.


Transit 게이트웨이(TGW)

Transit 게이트웨이는 여러 사설 네트워크 간 통신을 중개하는 게이트웨이이다. 보통 이러한 서비스를 “Transitive 하다"라고 한다. 이는 전달받을 패킷을 다른 트워크로 전송(Transit)할 수 있다는 뜻이다. Transit 게이트웨이는 줄여서 TGW라고 부른다. TGW는 VPC 간 통신을 중개한다. TGW는 별도의 라우팅 테이블을 사용하는데, 이는 VPC 서브넷의 라우팅 테이블이 아닌 별도의 라우팅 테이블이다.


TGW를 통해 네트워크를 연결하기 위해서는 우선 Attachment라는 과정을 거친다.  Attachment는 TGW에 통신할 네트워크를 등록하는 과정이다. Attachment 타입 중에 VPC를 선택하면 VPC 네트워크를 등록할 수 있다. TGW가 통신할 VPC를 인식하는 절차라고 보면 된다.


Attachment를 생성할 때는 가용영역별로 하나의 서브넷을 지정해야 한다. TGW는 설정한 서브넷에 별도의 네트워크 인터페이스를 두고 통신한다. TGW와 통신할 때는 반드시 해당 네트워크 인터페이스를 사용해야 한다. 다만, 같은 VPC 내에서는 서로 통신할 수 있기 때문에 하나의 서브넷만 연결해도 무방하다. 그러나 하나의 서브넷만 지정했다가 해당 가용영역에 장애가 발생하면, TGW와 통신할 수 없게 된다. 이를 방지하기 위해 각 가용영역당 하나의 서브넷을 지정하여 VPC Attachment를 생성하는 것이 좋다.

서브넷마다 하나의 네트워크 인터페이스(ENI)를 생성한다.


VPC Attachment 생성 예시
주의!
TGW에 VPC만 연결할 수 있는 건 아니다. VPN 네트워크와 또 다른 TGW와의 Peering 연결도 가능하다. VPN을 연결하면 VPC에서 데이터센터로 통신도 가능하다.


Transit 게이트웨이 통신 원리

Transit 게이트웨이(TGW)는 자체 라우팅 테이블을 통해 트래픽을 제어한다. TGW 라우팅 테이블을 구성할 때는 먼저 테이블을 사용할 Attachment를 연결한다. Attachment를 연결한다는 의미는 "해당 네트워크로부터 들어오는 트래픽은 그 라우팅 테이블을 사용하겠다"는 뜻이다. 즉, 라우팅 테이블을 사용할 네트워크를 연결하는 과정이다. 만약 라우팅 테이블을 분리해서 각 VPC에 적용하면, VPC마다 서로 다른 라우팅 테이블을 사용할 수 있다. 이렇게 하면 필요한 곳에만 통신할 수 있도록 네트워크를 정교하게 제어할 수 있다.


TGW 라우팅 테이블에 Attachment를 연결했다면, 이제 통신할 대상 네트워크를 지정해야 한다. 이는 어떤 대역을 목적지로 통신할 때, 어느 Attachment를 사용할지 결정하는 것이다. 만약 A VPC에서 B VPC와 통신하고 싶다면, B VPC IP 대역을 목적지로 설정하고, 경로를 B VPC의 Attachment로 지정한다. 이때 목적지 대역이 겹치면 안 된다. 서로 다른 Attachment가 같은 IP 대역을 사용하면, 두 Attachment를 동시에 라우팅 테이블 경로에 추가할 수는 없다. TGW가 어떤 네트워크로 트래픽을 보내야 할지 모르기 때문이다.


이전과 동일하게 A 서버와 B 서버가 각각 A VPC, B VPC에 존재하고, 두 VPC를 TGW에 연결했다고 가정해 보자. A VPC에서 B VPC를 호출하려면 TGW 라우팅 테이블에 경로를 등록해야 한다. 간단하게 그림을 통해 보면 다음과 같다.

TGW를 사용했을 때 트래픽 흐름

1. A 서버는 B 서버를 목적지로 통신을 시도한다. 이때 A 서버가 속한 서브넷에 등록된 라우팅 테이블을 기준으로 트래픽이 전송된다. TGW를 사용하기 위해서는 서브넷 라우팅 테이블에 TGW를 사용하도록 설정해야 한다. 위 그림에서 A VPC의 서브넷 라우팅 테이블을 보면, B VPC 대역(10.200.0.0/16)을 목적지로 설정한 패킷은 TGW(tgw-123)를 사용하도록 설정했다.

2. 서브넷 라우팅 테이블은 B VPC IP 대역 목적지를 확인하고 TGW로 패킷을 전달한다.

3. 패킷을 받은 TGW는 A VPC Attachment를 통해 전송되었음을 확인하고, 해당 Attachment가 사용하고 있는 라우팅 테이블을 확인한다. 라우팅 테이블의 경로를 보면 목적지가 10.200.0.0/16인 경우 B VPC Attachment를 통하도록 설정되어 있다.

4. 라우팅 테이블에 적힌 대로 패킷을 B VPC Attachment로 전송한다.

5. B VPC Attachment를 통해 들어온 패킷은 서브넷 라우팅 테이블을 거쳐 다음 목적지로 향한다. 목적지가 10.200.0.0/16에 속하면 local로 전송한다. 여기서 local은 VPC 내부 네트워크를 의미한다.

6. 서브넷 라우팅테이블에 의해 B 서버로 패킷이 전달된다.


Peering과 동일하게 서로 다른 VPC끼리 통신이 가능하지만, TGW는 별도의 라우팅 테이블을 사용하여 트래픽을 제어한다는 특징이 있다. TGW를 통해 네트워크를 구성하면, 모든 네트워크는 사설 네트워크끼리 통신할 때 일단 TGW로 트래픽을 전송한다. 그 후에 TGW 라우팅 테이블을 통해서 대상 네트워크를 결정한다.


그러면 아래와 같이 Hub & Spoke 형태로 네트워크를 디자인할 수 있다. 이 구조가 가진 가장 큰 장점은 확장성이다. 새로운 네트워크를 연결할 때, 해당 네트워크를 TGW에 연결하고 라우팅 테이블을 구성하면 된다. 이미 기존에 Attachment를 통해 연결을 맺었기 때문에, 통신하고자 하는 네트워크만 취사선택할 수 있다. 즉, Peering처럼 모든 네트워크와 새롭게 연결을 맺을 필요가 없다.


출처 | AWS 공식 문서


하지만 운영이 간편한 만큼 라우팅 테이블 관리에 신경 써야 한다. TGW 라우팅 테이블에 여러 네트워크를 연결하면, 라우팅 테이블을 변경하는 작업으로 영향받는 네트워크가 그만큼 많아진다. 즉, 잘못된 라우팅 설정으로 인해 여러 네트워크가 동시에 장애를 겪을 수 있다.


또한 TGW는 별도의 라우팅 구간을 만들어서 구성하기 때문에 대역폭이 제한적이다. 사설 네트워크에서 지나치게 많은 패킷을 TGW로 전송하면 네트워크에 더 이상 패킷을 넣을 수 없어 트래픽이 느려진다. 현재 VPC 연결당 제한은 50 Gbps이다. 만약 전송량이 50 Gbps를 넘는다면 TGW보다는 Peering을 사용하는 것이 좋다.


지금까지 서로 다른 VPC끼리 통신하는 방식에 대해서 알아보았다. 다음 편에서는 VPN을 통해 온프레미스(데이터센터)와 통신하는 구조에 대해서 알아보고자 한다.



어색한 표현이나, 잘못된 내용을 댓글로 지적해 주시면 정정하겠습니다.

글을 작성하면서 참고했던 자료는 아래에 첨부합니다.


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari