Canvas 1 Layer 1

깃허브(GitHub), L4 로드 밸런서 GLB 디렉터 오픈소스로 공개

깃허브 엔지니어링 블로그에서는 2016년에 내부적으로 개발중인 깃허브 로드 밸런서 GLB, GitHub Load Balancer를 소개한 적이 있습니다.

그리고 지난 (2018년) 8월 8일 내부적으로 개발하고 있던 깃허브 로드 밸런서 디렉터GLB, GitHub Load Balancer Director를 오픈소스로 공개했습니다.

GLB는 다음과 같은 특징을 가지고 있습니다.

깃허브 엔지니어링 블로그에서는 GLB 디렉터를 개발한 배경에 대해 소개하고 있습니다. 복잡한 네트워크 환경에서 패킷을 전달하고자 하는 경우 ECMP 라우팅 기법을 사용할 수 있습니다. ECMPEqual-cost multi-path routing는 하나의 연결에 대해 컨시스턴트 해싱과 같은 방법을 사용해 출발지와 목적지 사이에 패킷들이 같은 경로로 전달될 수 있도록 패킷을 라우트합니다. BGPBorder Gateway Protocol를 통해 여러 대의 서버에 같은 IP를 셋업하고 ECMP로 패킷을 라우트하면, 로드 밸런서처럼 트래픽을 분산하는 효과를 얻을 수 있습니다.

2개의 서버에서 트래픽을 분산 처리
2개의 서버에서 트래픽을 분산 처리

하지만 목적지 서버가 추가되거나 제거될 때 리해시가 일어납니다. 이미 처리되고 있던 패킷이 (처리중이던) 연결에 대한 정보를 가지고 있지 않은 새로운 서버로 분산되어버리면 이를 제대로 처리하지 못 하는 문제가 발생합니다.

서버가 추가되는 경우 기존 연결의 패킷을 처리하지 못 합니다
서버가 추가되는 경우 기존 연결의 패킷을 처리하지 못 합니다

이러한 문제를 해결하기 위해 디렉터 계층을 추가하는 전략을 사용할 수 있습니다. 디렉터로 LVSLinux Virtual Server를 사용하면 네트워크 연결 정보를 저장해두고 이 정보를 바탕으로 패킷이 전달될 서버를 선택합니다. 이를 통해 리해시가 일어나더라도 패킷을 적절한 곳에 전달하는 것이 가능해집니다. 하지만 새로운 디렉터가 추가되는 경우 상태 정보를 싱크하는 동안에 패킷을 제대로 전달하지 못 하는 경우가 발생합니다.

LVS를 사용하는 경우. 디렉터 계층에 서버가 추가 되는 경우 패킷이 제대로 전달되지 못 합니다
LVS를 사용하는 경우. 디렉터 계층에 서버가 추가 되는 경우 패킷이 제대로 전달되지 못 합니다

이는 디렉터 계층에서 상태를 가지고 있기 때문에 발생하는 문제입니다. GLB 디렉터는 상태를 없애는 방법으로 이 문제를 해결합니다. GLB 디렉터 노드들은 미리 해싱을 통해서 트래픽을 전달할 프라이머리 서버와 세컨더리 서버 테이블을 생성해서 가지고 있습니다. 이 테이블을 통해 먼저 프라이머리 서버로 패킷을 전달합니다. 패킷을 전달받은 서버가 올바르지 않다면 프라이머리 서버에서 세컨더리 서버로 패킷을 다시 전달합니다. 목적지 서버가 추가되거나 삭제되는 경우 리해시가 일어납니다. 테이블 상에서 프라이버리 서버는 활성화된 N대의 서버 중에서 하나가 선택되며 세컨더리 서버는 바로 직전의 프라이머리 서버가 됩니다. 따라서 새로운 서버에서 패킷을 처리할 수 없더라도 기존에 이 연결을 처리하던 서버로 연결 됩니다.

디렉터가 추가되었을 때 GLB의 동작 방식
디렉터가 추가되었을 때 GLB의 동작 방식

이를 통해서 디렉터 계층이나 실제 서버가 추가되거나 제거되어도 안정적으로 패킷을 처리하는 것이 가능해집니다. 더 자세한 해설은 깃허브 엔지니어링 블로그에서 다루고 있습니다.

GLB 디렉터를 사용하는 아키텍처는 다음과 같습니다.

GLB 아키텍처
GLB 아키텍처

디렉터 서버에는 glb-healthcheck, glb-director와 BGP daemon이 설치되어있어야합니다. 디렉터로부터 트래픽을 전달받는 서버들에는 패킷 처리에 실패했을 때 세컨더리 서버에 트래픽을 전달하기 위한 glb-redirect iptables 모듈이 필요합니다.

공식 저장소에서는 베이그런트를 사용한 예제컴포넌트 별 설치방법을 제공하고 있습니다.