상상해 보자. 당신은 데이터 송·수신이 중요한 시스템을 만들고 있다. 해당 시스템에서는 잠시간의 네트워크 단절이 큰 영향을 미친다. 그러나 안타깝게도, 불안정한 네트워크 속에서 서비스를 진행해야 한다.
예를 들어, 해외 서버와 지속적인 통신을 해야할 경우가 있다 하자. 해외 트레픽이 넘처나는 22시 즈음이 되면 최대 30%의 확률로 Packet loss가 발생한다. 사내 네트워크와 IDC내 서버간 연결이 필요할 수도 있다. 특히 새벽시간에 자주 발생하는 네트워크 순단에 의하여 데이터 송수신이 방해 받을 수 있다.
Tun 장치를 통한 Multi-path Network
그래서 생각한 것이 “multi path network”이다. application 코드 수정이 없는것이 중요하므로, tun 장치만으로 구성한다. 다시 말해서, 각 장치에 사전에 프로그램을 설치 한 뒤 tun 어뎁터를 이용하여 통신을 한다. 통신을 위해서는 수신측·발신측 모두에 프로그램을 사전에 설치해 놔야 한다.
tun 장치는 추상화 역할을 수행하여 n개의 네트워크가 있더라도, 1개의 장치만 신경쓰면 되도록 도와준다. 위의 그림 기준에서 application은 100.10.10.10만 신경쓰면 된다. [컨트롤 SW]가 회선 이중화를 수행한다. application은 그에 관한것을 신경쓸 필요가 없다.
수신측에서도 동일하게 tun 장치에서 나오는 패킷만 고려하면 된다. 실제 통신은 [컨트롤 SW]가 알아서 처리한다. Active-Active(Round-Robin, Replication), Active-Standby(HeartBeat) 모두 설정값에 따라 뒤에서 알아서 처리한다.
Direct and Relay 방식
네트워크 품질은 시시각각 바뀐다. 첫 문단에서 처럼 해외 서버와 통신을 한다면 중간 경유 국가를 설정하는것이 좋을 수 있다.
예를 들어, 홍콩에 있는 서버와 한국에 있는 서버간 통신한다고 생각해 보자. 국제 네트워크 상에서는 무슨일이 있을 지 모른다. 이런 경우에는 각 패킷이 일본과 중국을 각각 경유해서 들어오는 경우가 나을 수 있다. 경유를 하지 않고 직접 오는 경우도 생각할 수 있다.
그러므로, (1) 경유 서버를 이용한 Routing 과 (2) 직접 연결을 모두 고려해야 한다. 기본적으로는 Direct로 바로 연결하되, 설정에 따라서는 경유 서버를 사용할 수도 있어야 한다.
이와 같은 방식을 하기 위해서는 “사전 설정된(pre-defined) 경로” 기능이 필요하다. 특정 그룹(홍콩)에서 특정 그룹(서울)으로 데이터를 보낼때는 일본 중계, 중국 중계, Direct 방식을 사용하도록 설정하면 이에 맞춰서 통신하는 것이다.
A → B의 경로와 B → A 경로는 다를 수 있다.
기본적으로 설정하지 않으면 A → B의 역방향으로 통신한다. 그러나, 설정이 존재할 경우 A → C[제 3의 중계서버] → B 방향으로 통신될 수도 있다.
이런 방식은 국내에서 2개 이상의 통신사를 쓸 때도 도움이 된다. 예를 들어, 사내 네트워크는 KT를 주 회선으로 쓰되 백업으로는 SKT를 사용할 수 도 있다. 이때, 위와 같이망 구성을 할 수도 있다. 가상 네트워크로 묶여있기 때문에, 한쪽 망이 다운되더라도 소켓 재연결과 같은 로직 없이 작업을 이어나갈 수 있다.
추가적인 생각으로는, Packet Loss와 Latency를 통하여 최적의 route 경로도 구할수 있을것 같다. 그러나 아래의 ACL에 의해서 현실적인 어려움도 있을것 같다. Edge node는 허용된 그룹만 보이기 때문에, 경로 계산은 Controller가 담당해야 할 것으로 보인다.
그룹(테그) 기반 ACL
각 node끼리의 통신은 ACL 기반으로 이루어진다. 거의 모든 곳에서 “단일 서버” or “그룹” 단위로 설정할 수 있다.
예를 들어서, 위에서 설명한 홍콩·일본 중계 노드를 그룹단위로 설정할 수 있다. routing을 할 때 일일이 서버를 지정하는것이 번거롭다. 그룹을 설정하고, 해당 그룹 기반으로 라우팅을 하면 빠르게 설정이 가능할 것이다. 출발지 및 도착지 또한 그룹화 가능할 것이다.
각 서버는 ACL에 허용된 (그룹)노드들만 보인다. 기본적인 방화벽 기능을 담당하는 셈이다. 데이터 암호화 또한 그룹 단위로 적용할 수 있다. ACL에 허용된 (그룹)노드 단위로 암호키를 만들고 공유하여, 그룹별로 각기 다른 암호키를 가지게 할 수 있다. 필요하다면 Tor와 같이 암호화의 암호화의 암호화의 암호화를 적용할 수도 있을 거다.
분산 Controller
1:1 통신만 되는것은 진정한 네트워크가 아니다. 여러 대의 node가 붙을 수 있어야 한다. 대신, 중앙 서버가 하나만 존재하면 문제가 된다. 해당 서버가 터진다면 제대로 된 통신이 안될 수 있다. 그러므로 n개의 노드에서 컨트롤러 역할을 할 수 있어야 한다. 관리를 위해서 분산 Controller에서는 acl을 초월한 데이터를 가지고 있는다.
설정 상에 “컨트롤러 허용 여부”를 Enable하면 그 안에서 투표로 Controller를 선택한다. 이때에 사용되는 기술들은 분산 시스템에 쓰이는 기술을 적용한다. 특히 각 node끼리의 ping 값을 통하여 어느정도 고르게 분포시키면 좋을것 같다.
이렇게 되면 seed 서버를 통하여 계속해서 네트워크를 등록할 수 있다. 네트워크 등록을 위해서 토큰값(초대키)를 보낸다. 그러면 초대키에 미리 연결되어 있는 그룹에 자동 등록된다.
실제 패킷
모든 TUN에 들어온 데이터는 UDP로 목적지에(직접 및 중계를 통해) 전달된다. 이때, 패킷의 흐름을 컨트롤 하기 위해 패킷 type(1byte) 정보를 가진다. 패킷 type이 “실제 데이터”를 의미한다면 다시 { 출발지 node id, 도착지 node id, 현재 group id, 라우팅 번호 } 를 기록한다. 라우팅 번호는 Direct and Relay 문단의 “사전 설정된(pre-defined) 경로”에 해당한다.
이때, Group ID는 packet loop에서 빠져나오는데 도움을 준다. 아래와 같이 일부 그룹에서 겹치는 node가 있다면 계속해서 뺑뺑이를 돌게 된다. H, I가 앞의 “한국”에 해당하는건지, 뒤의 “춘천”에 해당하는건지 확인 불가능 하기 때문이다.
만약 “가장 마지막”에 해당하는 그룹으로 인식하게 된다면 (중복될 경우 뒤에 있는 “춘천”을 선택하게 된다면)
홍콩 → 중국 → 한국 해외망 전용 노드 → 서버
에서
홍콩 → 한국 해외망 전용 노드 → 서버
처럼 중간 route가 무시 될 수 있다.
그 외 고려사항
우리는 Data loss를 고려하지 않는다. Data loss는 TUN에 의해 encapsulation된 TCP 로직에서 할 일이다. Reliable UDP 같은것이 필요해 보이지는 않는다. 어짜피 상단에서 처리할 것이다.
내부 망에서의 라우팅도 문제이다. 아래의 상황을 다시 생각해 보자. controller 노드는 [주황색 node]와 [보라색 SKT 중계 PC]의 외부 IP만 보게 된다. 외부 IP만으로 홀펀칭을 하게 되면 [주황색 node] → 공유기 → KT → KT 백본 → SKT 백본 → [SKT 중계 PC] → SKT 백본 → IDC 서버로 통신하게 된다. 쓸데없이 경로가 더 복잡해진다.
edge node에서 사용 가능한 내부 IP가 있는지 부터 확인해야 한다. 해당 인터페이스에서 직접 연결이 된다면 내부망 통신으로 끝나기 때문이다. 어쨋든 route 지점이 늘어날 수록 더 힘들어진다.
TCP, ICMP에는 TTL이 존재한다. Trace route도 TTL을 이용한 기능이다. 당장은 우선순위가 후순위이기에 어렵지만, 추후에는 해당 기능을 구힌하여 Trace route까지도 보이면 좋을것 같다.
답글 남기기