HAProxy를 로드 밸런서로 사용한 고가용성

HAProxy를 로드 밸런서로 사용한 고가용성 (HA)

이 가이드는 HAProxy의 네이티브 통합을 사용해 Consul의 서비스 발견 데이터로 로드 밸런서를 자동 구성하는 방법을 설명해요. HAProxy의 server-template 기능과 Consul의 서비스 발견을 활용해 백엔드 서버 풀을 자동으로 확장할 수 있어요.

출처: 문서

본문

이 가이드는 HAProxy의 네이티브 통합을 사용해 Consul의 서비스 발견 데이터로 로드 밸런서를 자동 구성하는 방법을 설명합니다. 이를 통해 HAProxy는 server-template 기능과 Consul의 서비스 발견을 활용해 백엔드 서버 풀을 자동으로 확장할 수 있습니다.

이 가이드에서는 HAProxy의 server-template을 기반으로 기본 HAProxy 구성을 설정합니다. 이 템플릿은 Consul 서비스 발견에 등록된 사용 가능한 서비스 인스턴스를 기반으로 로드 밸런서 백엔드 서버 풀 구성을 생성합니다.

요구 사항 (Requirements)

이 가이드를 완료하려면 Consul과 HAProxy에 대한 사전 경험이 필요합니다. 또한 다음 인프라가 구성되어 있어야 합니다.

  • 웹 UI가 활성화된 Consul 데이터센터.
  • 이 가이드에서 참조하는 웹 서비스와 헬스 체크를 등록할 Consul 클라이언트 노드 최소 3개. 클라이언트 노드에서 enable_local_script_checks를 true로 설정해야 합니다.
  • 각 노드에서 실행되며 HTTP 포트 80에서 수신하는 표준 웹 서버.
  • Consul 클라이언트와 함께 설치된 HAProxy 2.6+(LTS) 버전. HA Proxy 버전별 매뉴얼은 HAProxy documentation을 참조하세요.

이 가이드의 단계를 완료한 후 인프라는 다음 다이어그램과 같아야 합니다.

HAProxy 구성 생성

기본 설치된 HAProxy로 시작합니다. /etc/haproxy/haproxy.cfg 파일 끝에 다음 구성을 추가합니다.

/etc/haproxy/haproxy.cfg

defaults
   timeout connect 5s
   timeout client 1m
   timeout server 1m

frontend stats
   bind *:1936
   mode http
   stats uri /
   stats show-legends
   no log

frontend http_front
   bind *:80
   default_backend http_back

backend http_back
    balance roundrobin
    server-template mywebapp 1-10 _web._tcp.service.consul resolvers consul resolve-opts allow-dup-ip resolve-prefer ipv4 check

resolvers consul
    nameserver consul 127.0.0.1:8600
    accepted_payload_size 8192
    hold valid 5s

프론트엔드 (Frontend)

frontend http_front
   bind *:80
   default_backend http_back

frontend http_front 스탠자는 HAProxy가 TCP 포트 80에서 HTTP 요청을 수신하고 http_back 서버 풀을 해당 로드 밸런서 백엔드로 사용하도록 지시합니다.

백엔드 (Backend)

backend http_back
    balance roundrobin
    server-template mywebapp 1-10 _web._tcp.service.consul resolvers consul resolve-opts allow-dup-ip resolve-prefer ipv4 check

backend http_back 스탠자에는 balance 유형과 server-template 설정이 포함됩니다. 이러한 설정에 대한 설명은 HAProxy Configuration Manual을 참조하세요.

balance 유형은 라운드 로빈으로, 사용 가능한 서비스에 순서대로 로드 밸런싱합니다.

HAProxy server-template 덕분에 Consul 서비스 등록이 HAProxy의 백엔드 서버 풀을 구성할 수 있습니다. 즉 백엔드 서버의 IP 주소를 명시적으로 추가할 필요가 없습니다. 이 구성은 mywebapp이라는 server-template을 지정합니다. 템플릿 이름은 Consul에 등록된 서비스 이름에 연결되어 있지 않습니다.

server-template은 HAProxy의 런타임 구성에서 백엔드 서버를 위한 1-10 슬롯을 프로비저닝합니다. 모두 사용하지 않더라도 최대 10개 인스턴스에 대한 메모리를 예약합니다. 정상이고 사용 가능한 서비스가 10개보다 많으면 HAProxy는 그중 10개만 사용하고 서비스 오류 시 사용 가능한 슬롯을 백필(backfill)합니다. 사용 가능한 슬롯 수를 구성할 수 있습니다.

_web._tcp.service.consul 매개변수는 HAProxy가 백엔드 서비스 _web.service.consul_에 대한 DNS SRV 레코드를 사용해 사용 가능한 서비스를 발견하도록 지시합니다.

또한 이 구성은 resolve-opts allow-dup-ip로 같은 IP 주소에서 다른 포트를 사용하는 두 서비스 인스턴스의 실행을 허용하고, resolve-prefer ipv4로 서비스 엔드포인트의 IPv4 주소를 해석합니다.

마지막으로 서버 템플릿이 Consul의 DNS 인터페이스를 찾을 위치를 발견하기 위해 resolvers consul 스탠자를 보도록 지정하세요.

참고

Consul에는 정교한 분산 헬스 체크가 있으므로, Consul의 헬스 체크 구성과 HAProxy가 Consul 서비스 발견에서 정상 엔드포인트를 발견하는 데 사용하는 업데이트 간격에 따라 추가적인 HAProxy 헬스 check가 반드시 필요하지는 않습니다.

리졸버 (Resolvers)

resolvers consul
    nameserver consul 127.0.0.1:8600
    accepted_payload_size 8192
    hold valid 5s

resolvers consul 스탠자는 HAProxy가 사용할 실제 서비스 발견 엔드포인트를 정의합니다.

nameserver consul 127.0.0.1:8600은 HAProxy를 로컬 Consul 클라이언트의 DNS 인터페이스로 연결합니다.

DNS SRV 레코드는 Consul 서비스 발견의 더 큰 DNS 응답을 초래할 수 있으므로 accepted_payload_size 8192를 구성해 더 큰 페이로드를 허용해야 합니다. 이는 사용 가능하고 정상인 서비스 수에 기반합니다.

마지막으로 hold valid 5s는 HAProxy가 매 5초마다 Consul의 서비스 카탈로그를 확인하여 사용 가능하고 정상인 서비스 엔드포인트의 업데이트를 확인하도록 지시합니다. 이 값은 이 예시에서 더 빠른 서비스 발견을 위해 조정된 값이기도 합니다.

HAProxy 다시 로드

조정된 haproxy.cfg 구성 파일을 적용하려면 HAProxy 인스턴스를 다시 로드하세요.

$ service haproxy reload

HAProxy 설정 확인

http://<Your-HAProxy-IP-address>:1936에서 HAProxy 통계 및 모니터링 페이지에 액세스하여 새 구성 설정을 확인하세요.

웹 서비스 등록

첫 번째 노드의 웹 서비스를 Consul에 등록하려면 Consul의 /etc/consul.d/ 구성 디렉터리에 서비스 정의를 만드세요.

web-service.hcl

service {
  name = "web"
  port = 80
  check {
    args = ["curl", "localhost"]
    interval = "3s"
  }
}

새 서비스 정의를 적용하려면 클라이언트를 다시 로드하세요.

$ consul reload

두 번째 노드에서 이 과정을 반복하여 두 번째 웹 서비스를 등록하세요.

Consul에 서비스가 등록되었는지 확인

등록이 성공했다면 Consul 카탈로그에서 변경 사항을 볼 수 있습니다. 선호하는 방법으로 서비스가 Consul에 올바르게 등록되었는지 확인하세요.

consul catalog 명령을 사용해 사용 가능한 서비스를 확인하세요.

$ consul catalog services
consul
web

로드 밸런싱 확인

HAProxy 모니터링 UI도 서비스를 반영하므로, 사용 가능한 10개 중 두 인스턴스가 현재 실행 중인지 확인할 수 있습니다.

HAProxy 로드 밸런서의 IP 주소로 이동하여 페이지를 여러 번 새로고침하세요. Consul에 두 서비스를 등록했고 HAProxy를 라운드 로빈 로드 밸런싱으로 구성했으므로, 두 사용 가능한 웹 서버 사이에서 연결이 전환되는 것을 볼 수 있습니다.

백엔드 서버 확장

HAProxy는 매 5초마다 Consul의 DNS 인터페이스를 쿼리하여 요청한 서비스 web 내에서 무언가 변경되었는지 확인합니다.

세 번째 노드에서 실행되는 인스턴스를 등록하여 웹 서비스를 확장하세요.

세 번째 Consul 클라이언트의 구성 디렉터리(/etc/consul.d/)에 서비스 정의를 만드세요.

web-service.hcl

service {
  name = "web"
  port = 80
  check {
    args = ["curl", "localhost"]
    interval = "3s"
  }
}

새 서비스 정의를 적용하려면 클라이언트를 다시 로드하세요.

$ consul reload

참고

프로덕션 배포에서는 새 서비스 인스턴스의 등록을 자동화하여 데이터센터에서 새 서비스가 시작될 때 Consul이 알 수 있도록 해야 합니다.

새 웹 서비스를 등록하면 HAProxy가 변경을 감지하고 런타임 구성의 업데이트를 트리거합니다. 백엔드 서버를 두 인스턴스에서 세 인스턴스로 확장한 후 HAProxy 통계 페이지는 결과적인 런타임 로드 밸런서 구성을 반영합니다.

이제 트래픽이 세 사용 가능한 서비스에 모두 로드 밸런싱되어야 합니다.

하나의 백엔드 서비스 중지

HAProxy의 서비스 발견 통합은 사용 가능한 서비스에 따라 백엔드 구성을 자동으로 확장합니다. 최종 구성 렌더링에는 정상 서비스만 사용합니다.

서비스 정의에서 Consul이 기본 curl 헬스 체크를 수행하도록 구성했습니다. Consul은 web 서버 인스턴스가 비정상 상태인지 알아차립니다.

오류를 시뮬레이션하고 Consul 헬스 체크가 어떻게 작동하는지 보려면 백엔드 서버 중 하나에서 웹 서버 프로세스를 중지하세요.

$ service <WEBSERVER> stop

HTTP 포트 80의 요청에 응답하는 서비스가 없어 curl 헬스 체크가 오류를 초래하므로, 이 서비스 인스턴스의 상태는 Consul UI에서 즉시 비정상(unhealthy)이 됩니다.

Consul의 DNS 인터페이스에 대한 정기적인 검사로 인해 HAProxy 인스턴스는 서비스 중 하나의 상태에 변경이 발생했음을 알아차리고 런타임 로드 밸런서 구성을 조정합니다.

이제 HAProxy 인스턴스는 남은 정상 서비스 사이에서만 트래픽을 밸런싱합니다.

통계 페이지에서 HAProxy 인스턴스의 결과적인 런타임 로드 밸런서 구성을 다시 확인할 수 있습니다.

비정상 인스턴스는 HAProxy의 관점에서 오류 상태가 아닙니다. 이 특정 호스트에 대한 DNS 해석이 더 이상 작동하지 않으므로 유지보수 상태(MAINT)에 있습니다.

참고

Consul 헬스 체크는 중앙 로드 밸런서가 모니터링할 수 없는 웹 서비스의 CPU 사용률, RAM 사용량 및 기타 메트릭을 볼 수 있습니다. Consul의 헬스 체크 기능에 대해 자세히 알아보려면 health check tutorial을 참조하세요.

중지된 web 서버 인스턴스를 다시 시작하세요. Consul 헬스 체크가 서비스를 정상으로 표시하고 트래픽을 제공하도록 로드 밸런서 백엔드 구성에 서비스를 다시 추가합니다.

HAProxy 구성에 DNS 가중치 추가

정상 인스턴스만 쿼리하기 위한 Consul의 DNS 인터페이스 외에도 HAProxy의 서비스 발견 통합은 DNS 가중치를 평가할 수 있습니다. 이 섹션에서는 서비스 중 하나를 조정해 더 높은 가중치를 부여합니다. 이는 HAProxy가 백엔드 서버 가중치에 대한 런타임 값을 조정할 수 있게 해주며, 결과적으로 해당 백엔드 서버로 더 많은 트래픽을 보냅니다.

이 접근 방식은 서버 크기가 다르거나 서비스의 일부 인스턴스가 다른 인스턴스보다 더 많은 요청을 처리할 수 있을 때 유용합니다.

현재 가중치 확인

먼저 Consul DNS 인터페이스를 사용해 Consul에서 할당된 DNS 가중치를 확인하세요.

$ dig @127.0.0.1 -p 8600 -t srv web.service.consul +short
1 1 80 web-app-0.node.dc1.consul.
1 1 80 web-app-1.node.dc1.consul.
1 1 80 web-app-2.node.dc1.consul.

DNS 가중치는 포트 번호(여기서는 80) 앞의 열입니다. 현재 모든 정상 서비스에서 DNS 가중치는 Consul이 사용하는 기본값인 1로 설정되어 있습니다.

하나의 서비스에 가중치 추가

HAProxy의 서비스 발견 통합은 주어진 서비스의 변경 사항에 대한 업데이트를 얻기 위해 정기적이고 구성 가능한 기준으로 Consul의 DNS 인터페이스를 쿼리하고 HAProxy의 런타임 구성을 자동으로 조정합니다. DNS 가중치 같은 Consul의 추가 옵션을 구성하여 HAProxy 런타임 구성을 조정하세요.

HAProxy는 1에서 256 사이의 가중치를 지원합니다. Consul의 공식 지원 DNS 가중치는 지원되는 HAProxy 백엔드 서버 가중치와 일치하지 않으므로 다음 공식으로 Consul의 서비스 정의에 구성된 DNS 가중치로 원하는 HAProxy 가중치를 변환해야 합니다.

([Desired weight in HAProxy] * 256) - 1 = (Service weight in Consul)

이 가이드에서는 HAProxy 가중치를 2로 하려고 하며, 이는 다음 계산을 초래합니다.

(2 * 256) - 1 = 511

web 서비스 등록에 weights 옵션을 추가하여 서비스 정의 중 하나를 조정하세요.

web-service.hcl

service {
  name = "web"
  port = 80
  check {
    args = ["curl", "localhost"]
    interval = "3s"
  }
  weights {
    passing = 511
    warning = 1
  }
}

새 서비스 정의를 적용하려면 로컬 Consul 클라이언트를 다시 로드하세요.

$ consul reload

새 가중치 확인

먼저 Consul의 DNS 인터페이스를 확인하여 방금 구성한 서비스 인스턴스에 대해 Consul이 이제 다른 가중치를 표시하는지 확인하세요.

$ dig @127.0.0.1 -p 8600 -t srv web.service.consul +short
1 511 80 web-app-1.node.dc1.consul.
1 1 80 web-app-0.node.dc1.consul.
1 1 80 web-app-2.node.dc1.consul.

둘째, HAProxy 통계 페이지 http://<Your-HAProxy-IP-address>:1936을 확인할 수 있습니다.

마지막으로 세 사용 가능한 서비스 엔드포인트 간에 트래픽이 균등하지 않게 로드 밸런싱되는지 확인하세요. HAProxy 로드 밸런서의 IP 주소로 이동하여 페이지를 여러 번 새로고침하세요. 인스턴스 중 하나가 다른 인스턴스보다 두 배 많은 요청을 제공합니다.

다음 단계 (Next steps)

다른 로드 밸런싱 옵션은 NGINX, F5, Envoy 가이드를 참조하세요.

더 알아보기 (Learn more)