如何在haproxy上负载平衡tcp

how to loadbalance tcp on haproxy

我在 haproxy 后面的 3 台服务器上的端口 8080 上有一个 tcp 服务 运行 我想通过 haproxy

对这些服务器之间的 tcp 流量进行负载平衡
server1 192.168.10.1 8080
server2 192.168.10.2 8080
server3 192.168.10.3 8080

假设 haproxy 服务器 ip 是 192.168.10.10

1.

我可以使用什么 haproxy 配置来实现这一点? 配置激活后访问负载均衡 tcp 流量的端点是什么?

2.

另一件事是,是否可以将该端点代理为没有端口的 url? 类似于基于 http 的路由...那么我可以放置那个 tcp 端点并有办法通过主机名将 http 端点路由到负载均衡的 tcp 服务吗?

所以假设我想在 http://tcp-app.example.com 访问服务,然后应该路由到负载均衡的 tcp 服务

回答1你能以此为起点吗

listen tcp-in
  bind :8080

  mode tcp
  log stdout format raw daemon
  option tcplog

  timeout client   5s
  timeout connect 30s
  timeout server  30s

  server server1 192.168.10.1:8080
  server server2 192.168.10.2:8080
  server server3 192.168.10.3:8080

您可以通过 192.168.10.10:8080 访问负载均衡器。
为了更好地理解 haproxy,这篇博客 post 是一个很好的起点恕我直言
https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/

关于问题 2 你是否应该切换到 Server Name Indication (SNI) 因为 TCP 没有“主机名”的概念。
我在这篇博客 post https://www.me2digital.com/blog/2019/05/haproxy-sni-routing/

中描述了 SNI 路由在 HAProxy 中的工作原理

这里是 TCP 和 HTTP 协议之间的 SNI 路由的示例 haproxy 配置。这有点复杂,因为您需要在 HTTP 路由之前检查 TCP 路由。

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log stdout format raw daemon debug

    maxconn     5000

    tune.ssl.default-dh-param 3072

    # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy-1.8.0&openssl=1.1.0i&hsts=yes&profile=modern
    # set default parameters to the intermediate configuration
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options ssl-min-ver TLSv1.1 no-tls-tickets

    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options ssl-min-ver TLSv1.1 no-tls-tickets
    
    # https://www.haproxy.com/blog/dynamic-configuration-haproxy-runtime-api/
    stats socket ipv4@127.0.0.1:9999 level admin
    stats socket /var/run/haproxy.sock mode 666 level admin
    stats timeout 2m

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    tcp
    log                     global
    option                  dontlognull
    #option                  logasap
    option                  srvtcpka
    option                  log-separate-errors
    retries                 3
    timeout http-request    10s
    timeout queue           2m
    timeout connect         10s
    timeout client          5m
    timeout server          5m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 750

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------

##
## Frontend for HTTP
##
frontend http-in
    bind :::80 v4v6
    mode http
    option httplog

    tcp-request inspect-delay 5s
    tcp-request content accept if HTTP

    # redirect http to https .
    http-request redirect scheme https unless { ssl_fc }

##
## Frontend for HTTPS
##
frontend public_ssl

    bind :::443 v4v6 

    option tcplog

    tcp-request inspect-delay 5s
    tcp-request content capture req.ssl_sni len 25
    tcp-request content accept if { req.ssl_hello_type 1 }
    
    # https://www.haproxy.com/blog/introduction-to-haproxy-maps/
    use_backend %[req.ssl_sni,lower,map(tcp-domain2backend-map.txt)]

    default_backend be_sni

##########################################################################
# TLS SNI
#
# When using SNI we can terminate encryption with dedicated certificates.
##########################################################################
backend be_sni
  server fe_sni 127.0.0.1:10444 weight 10 send-proxy-v2-ssl-cn

backend be_sni_xmpp
  server li_tcp-in 127.0.0.1:8080 weight 10 send-proxy-v2-ssl-cn

# handle https incoming
frontend https-in

    # terminate ssl 
    bind 127.0.0.1:10444 accept-proxy ssl strict-sni alpn h2,http/1.1 crt haproxy-certs

    mode http
    option forwardfor
    option httplog
    option http-ignore-probes

    # Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
    http-request del-header Proxy

    http-request set-header Host %[req.hdr(host),lower]
    http-request set-header X-Forwarded-Proto https
    http-request set-header X-Forwarded-Host %[req.hdr(host),lower]
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request set-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
    http-request add-header Forwarded for=\"[%[src]]\";host=%[req.hdr(host),lower];proto=%[req.hdr(X-Forwarded-Proto)];proto-version=%[req.hdr(X-Forwarded-Proto-Version)]

    # Add hsts https://www.haproxy.com/blog/haproxy-and-http-strict-transport-security-hsts-header-in-http-redirects/
    # http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"

    # https://www.haproxy.com/blog/introduction-to-haproxy-maps/
    use_backend %[req.hdr(host),lower,map(http-domain2backend-map.txt)]

#---------------------------------------------------------------------
#  backends
#---------------------------------------------------------------------
## backend for cloud.DOMAIN
backend nextcloud-backend
    mode http
    option httpchk GET / HTTP/1.1\r\nHost:\ BACKEND_VHOST
    server short-cloud 127.0.0.1:81 check 


## backend for dashboard.DOMAIN
backend dashboard-backend
    mode http
    server short-cloud 127.0.0.1:82 check

## backend for upload.DOMAIN
backend httpupload-backend
    log global
    mode http
    server short-cloud 127.0.0.1:8443 check

listen tcp-in
  bind :8080 accept-proxy ssl strict-sni crt haproxy-certs

  mode tcp
  log stdout format raw daemon
  option tcplog

  timeout client   5s
  timeout connect 30s
  timeout server  30s

  server server1 192.168.10.1:8080
  server server2 192.168.10.2:8080
  server server3 192.168.10.3:8080

文件tcp-domain2backend-map.txt

tcp-service.mydomain.im be_sni_xmpp

文件http-domain2backend-map.txt

# http backends
nextcloud.MyDomain.com nextcloud-backend
dashboard.MyDomain.com dashboard-backend 
jabupload.MyDomain.com httpupload-backend