최근 mongodb 프로토콜 연결을 위해 HAProxy에서 SNI 기반 라우팅을 설정하려고 했습니다 mongodb+srv
.
작동하게 만들었지만 넣기 전까지는 그렇지 않았습니다.
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
내 프런트엔드 구성에서 제대로 작동하기 시작했습니다.
이것들이 없으면 (또는하나만으로이 중) 요청의 약 70%에 대해 산발적인 연결 재설정이 계속 발생했습니다. 때때로 연결이 설정되었습니다.
에 따르면http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4-tcp-request%20content
콘텐츠 기반 규칙은 정확한 선언 순서에 따라 평가됩니다. 일치하는 규칙이 없거나 규칙이 없는 경우 기본 작업은 내용을 수락하는 것입니다. 삽입할 수 있는 규칙 수에는 특별한 제한이 없습니다.
따라서 기본적으로 작동했어야 합니다.
기본적인 TCP 개념이나 특정 Mongo 연결 세부 정보가 누락되었습니다. 그러나 나는 거의 모든 사람들이 SNI 기반 라우팅을 선택할 때 정의된 동일한 규칙을 가지고 있으므로 대부분의 사람들에게 이해가 될 것입니다.
HAProxy 구성 작동:
frontend fe_mongo-nonprod
bind :27017
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl mongoAtlas-01 req_ssl_sni -i host1.mongodb.net
acl mongoAtlas-02 req_ssl_sni -i host2.mongodb.net
acl mongoAtlas-03 req_ssl_sni -i host3.mongodb.net
use_backend be_mongo-nonprod if mongoAtlas-01 || mongoAtlas-02 || mongoAtlas-03
backend be_mongo-nonprod
mode tcp
acl mongoAtlas-01 req_ssl_sni -i host1.mongodb.net
acl mongoAtlas-02 req_ssl_sni -i host2.mongodb.net
acl mongoAtlas-03 req_ssl_sni -i host3.mongodb.net
use-server server-01 if mongoAtlas-01
use-server server-02 if mongoAtlas-02
use-server server-03 if mongoAtlas-03
server server-01 host1.mongodb.net:27017
server server-02 host2.mongodb.net:27017
server server-03 host3.mongodb.net:27017
HAProxy는 Kubernetes(GCP의 Google 관리형 클러스터)에 배포되고 istio-사이드카가 있으며 내부 LoadBalancer k8s 서비스를 통해 노출된다는 점도 언급할 가치가 있습니다.
언급한 바와 같이 위의 구성은 완벽하게 잘 작동합니다. 내가 관심 있는 것은 왜 tcp-request content accept
절대적으로 필요하고 여기에서는 연결이 기본적으로 [항상] 허용되지 않는지입니다.
답변1
나는 내 자신의 질문에 대해 좀 생각해 본 후에 대답하려고 노력할 것입니다.
따라서 HAProxy 문서에는 다음과 같은 언급도 있습니다. http://cbonte.github.io/haproxy-dconv/2.0/configuration.html
콘텐츠 전환이 필요한 경우 아래 예와 같이 먼저 완전한 클라이언트 hello(유형 1)를 기다리는 것이 좋습니다.
이제 SNI 데이터는 요청의 Client Hello 섹션에도 포함되어 있으므로(https://www.rfc-editor.org/rfc/rfc6066#page-6) 내 가정은 다음과 같습니다.
Client Hello가 여러 TCP 패킷에 분산되어 있고 no 경우 tcp-request content accept is configured
첫 번째 패킷을 수신하면 HAProxy가 이를 라우팅하려고 시도하고 두 가지 중 하나가 발생합니다.
- 기본 백엔드가 구성된 경우 패킷은 이 백엔드로 전달됩니다.
- 기본 백엔드가 구성되지 않은 경우(필자의 경우) 패킷이 삭제되고 연결이 재설정됩니다.
또한 설명된 첫 번째 경우에도 백엔드 섹션에 있는 서버 HAProxy 지점에는 SNI가 필요할 수도 있습니다. 따라서 SNI 표시 없이 불완전한 요청을 전달하면 연결이 재설정됩니다.