Recentemente, tentei configurar o roteamento baseado em SNI no HAProxy para mongodb+srv
conexão do protocolo mongodb.
Eu fiz funcionar, mas não foi até eu colocar
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
na minha configuração de frontend que começou a funcionar corretamente
Sem eles (ou com apenas um deles), continuei recebendo redefinições de conexão esporádicas em cerca de 70% das minhas solicitações. Observe que em algum momento a conexão conseguiu se estabelecer.
De acordo com http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4-tcp-request%20content
As regras baseadas em conteúdo são avaliadas em sua ordem de declaração exata. Se nenhuma regra corresponder ou se não houver regra, a ação padrão é aceitar o conteúdo. Não há limite específico para o número de regras que podem ser inseridas.
Portanto, deveria estar funcionando por padrão.
Ou estou perdendo algum conceito TCP fundamental ou algum detalhe específico da conexão do Mongo. Mas notei que quase todos têm a mesma regra definida quando vão para o roteamento baseado em SNI, então deve fazer sentido para a maioria das pessoas.
Configuração HAProxy de trabalho:
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
Também vale a pena mencionar que o HAProxy é implantado no Kubernetes (cluster gerenciado pelo Google no GCP), possui um istio-sidecar e é exposto por meio do serviço Internal LoadBalancer k8s.
Como afirmado, a configuração acima funciona perfeitamente bem. O que me interessa é por que tcp-request content accept
é absolutamente necessário e a conexão nem sempre é aceita por padrão aqui.