【问题标题】:how to loadbalance tcp on haproxy如何在 haproxy 上对 tcp 进行负载平衡
【发布时间】:2020-09-06 22:20:31
【问题描述】:

我在 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 服务

【问题讨论】:

    标签: tcp load-balancing haproxy


    【解决方案1】:

    回答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,这篇博文是一个很好的起点恕我直言
    https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/

    对于问题2,您是否应该切换到Server Name Indication (SNI),因为TCP 没有“主机名”的概念。
    我已经在这篇博文 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
    

    【讨论】:

    • in #1 answer..你有这行listen tcp-in 你介意解释listen 的含义和tcp-in 的含义吗?这些只是可以更改的名称还是意味着什么?
    • + 还可以说在端口 8081 上的服务器上还有另一个 tcp 服务..我会有相同的块但用 8081 代替吗?这就是全部
    • 指令listen tcp-in 在这篇博文haproxy.com/blog/… 中有解释。是的,对于另一个端口,您可以复制 listen 块。
    猜你喜欢
    • 1970-01-01
    • 2016-12-25
    • 2015-09-21
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2011-06-22
    相关资源
    最近更新 更多