사전 로드 밸런서
개념

로드 밸런서

gabury1

들어온 요청을 뒤에 있는 여러 대의 서버 가운데 하나로 골라 넘기는 중간 장치입니다. 요청을 보내는 쪽은 주소 하나만 알면 됩니다. 뒤에 몇 대가 있는지, 그중 어느 대가 그 요청을 받았는지는 보내는 쪽이 모릅니다.

상세

처음 온 환자를 접수처가 여러 진료실 가운데 한 곳으로 보냅니다. 그 환자가 다음에 또 오면 접수처는 지난번 기록을 찾아 같은 진료실로 보냅니다. 누구를 어디로 보냈는지 적어 두지 않으면 못 하는 일입니다.

RFC(Request for Comments) 3234 는 이런 장치를 미들박스로 분류합니다. 그 안에서 다시 두 갈래로 나눠 적습니다. 하나는 패킷을 돌리는 쪽입니다. 패킷을 원래 향하던 IP(Internet Protocol) 목적지에서 다른 곳으로 돌리거나 그 목적지를 모호하게 만드는 기법들을 묶은 것입니다. 같은 문서는 그 동기가 대개 서버들 사이에 부하를 고르게 나누는 것이라고 적습니다. 목적지 포트 번호에 따라 IP 라우팅으로 응용을 여러 서버에 쪼개는 것까지 같은 자리에 넣습니다.

다른 하나는 URL(Uniform Resource Locator) 을 돌리는 쪽입니다. 같은 문서는 URL 리다이렉트로 서버 묶음 사이에 부하를 나눌 수 있다고 적습니다. HTTP(HyperText Transfer Protocol) 프록시가 요청을 고쳐 써서 묶음 안의 특정 서버로 보내는 방식도 함께 듭니다.

고르는 일에는 조건이 하나 붙습니다. 같은 응용 세션에서 나온 패킷은 전부 같은 물리 서버로 가야 합니다. 그래서 이 기법들은 한 번에 끝나는 UDP(User Datagram Protocol) 프로토콜 같은 드문 경우를 빼면 필연적으로 상태를 갖는다고 RFC 3234 는 적습니다. 정교한 해법이라면 장애가 난 쪽을 넘기는 페일오버까지 다룰 수 있을 것이라는 말도 덧붙입니다.

sequenceDiagram
    participant C as 클라이언트
    participant LB as 로드 밸런서
    participant A as 서버 A
    participant B as 서버 B
    C->>LB: 요청
    LB->>A: 하나를 골라 넘김
    A-->>LB: 응답
    LB-->>C: 응답
    C->>LB: 같은 세션의 다음 요청
    LB->>A: 앞서 고른 서버로
    Note over B: 이번 세션에서는 안 고름

클라이언트는 주소 하나를 보고 요청을 보냅니다. 그 요청은 중간에서 한 번 멈춰 서고, 뒤에 있는 서버 가운데 하나가 골라집니다. 같은 세션에서 이어지는 요청은 앞서 골라 둔 서버로 갑니다. 그러려면 중간 장치가 어느 세션을 어디로 보냈는지 기억하고 있어야 합니다.

후보가 늘 성한 것은 아닙니다. 뒤의 서버 한 대가 멈춰도 앞에 내건 주소는 그대로입니다. 고르는 자리가 그 사정을 모르면 멈춘 서버에도 차례가 돌아갑니다. 그래서 이 자리에는 대상이 살아 있는지 살피는 헬스체크가 붙습니다. 살아 있다고 확인된 대상에게만 요청을 넘깁니다. 멈춘 대상은 후보에서 빠집니다.

배경

서버 한 대가 같은 시간에 받아낼 수 있는 요청 수에는 천장이 있습니다. 천장에 닿으면 요청은 줄을 섭니다. 줄이 길어지면 기다리던 요청이 끊깁니다. 천장에 닿지 않아도 곤란한 자리가 하나 더 있습니다. 그 한 대가 멈추면 서비스 전체가 같이 멈춥니다.

같은 일을 하는 서버를 여러 대 두면 두 불편이 함께 풀립니다. 대신 새 불편이 하나 생깁니다. 요청을 보내는 쪽이 서버 목록을 들고 있어야 합니다. 그중 어느 대로 보낼지도 스스로 정해야 합니다. 서버가 늘거나 줄 때마다 보내는 쪽을 전부 고쳐야 한다는 뜻입니다.

그래서 고르는 일을 중간의 한 자리로 옮깁니다. 보내는 쪽은 주소 하나만 알면 됩니다. 그 자리가 뒤의 목록을 들고 있다가 하나를 골라 넘깁니다. RFC 3234 는 미들박스를 분류하면서 이 자리를 두 절에 나눠 적고 둘 다 「load balancer」라고 부릅니다. 부하를 고르게 나눈다는 동기가 그대로 이름이 됐습니다. 다만 같은 문서는 그것이 쓰인 시점까지는 이 기법들이 독점적이어서 관리가 촘촘한 환경에서만 쓸 수 있었다고 적습니다.

이름이 먼저 붙은 곳은 이름 질의 쪽입니다. RFC 1794 는 「load balancing」이 원래 DNS 에이전트가 기계들의 「클러스터」 개념을 다루게 하려던 말이었다고 적습니다. 그 클러스터의 기계들은 기능이 서로 비슷하거나 같았습니다. 그래서 어느 기계가 뽑히는지는 상관이 없었습니다. 처리 부하가 여러 호스트에 고르게 흩어지기만 하면 됐습니다.

같은 문서는 그 방식이 갖춰야 할 조건도 늘어놓습니다. 기존 DNS 문서와 하위 호환일 것, 자주 바뀌는 정보를 다룰 것, 주소를 여러 개 내보낼 것, 다른 리소스 레코드와 어긋나지 않을 것, 여러 종류의 「부하」를 표현할 수 있을 것, 그리고 빠를 것입니다.

갈래

두 축으로 갈립니다. 하나는 요청의 무엇을 보고 고르느냐입니다. 다른 하나는 후보 가운데 무엇을 기준으로 하나를 집느냐입니다. 앞의 축은 고르는 자리가 어느 계층에 서는지를 정합니다. 뒤의 축은 그 자리에서 도는 규칙을 정합니다.

L4

OSI(Open Systems Interconnection) 모델의 네 번째 계층에 서는 방식입니다. L4(Layer 4, 4계층) 라고 부릅니다. 클라이언트에게는 단일 접점 노릇을 합니다.

고르는 절차는 이렇습니다. 리스너가 설정된 프로토콜과 포트로 연결 요청을 확인해 타겟 그룹으로 넘깁니다. 요청을 받으면 기본 동작에 딸린 타겟 그룹에서 대상 하나를 고릅니다. 그리고 지정된 프로토콜과 포트로 그 대상에 요청을 보내려 시도합니다. 헬스체크는 타겟 그룹 단위로 설정합니다. 등록된 대상의 상태를 지켜보다가 건강한 대상에게만 트래픽을 보냅니다. 응용 트래픽의 내용으로 대상을 가르는 것은 다음 소절의 자리입니다.

L7

응용 계층, 곧 OSI 모델의 일곱 번째 계층에 서는 방식입니다. L7(Layer 7, 7계층) 이라고 부릅니다. 요청을 받으면 리스너 규칙을 우선순위 순으로 따져 어느 규칙을 적용할지 정합니다. 그런 다음 그 규칙의 동작에 딸린 타겟 그룹에서 대상을 고릅니다. 규칙 하나는 우선순위 하나와 하나 이상의 동작, 하나 이상의 조건으로 이루어집니다.

가르는 근거가 응용 트래픽의 내용이라는 점이 L4 와 다릅니다. 응용 트래픽의 내용에 따라 서로 다른 타겟 그룹으로 요청을 보내도록 리스너 규칙을 설정할 수 있습니다.

이름 질의와 URL 단계

고르는 자리가 요청이 지나는 경로 위가 아니라 그 앞일 수도 있습니다. RFC 3234 는 DNS(Domain Name System) 를 이용한 방법과 나란히 URL 리다이렉트로 서버 묶음 사이에 부하를 나누는 방식을 듭니다. 같은 문서는 그것을 콘텐츠 분산 네트워크의 로컬판이라고 부릅니다.

라운드로빈

후보를 차례로 돌아가며 하나씩 집는 규칙입니다. 서버마다 가중치를 달면 가중 라운드로빈이 됩니다. 첫 서버에 가중치 5 가 붙고 나머지 둘에 1 이 붙으면 일곱 요청마다 다섯이 첫 서버로 가고, 둘째와 셋째 서버로 한 건씩 갑니다. 후보 묶음의 기본 규칙을 이 방식으로 두는 구현이 여럿입니다.

최소 연결

지금 열려 있는 연결이 가장 적은 서버로 요청을 넘기는 규칙입니다. 서버의 가중치도 함께 따집니다. 그런 서버가 여럿이면 그것들끼리 다시 가중 라운드로빈으로 돌립니다. 같은 축의 변형으로, 열려 있는 연결이 아니라 처리 중인 요청이 가장 적은 대상을 고르는 규칙도 있습니다.

해시

요청에서 뽑은 값을 해시해 대상을 정하는 규칙입니다. 클라이언트와 서버의 짝이 그 해시 값으로 묶입니다. 해시 키로는 텍스트와 변수, 둘을 섞은 것까지 쓸 수 있습니다. 클라이언트 IP 를 키로 쓰는 변형도 있습니다. 이 방식에서는 묶음에 서버를 더하거나 빼면 키 대부분이 다른 서버로 다시 배정될 수 있습니다.

예시

nginx 업스트림

nginx 의 ngx_http_upstream_module 은 서버 묶음을 정의합니다. 그 묶음을 proxy_pass 같은 지시어가 가리킵니다. 공식 문서의 설정 예는 이렇습니다.

nginx
upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;
    server backup1.example.com:8080 backup;
    server backup2.example.com:8080 backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

upstream backend 블록이 후보 목록입니다. 유닉스 소켓도 후보가 됩니다. 마지막 두 줄에는 backup 파라미터가 붙어 있습니다. location / 로 들어온 요청은 proxy_pass http://backend; 를 타고 그 묶음으로 넘어갑니다. 같은 문서는 어느 서버와 통신하다 오류가 나면 그 요청을 다음 서버로 넘긴다고 적습니다. 동작하는 서버를 전부 시도할 때까지 그렇게 합니다. 이것은 요청을 보낸 뒤 오류를 만났을 때의 재시도입니다. 요청을 보내기 전에 대상의 상태를 미리 살피는 헬스체크와는 다른 자리입니다.

쿠버네티스 Service

쿠버네티스의 Service 는 클러스터 안에서 파드로 도는 응용을 바깥을 향한 접점 하나 뒤에 둡니다. type 을 LoadBalancer 로 두면 외부 로드 밸런서를 지원하는 클라우드 사업자에서 그 Service 를 위한 로드 밸런서가 마련됩니다. 공식 문서의 예는 이렇습니다.

YAML
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

위 매니페스트에서 type: LoadBalancer 라고 적힌 줄이 그 설정입니다. 로드 밸런서가 실제로 만들어지는 일은 비동기로 일어납니다. 마련된 결과는 .status.loadBalancer 에 실립니다. 위 예에서는 ingress 아래의 192.0.2.127 이 그 자리입니다. 같은 문서는 외부 로드 밸런서에서 온 트래픽이 뒤의 파드로 향한다고 적습니다. 어떻게 부하를 나눌지는 클라우드 사업자가 정합니다.

관련 항목

이것과 나란히 미들박스로 묶이는 장치

HTTP 프록시 · 인터셉션 프록시 · 어나니마이저

이것이 속하거나 따르는 상위 분류·표준

미들박스 · RFC 3234 · OSI 모델

이것이 계층에 따라 오가는 프로토콜

TCP(Transmission Control Protocol, 전송 제어 프로토콜) · UDP · TLS(Transport Layer Security, 전송 계층 보안) · HTTP

이것을 대신할 수 있는 다른 수단

DNS · URL · 라우팅 · 콘텐츠 분산 네트워크

이것을 이루는 구성 요소

리스너 · 리스너 규칙 · 타겟 그룹 · 업스트림

이것이 다루는 상태·기능

헬스 체크 · 세션 어피니티 · 스티키 세션 · 페일오버 · 세션

이것을 nginx 에서 켜는 지시어

keepalive · backup · least_time · queue · random · resolver

이것이 후보를 고르는 방식

라운드로빈 · 가중 라운드로빈 · 최소 연결 · 해시 · 일관성 해싱

이것과 역할이 겹쳐 헷갈리는 이웃 장치

리버스 프록시 · 프록시 · 커넥션 풀

이것이 떠받치는 확장·가용성 개념

부하 분산 · 수평 확장 · 고가용성 · 처리량

이것이 놓이는 더 큰 분야

분산 시스템 · 네트워크 · 인프라

이것을 감싸는 쿠버네티스 개념

쿠버네티스 · 클러스터 · 파드 · Service · NodePort · 클러스터 IP · 클라우드 컨트롤러 매니저

이것이 걸쳐 있는 클라우드 인프라

가용 영역 · EC2 인스턴스 · 컨테이너 · 클라우드 · 가용성

이것을 실제로 구현·채택한 제품

AWS · nginx · Network Load Balancer · Application Load Balancer

다른 이름: 로드밸런서 · load balancer · LB · 부하 분산기