HTTP로드 밸런싱 계층을 확장하는 핵심은 먼저 하위 레벨 (IP 또는 TCP)로드 밸런싱의 다른 계층을 추가하는 것입니다. 이 계층은 오픈 소스 소프트웨어로 완전히 구축 할 수 있지만 최신 라우터를 사용하면 더 나은 결과를 얻을 수 있습니다.
플로우 (TCP 세션)는 소스 / 대상 IP 및 TCP 포트와 같은 헤더를 사용하여 해시 되어 어떤 프론트 엔드로 이동해야하는지 결정해야합니다. 또한 프론트 엔드가 죽을 때 사용이 중지되도록하는 메커니즘이 필요합니다.
다양한 전략이 있습니다. 저는 수백만 명의 사용자에게 서비스를 제공하는 사이트에서 프로덕션에 사용한 몇 가지를 간략하게 설명하겠습니다. 모든 것을 자세히 설명하기에는 너무 길지만이 답변이 시작하기에 충분한 정보 / 포인터를 제공하기를 바랍니다. 이러한 솔루션을 구현하려면 네트워킹에 대해 잘 알고있는 사람이 필요합니다.
필자가 여기서 설명하는 것은 다른 답변에 설명 된 것보다 구현하기가 훨씬 어렵지만, 99.9 % 이상의 확장 성 문제 및 가용성 요구 사항이있는 트래픽이 많은 웹 사이트를 보유한 경우 실제로는 최신 기술입니다. . 이미 온보드 네트워크 엔지니어를 보유하고 있다면로드 밸런서 어플라이언스보다 설치 및 실행 비용이 적고 (CAPEX 및 Opex 모두), 추가 비용없이 추가로 확장 할 수 있습니다. 현재 모델을 능가하는 고가의 기기).
첫 번째 전략 : 방화벽
아마도 ISP 업 링크가 연결된 몇 개의 라우터가있을 것입니다. ISP는 2 개의 링크를 제공합니다 (VRRP를 사용하여 활성 / 수동). 라우터에서도 VRRP를 사용하며 공용 네트워크로가는 트래픽을 방화벽으로 라우팅합니다. 방화벽은 ( FW 1
그리고 FW 2
아래)도 또한 액티브 / 패시브하고 (당신의 HTTP로드 밸런서, 트래픽을 필터링하고 건강한 프런트 엔드 서버에 각각의 흐름을 보낼 것입니다 FE 1
및 FE 2
아래).
+ -------------- + + -------------- +
| ISP 라우터 A | | ISP 라우터 B |
+ -------------- + + -------------- +
| |
== # ====================== # == (공용 네트워크)
| |
+ --------------- + + --------------- +
| 라우터 A | | 라우터 B |
+ --------------- + + --------------- +
| |
== # ===== # ========== # ===== # == (RFC 1918 개인 네트워크)
| | | |
+ ------ + + ------ + + ------ + + ------ +
| FW 1 | | 2 월 1 일 | | 2 월 2 일 | | FW 2 |
+ ------ + + ------ + + ------ + + ------ +
목표는 다음과 같은 흐름을 유지하는 것입니다.
- ISP는 IP로가는 트래픽을 활성 라우터로 라우팅합니다.
- 라우터는 트래픽을 RFC 1918 주소 를 사용하는 VIP로 라우팅합니다 . 이 VIP는 VRRP와 같이 활성 방화벽이 소유합니다. 방화벽 요구 사항에 OpenBSD를 사용하는 경우 VRRP / HSRP의 특허없는 대안 인 CARP 를 사용할 수 있습니다 .
- 방화벽이 필터를 적용합니다 (예 : "이 특정 IP 주소로가는 80 / tcp 및 443 / tcp 만 허용").
- 방화벽은 라우터 역할을하며 패킷을 정상적인 프론트 엔드로 전달합니다.
- 프론트 엔드가 TCP 연결을 종료합니다.
이제 마술은 4 단계와 5 단계에서 이루어 지므로 더 자세한 내용을 살펴 보겠습니다.
방화벽은 프런트 엔드 목록 ( FE 1
과 FE 2
)을 알고 있으며 흐름의 특정 측면에 따라 (예 : 다른 헤더 중에서 소스 IP 및 포트를 해시) 이들 중 하나를 선택합니다. 그러나 또한 트래픽을 정상적인 프론트 엔드로 전달해야합니다. 그렇지 않으면 트래픽이 블랙홀됩니다. 예를 들어 OpenBSD를 사용한다면을 사용할 수 있습니다 relayd
. 뭐relayd
간단합니다 : 모든 프론트 엔드의 상태를 점검합니다 (예 : 프로브 HTTP 요청을 전송하여), 프론트 엔드가 정상일 때 방화벽이 주어진 플로우의 패킷의 다음 홉을 선택하는 데 사용하는 테이블에 추가합니다. . 프런트 엔드가 상태 확인에 실패하면 테이블에서 제거되고 더 이상 패킷이 전송되지 않습니다. 패킷을 프런트 엔드로 전달할 때 모든 방화벽은 패킷의 대상 MAC 주소를 선택한 프런트 엔드의 주소로 교체합니다.
5 단계에서 사용자의 패킷은로드 밸런서 (Varnish, nginx 등)에 의해 수신됩니다. 이 시점에서 패킷은 여전히 공개 IP 주소로 보내 지므로 루프백 인터페이스에서 VIP의 별칭을 지정해야합니다. 이 호출됩니다 DSR 당신의 프론트 엔드는 TCP 연결 만이 단순 트래픽을 보는 사이에 방화벽 (들어오는 패킷)를 종료하기 때문에, (직접 서버 반환). 라우터는 나가는 패킷을 ISP의 라우터로 직접 라우팅합니다. 요청이 응답보다 작은 경향이 있기 때문에 HTTP 트래픽에 특히 유용합니다. 분명히 말하면 : 이것은 OpenBSD에만 해당되는 것이 아니며 트래픽이 많은 웹 사이트에서 널리 사용됩니다.
잡았다 :
- DSR을 사용하기 때문에 최종 사용자는 프런트 엔드 서버에 직접 연결됩니다. 어쩌면 이미 그런 경우 였을 수도 있지만 그렇지 않은 경우에는 제대로 고정되어 있는지 확인해야합니다.
- OpenBSD를 사용하는 경우 커널이 단일 스레드이므로 단일 CPU 코어의 성능으로 인해 방화벽의 처리량이 제한됩니다. NIC 유형과보고있는 패킷 속도에 따라 문제가 될 수 있습니다. 이 문제를 해결하는 방법이 있습니다 (자세한 내용은 아래 참조).
두 번째 전략 : 방화벽없이
이 전략은 사용하는 라우터의 특성에 따라 달라 지므로보다 효율적이지만 설정하기가 어렵습니다. 아이디어는 위의 방화벽을 무시하고 라우터가 방화벽이 수행 한 모든 작업을 수행하도록하는 것입니다.
포트 별 L3 / L4 ACL, BGP 및 ECMP 및 정책 기반 라우팅 (PBR) 을 지원하는 라우터가 필요합니다 . 고급 라우터 만 이러한 기능을 지원하며 종종 BGP를 사용하기 위해 추가 라이센스 비용이 부과됩니다. 이는 일반적으로 하드웨어로드 밸런서보다 저렴하며 확장하기가 훨씬 쉽습니다. 이 하이 엔드 라우터의 장점은 회선 속도 (예 : 10GbE 인터페이스에서도 링크를 최대한 활용할 수 있음)는 모든 결정이 ASIC에 의해 하드웨어에서 이루어지기 때문입니다.
ISP 업 링크가있는 포트에서 방화벽에있는 ACL을 적용하십시오 (예 : "이 특정 IP 주소로가는 80 / tcp 및 443 / tcp 만 허용"). 그런 다음 각 프론트 엔드가 라우터와 BGP 세션을 유지하도록하십시오. 우수한 OpenBGPD (프런트 엔드가 OpenBSD에있는 경우) 또는 Quagga를 사용할 수 있습니다 . 라우터는 BGP 세션을 유지하고 있기 때문에 정상인 프론트 엔드에 대한 트래픽을 ECMP합니다. 라우터는 또한 PBR을 사용하여 트래픽을 적절히 라우팅합니다.
개선
- 방화벽 쌍 솔루션을 사용하면 방화벽을 통해 TCP 상태를 동기화 할 수있어 한 방화벽이 실패 할 때 모든 방화벽이 다른 방화벽으로 원활하게 실패 할 수 있습니다. 으로이 작업을 수행 할 수 있습니다
pfsync
.
- 마음에 베어
pfsync
일반적으로 방화벽의 패킷 속도를 두 배로.
- HTTP는 상태 비 저장 프로토콜이므로을 사용하지 않기 때문에 방화벽 장애 조치 (failover) 중에 모든 연결을 재설정하면 끝이 아닙니다
pfsync
.
- 단일 방화벽을 능가하는 경우 라우터에서 ECMP를 사용하여 트래픽을 둘 이상의 방화벽 쌍으로 라우팅 할 수 있습니다.
- 둘 이상의 방화벽 쌍을 사용하는 경우 방화벽을 모두 활성 / 활성으로 만들 수도 있습니다. 방화벽이 라우터와의 BGP 세션을 유지하도록함으로써 방화벽을 만들지 않고도 프런트 엔드가 2 차 설계에서 1을 유지해야하는 것처럼 방화벽을 확보 할 수 있습니다.
샘플 relayd
구성
https://calomel.org/relayd.html의 HOWTO도 참조 하십시오
vip = "1.2.3.4"# 퍼블릭 IP 주소
# (하나 이상 가질 수 있지만 반드시 그럴 필요는 없습니다)
fe1 = "10.1.2.101"
fe2 = "10.1.2.102"
fe3 = "10.1.2.103"
fe4 = "10.1.2.104"# 여러 프런트 엔드를 가질 수 있습니다.
int_if = "em0"
표 <fe> {$ fe1 재시도 2, $ fe2 재시도 2, $ fe3 재시도 2, $ fe4 재시도 2}
테이블 <fallback> {127.0.0.1}
웹 트래픽 리디렉션 {
$ vip 포트 80으로 청취
세션 시간 초과 60
<fe> 라우트 http "/healthcheck.html"다이제스트 "(healthcheck.html의 sha1sum)"인터페이스 $ int_if
}