로드 밸런싱 101: 기본 원리

소개

오늘날과 같이 애플리케이션 중심으로 빠르게 변화하는 시장에서 조직은 고객이 기대하는 정보, 서비스 및 경험을 신속하고 안정적이며 안전하게 제공해야 한다는 압박을 점점 더 받고 있습니다. 로드 밸런싱, 암호화, 가속 및 보안과 같은 주요 네트워크 및 애플리케이션 기능은 물리적 서버의 프록시 역할을 하는 물리적 또는 가상 어플라이언스인 애플리케이션 전송 컨트롤러(ADC)를 통해 제공할 수 있습니다. 애플리케이션이 폭발적으로 증가하고 지속적 통합 및 지속적 배포(CI/CD)의 엄격한 주기로 인해 조직에 가해지는 요구가 커짐에 따라, ADC 시장이 2020년까지 연간 29억 달러 규모에 이를 것으로 전망되는 것은 놀라운 일이 아닙니다.1

하지만 미래로 나아가기에 앞서, 지금에 이르기까지의 과정을 살펴보겠습니다. 네트워크 기반 부하 분산은 ADC가 작동하는 데 필수적인 기반입니다. 1990년대 중반, 최초의 부하 분산 하드웨어 어플라이언스가 서버와 네트워크 전반에 워크로드를 분산하여 조직의 애플리케이션 확장을 지원하기 시작했습니다. 이러한 초기 장치는 특정 애플리케이션에 종속되지 않았으며 애플리케이션 서버 외부에 위치했기 때문에 간단한 네트워크 기술을 사용하여 부하를 분산할 수 있었습니다. 기본적으로 이러한 장치는 외부에 "가상 IP 주소"를 제공하고, 사용자가 연결을 시도하면 양방향 네트워크 주소 변환(NAT)을 수행하는 가장 적합한 실제 서버로 연결을 전달했습니다.

그러나 가상화와 클라우드 컴퓨팅이 등장하면서 하이퍼바이저에서 실행되도록 설계된 소프트웨어 기반 가상 에디션 형태의 차세대 부하 분산 ADC가 출시되었습니다. 오늘날 가상 어플라이언스는 전용 하드웨어에서 실행되는 어플라이언스와 동일한 수준의 폭넓은 기능으로 애플리케이션 서비스를 제공할 수 있습니다. 또한 이러한 가상 에디션은 가상, 클라우드 및 하이브리드 환경 간에 애플리케이션 서비스를 이전할 때 수반되는 복잡성을 크게 줄여 주므로, 조직은 프라이빗 또는 퍼블릭 클라우드 환경에서 애플리케이션 서비스를 빠르고 손쉽게 구축할 수 있습니다.

최근 데이터 센터에서 주목받는 추세는 컨테이너화입니다. 컨테이너화는 분산 애플리케이션의 배포와 실행을 지원하는 애플리케이션 가상화 방식입니다. 이 방식은 애플리케이션을 격리하여 공유 OS 내에서 명확히 구분된 메모리 공간에 배치하므로, 가상 어플라이언스를 구축하는 것보다 애플리케이션을 더 쉽고 빠르게 개발하고 배포할 수 있습니다. 이식성과 성능이 크게 향상됨에 따라 컨테이너화는 기업에 더 뛰어난 확장성과 민첩성을 제공할 수 있습니다. 향후 컨테이너 아키텍처는 조직이 다양한 클라우드 환경을 더욱 효과적으로 활용하는 데에도 도움이 될 수 있습니다.

오늘날의 ADC는 최초의 로드 밸런서에서 서비스 가상화 과정을 거쳐 발전해 왔습니다. 이제 소프트웨어 전용 가상 에디션을 통해 ADC는 가용성을 향상할 뿐만 아니라, 조직이 비즈니스에 필요한 확장 가능하고 성능이 뛰어나며 안전한 애플리케이션을 제공할 수 있도록 지원합니다. 하지만 궁극적으로 이러한 모든 가상화된 애플리케이션 서비스, 공유 인프라 배포 및 지능형 라우팅 기능은 로드 밸런싱 기술이라는 견고한 기반 없이는 구현할 수 없습니다.

기업이 역동적으로 변화하는 시장의 복잡한 과제에 더 효과적으로 대응할 수 있는 방법을 이해하기 위해, 애플리케이션 딜리버리의 기반인 로드 밸런싱의 기초를 살펴보겠습니다.

그림 1: 네트워크 기반 부하 분산 어플라이언스.

기초: 용어

시작하기에 앞서 로드 밸런싱의 기본 용어를 살펴보겠습니다. 모두가 동일한 용어를 사용한다면 더 이해하기 쉽겠지만, 안타깝게도 로드 밸런싱 장비(그리고 더 나아가 ADC) 공급업체마다 서로 다른 용어를 사용하는 듯합니다. 하지만 조금만 설명을 덧붙이면 이러한 혼란을 해소할 수 있습니다.

노드, 호스트, 멤버 및 서버

대부분의 부하 분산 ADC에서는 노드, 호스트, 멤버 또는 서버라는 개념을 사용합니다. 이 네 가지를 모두 사용하는 경우도 있지만, 각각의 의미는 서로 다릅니다. 이러한 용어가 나타내려는 기본 개념은 두 가지입니다. 그중 하나는 일반적으로 노드 또는 서버라고 하며, ADC에서 트래픽을 수신하는 물리적 또는 가상 서버 자체를 의미합니다. 이는 물리적 서버의 IP 주소와 같은 개념이며, 부하 분산 장치가 없다면 서버 이름(예: www.example.com)이 확인되는 IP 주소에 해당합니다. 이 문서의 나머지 부분에서는 이 개념을 호스트라고 하겠습니다.

두 번째 개념은 "멤버"라는 용어로 표현됩니다(안타깝게도 일부 제조업체에서는 이를 노드라고도 부릅니다). 멤버는 트래픽을 수신할 실제 애플리케이션의 TCP 포트까지 포함한다는 점에서 일반적으로 호스트보다 좀 더 구체적으로 정의됩니다. 예를 들어 www.example.com이라는 호스트는 해당 호스트를 나타내는 주소인 172.16.1.10으로 확인될 수 있으며, TCP 포트 80에서 애플리케이션(웹 서버)이 실행 중이라면 멤버 주소는 172.16.1.10:80이 됩니다. 간단히 말해 멤버에는 물리적/가상 서버의 IP 주소뿐만 아니라 애플리케이션 포트에 대한 정의도 포함됩니다. 이 문서의 나머지 부분에서는 이를 서비스라고 지칭하겠습니다.

왜 이렇게 복잡할까요? 서버와 서버에서 실행되는 애플리케이션 서비스를 구분하면 데이터센터나 클라우드에서 로드 밸런서가 기반 하드웨어 또는 하이퍼바이저가 아닌 각 애플리케이션과 개별적으로 상호 작용할 수 있기 때문입니다. 하나의 호스트(172.16.1.10)에서 둘 이상의 서비스(HTTP, FTP, DNS 등)를 제공할 수 있습니다. 각 애플리케이션을 고유하게 정의하면(예: 172.16.1.10:80, 172.16.1.10:21, 172.16.1.10:53) ADC는 호스트가 아닌 서비스를 기준으로 고유한 로드 밸런싱 및 상태 모니터링(나중에 설명할 개념)을 적용할 수 있습니다.

대부분의 부하 분산 기반 기술에서는 호스트, 즉 물리적 서버를 나타내는 용어와 해당 서버에서 제공되는 서비스를 나타내는 용어를 각각 따로 사용한다는 점을 기억하세요. 이 경우에는 간단히 호스트와 서비스라고 합니다.

풀, 클러스터 및 팜

부하 분산을 사용하면 조직은 퍼블릭 또는 프라이빗 클라우드의 배포 환경을 비롯한 여러 백엔드 대상으로 인바운드 애플리케이션 트래픽을 분산할 수 있습니다. 따라서 백엔드 대상의 집합이라는 개념이 필요합니다. 여기서는 이를 클러스터라고 부르며(풀 또는 팜이라고도 함), 클러스터는 여러 호스트에서 제공되는 유사한 서비스의 집합입니다. 예를 들어 회사 웹 페이지를 제공하는 모든 서비스는 "회사 웹 페이지"라는 클러스터로 묶고, 전자상거래 서비스를 제공하는 모든 서비스는 "전자상거래"라는 클러스터로 묶을 수 있습니다.

가상 서버

가상 서버는 실제 서버(물리 서버, 가상 서버 또는 컨테이너)를 대신하는 프록시입니다. 가상 IP 주소와 결합되어 외부에 공개되는 애플리케이션 엔드포인트 역할을 합니다.

모두 종합하기

이러한 용어를 이해했다면 로드 밸런싱의 기본 개념을 익힌 것입니다. 로드 밸런싱 ADC는 외부에 가상 서버를 제공합니다. 각 가상 서버는 하나 이상의 물리적 호스트에 있는 서비스 클러스터를 가리킵니다.

그림 2: 애플리케이션 딜리버리는 가상 서버, 클러스터, 서비스, 호스트라는 네 가지 기본 개념으로 구성됩니다.

그림 2가 실제 환경의 배포 구성을 그대로 나타내는 것은 아닐 수 있지만, 부하 분산 및 애플리케이션 전송 프로세스에 관한 논의를 이어가는 데 필요한 기본 구조를 제시합니다.

부하 분산의 작동 방식

이제 공통 용어를 정리했으므로 애플리케이션이 고객에게 전달되는 간단한 처리 과정을 살펴보겠습니다. 그림과 같이 부하 분산 ADC는 일반적으로 클라이언트와 클라이언트가 사용하려는 서비스를 제공하는 호스트 사이의 경로상에 배치됩니다. 애플리케이션 전송과 관련된 대부분의 사항이 그렇듯이, 이러한 배치는 반드시 지켜야 할 규칙이라기보다 모든 유형의 배포에서 권장되는 모범 사례에 가깝습니다. 또한 ADC에는 두 개의 서비스 지점으로 구성된 클러스터를 가리키는 가상 서버가 이미 구성되어 있다고 가정하겠습니다. 이러한 배포 시나리오에서는 반환 트래픽이 클라이언트로 돌아가는 도중 부하 분산 장치를 거쳐 처리되도록 호스트의 반환 경로가 부하 분산 장치를 가리키게 하는 것이 일반적입니다.

기본적인 애플리케이션 전송 트랜잭션은 다음과 같습니다:

  • 클라이언트가 서비스에 연결을 시도합니다.
  • ADC는 연결을 수락한 후 연결을 수신할 호스트를 결정하고, 선택한 호스트의 서비스에 맞게 대상 IP(필요한 경우 포트도 포함)를 변경합니다(클라이언트의 소스 IP는 변경하지 않음).
  • 호스트는 연결을 수락하고 기본 경로인 ADC를 통해 원래 소스인 클라이언트에 응답합니다.
  • ADC는 호스트에서 반환되는 패킷을 가로채 소스 IP(및 해당되는 경우 포트)를 가상 서버의 IP 및 포트와 일치하도록 변경한 후, 패킷을 클라이언트로 다시 전달합니다.
  • 클라이언트는 반환 패킷이 가상 서버에서 온 것으로 간주하여 수신한 후 프로세스를 계속 진행합니다.
그림 3: 기본적인 부하 분산 트랜잭션.

이 매우 간단한 예는 비교적 이해하기 쉽지만, 몇 가지 핵심 요소에 주목해야 합니다. 첫째, 클라이언트가 인식하기에는 자신이 가상 서버로 패킷을 보내면 가상 서버가 응답하는 단순한 구조입니다. 둘째, NAT가 수행됩니다. 이때 ADC는 클라이언트가 전송한 대상 IP(가상 서버의 IP)를 요청의 부하 분산 대상으로 선택한 호스트의 대상 IP로 바꿉니다. 셋째, 이 과정에는 NAT를 "양방향"으로 만드는 단계가 있습니다. 호스트에서 반환되는 패킷의 출발지 IP는 해당 호스트의 IP입니다. 이 주소를 변경하지 않고 패킷을 그대로 클라이언트에 전달하면, 클라이언트는 자신이 요청하지 않은 대상으로부터 패킷을 받게 되므로 이를 폐기합니다. 대신 로드 밸런서는 해당 연결을 기억하고 패킷의 출발지 IP가 가상 서버의 IP가 되도록 다시 작성하여 이 문제를 해결합니다.

애플리케이션 전송 결정

일반적으로 이 시점에서 두 가지 질문이 생깁니다. 부하 분산 ADC는 연결을 어느 호스트로 보낼지 어떻게 결정할까요? 그리고 선택된 호스트가 작동하지 않으면 어떻게 될까요?

두 번째 질문부터 살펴보겠습니다. 선택한 호스트가 작동하지 않으면 어떻게 될까요? 간단히 말해, 호스트가 클라이언트 요청에 응답하지 않아 결국 연결 시도가 시간 초과로 실패하게 됩니다. 이는 고가용성을 보장하지 못하므로 바람직한 상황이 아닙니다. 따라서 대부분의 부하 분산 기술에는 호스트로 연결을 보내기 전에 해당 호스트가 실제로 사용 가능한지 확인하는 상태 모니터링 기능이 어느 정도 포함되어 있습니다.

상태 모니터링에는 여러 수준이 있으며, 수준이 높아질수록 세분성과 점검 범위가 향상됩니다. 기본적인 모니터는 호스트 자체에 단순히 ping을 보냅니다. 호스트가 ping에 응답하지 않으면 해당 호스트에 정의된 모든 서비스가 중단되었을 가능성이 높다고 판단하여 사용 가능한 서비스 클러스터에서 제외해야 합니다. 하지만 호스트가 ping에 응답하더라도 서비스 자체가 정상적으로 작동한다는 의미는 아닙니다. 따라서 대부분의 장치는 단순한 TCP 연결부터 스크립트 또는 지능형 상호 작용을 통해 애플리케이션과 통신하는 방식에 이르기까지 다양한 형태의 "서비스 ping"을 수행할 수 있습니다. 이러한 상위 수준의 상태 모니터는 호스트가 아닌 실제 서비스의 가용성을 더욱 확실하게 확인할 수 있을 뿐만 아니라, 로드 밸런서가 단일 호스트에서 실행되는 여러 서비스를 구분할 수 있게 해 줍니다. 로드 밸런서는 한 서비스가 사용 불가능하더라도 동일한 호스트의 다른 서비스는 정상적으로 작동할 수 있으므로, 해당 서비스들을 사용자 트래픽의 유효한 대상으로 계속 간주해야 한다는 점을 인식합니다.

이제 첫 번째 질문으로 돌아가 보겠습니다. ADC는 연결 요청을 어느 호스트로 보낼지 어떻게 결정할까요? 각 가상 서버에는 해당 서비스를 제공하는 호스트 목록으로 구성된 전용 서비스 클러스터가 있으며, 이 목록이 선택 가능한 후보가 됩니다. 또한 상태 모니터링을 통해 이 목록을 조정하여 지정된 서비스를 제공하는 "현재 사용 가능한" 호스트 목록을 만듭니다. ADC는 이렇게 조정된 목록에서 새 연결을 수신할 호스트를 선택합니다. 정확히 어느 호스트를 선택할지는 해당 클러스터에 연결된 부하 분산 알고리즘에 따라 달라집니다. 이러한 알고리즘에는 최소 연결, 동적 비율, 단순 라운드 로빈 등이 있습니다. 단순 라운드 로빈에서는 부하 분산 장치가 목록의 맨 위부터 차례로 내려가며 새 연결을 다음 호스트에 할당하고, 목록의 맨 아래에 도달하면 다시 맨 위부터 시작합니다. 이 방식은 간단하고 예측 가능성이 매우 높지만, 모든 연결이 백엔드 호스트에 유사한 부하를 주고 지속 시간도 비슷하다고 가정합니다. 그러나 실제로는 항상 그렇지는 않습니다. 더 고급 알고리즘은 사용 가능한 클러스터 서비스 중 가장 적합한 호스트를 선택하기 위해 현재 연결 수, 호스트 사용률, 심지어 해당 호스트로 전송되는 기존 트래픽의 실제 응답 시간과 같은 요소를 활용합니다.

충분히 고도화된 애플리케이션 전송 시스템은 상태 모니터링 정보와 부하 분산 알고리즘을 통합하여 서비스 간 종속성까지 파악할 수 있습니다. 이는 하나의 호스트에서 여러 서비스를 제공하고, 사용자의 요청을 처리하는 데 해당 서비스가 모두 필요한 경우에 특히 유용합니다. 이런 경우 한 서비스는 정상적으로 작동하지만 다른 서비스는 작동하지 않는 호스트로 사용자가 연결되어서는 안 됩니다. 즉, 호스트의 서비스 중 하나에 장애가 발생하면 해당 호스트의 다른 서비스도 사용 가능한 서비스의 클러스터 목록에서 제외해야 합니다. HTML과 스크립팅을 통해 서비스가 점점 더 세분화됨에 따라 이 기능의 중요성도 커지고 있습니다.

로드 밸런싱을 할 것인가, 말 것인가?

클라이언트가 트랜잭션 요청을 시작할 때 사용 가능한 서비스를 선택하는 것은 부하 분산 솔루션의 절반에 불과합니다. 연결이 설정되면 ADC는 해당 사용자의 후속 트래픽에 부하 분산을 적용해야 하는지 계속 추적해야 합니다. 부하 분산이 적용된 후속 트래픽을 처리할 때는 일반적으로 연결 유지와 지속성이라는 두 가지 문제가 발생합니다.

연결 유지

사용자가 즉시 종료되지 않는 장기 TCP 연결(포트 21: FTP, 포트 23: Telnet 등)을 사용하려는 경우, 로드 밸런서는 해당 연결을 통해 전송되는 여러 데이터 패킷이 사용 가능한 다른 서비스 호스트로 분산되지 않도록 해야 합니다. 이를 연결 유지 관리라고 하며, 여기에는 두 가지 핵심 기능이 필요합니다. 첫째, 열려 있는 연결과 해당 연결이 속한 호스트 서비스를 추적할 수 있어야 합니다. 둘째, 연결이 종료될 때 연결 테이블을 업데이트할 수 있도록 로드 밸런서가 해당 연결을 지속적으로 모니터링할 수 있어야 합니다. 이는 대부분의 ADC에서 상당히 일반적인 기능입니다.

지속성

하지만 최근에는 클라이언트가 하나의 작업을 수행하기 위해 여러 개의 단기 TCP 연결(예: 포트 80: HTTP)을 사용하는 경우가 점점 더 흔해지고 있습니다. 일반적인 웹 탐색과 같은 경우에는 각 새 요청이 어떤 백엔드 서비스 호스트로 전달되어도 상관없습니다. 그러나 XML, 전자상거래 등의 많은 경우에는 동일한 사용자의 여러 연결이 부하 분산되지 않고 동일한 백엔드 서비스 호스트로 전달되는 것이 매우 중요합니다. 이 개념을 지속성 또는 서버 선호도라고 합니다.

이 문제를 해결하는 방법은 프로토콜과 원하는 결과에 따라 여러 가지가 있습니다. 예를 들어 최신 HTTP 트랜잭션에서는 서버가 "keep-alive" 연결을 지정하여 여러 개의 단기 연결을 하나의 장기 연결로 전환할 수 있으며, 이렇게 전환된 연결은 다른 장기 연결과 동일하게 처리할 수 있습니다. 하지만 이는 제한적인 완화책에 불과합니다. 웹 및 모바일 서비스 사용이 증가함에 따라 모든 연결을 필요 이상으로 오래 열어 두면 전체 시스템의 리소스에 부담을 주기 때문입니다. 이러한 이유로 오늘날 많은 조직이 확장성과 이식성을 확보하기 위해 API를 기반으로 하는 무상태 애플리케이션을 구축하는 방향으로 전환하고 있습니다. 이는 기본적으로 리소스 부하를 줄이기 위해 서버가 모든 세션 정보를 저장하지 않는다는 의미이며, 이러한 경우 세션 ID를 전달하고 지속성 개념을 활용하여 상태를 유지합니다.

가장 기본적인 지속성 방식 중 하나는 소스 주소 선호도입니다. 이 방식은 들어오는 요청의 소스 IP 주소와 해당 요청이 부하 분산된 서비스 호스트를 기록한 다음, 이후의 모든 트랜잭션을 동일한 호스트로 보내는 것입니다. 이를 구현하는 두 가지 방법은 SSL 세션 ID와 쿠키를 사용하는 것입니다. SSL 지속성은 SSL 세션 ID를 사용하여 SSL 세션을 추적하므로 클라이언트의 IP 주소가 변경되더라도 부하 분산 장치는 세션 ID를 기반으로 해당 세션의 지속성을 인식합니다. 쿠키 기반 지속성은 세션을 고유하게 식별할 수 있도록 클라이언트의 컴퓨터에 쿠키를 삽입한 다음 요청에서 해당 쿠키를 참조하여 연결이 올바른 서버로 전달되도록 하는 방식입니다.

오늘날 ADC의 지능형 기능을 통해 조직은 데이터 패킷을 열어 그 안에 포함된 거의 모든 정보를 기반으로 지속성 테이블을 생성할 수 있습니다. 이를 통해 사용자 이름과 같은 고유 정보를 사용하여 지속성을 유지할 수 있습니다. 그러나 식별 가능한 이 클라이언트 정보가 모든 요청에 포함되도록 해야 합니다. 이 정보가 없는 패킷에는 지속성이 적용되지 않고 다시 로드 밸런싱되어 애플리케이션이 중단될 가능성이 높기 때문입니다.

결론

초기에는 로드 밸런싱이 네트워크 전반에 워크로드를 분산하고 애플리케이션과 서비스의 가용성을 보장하는 데 중점을 두었습니다. 그러나 기술이 발전하면서 로드 밸런서는 애플리케이션 전송 플랫폼으로 진화하여 조직의 핵심 애플리케이션에 높은 가용성과 보안성을 제공하게 되었습니다. 기본적인 로드 밸런싱은 여전히 애플리케이션 전송의 기반이지만, 최신 ADC는 훨씬 더 향상된 기능을 제공합니다.

기업은 애플리케이션에 단순히 접속할 수 있다고 해서 실제로 사용할 수 있는 것은 아니며, 사용할 수 없는 애플리케이션은 이를 배포한 조직에 시간과 비용의 낭비를 초래한다는 사실을 잘 알고 있습니다. 바로 이 지점에서 최신 ADC가 중요한 역할을 합니다. 최신 ADC를 사용하면 SSL/TLS 오프로딩, 캐싱, 압축, 속도 제어, 침입 탐지, 애플리케이션 방화벽, 원격 액세스 등의 네트워크 기반 서비스를 하나의 전략적 지점으로 통합할 수 있습니다. 이 지점은 모든 애플리케이션 서비스와 호스트에서 공유하고 재사용할 수 있어 가상화된 애플리케이션 전송 네트워크를 구축할 수 있습니다. 이를 통해 네트워크, 애플리케이션 및 운영 팀은 보안 요구 사항을 절대 희생하지 않으면서도 더 짧은 제공 일정과 향상된 확장성을 요구하는 비즈니스 수요에 더욱 효과적으로 대응할 수 있습니다.

고급 애플리케이션 딜리버리의 작동 방식과 ADC의 미래에 대해 자세히 알아보려면 애플리케이션 딜리버리 컨트롤러의 진화 및 기존 로드 밸런싱을 넘어서를 읽어보세요.

1 http://www.strategyr.com/MarketResearch/Application_Delivery_Controllers_ADC_Market_Trends.asp

2017년 5월 10일 게시