Report health of TCP mode frontends to external health-checks


#1

Dear all,
I am struggling with a planned setup (yes, it could be done more elegantly, but the solution has to fit into an existing setup):

  • haproxy in TCP mode, load-balances between two backend servers.
  • an external LB in front needs to be able to check if the frontend (= at least one backend server) is up

Now:

  • When the external LB uses a TCP health check, it considers the frontend always up, because the TCP-handshake is successful (haproxy sends a RST right after the TCP handshake, but the external LB (A10) looks only at the SYN/ACK and considers the service is up).

  • I can configure a separate HTTP frontend on a different port for testing purposes and have the external LB do an HTTP health check:

    listen svc1
    bind 10.0.0.1:5555
    server 192.168.0.1:5555 check

    frontend HEALTH-svc1
    bind 10.0.0.1:80
    mode http
    acl service_dead nbsrv(svc1) lt 1
    monitor-uri /health
    monitor fail if service_dead

Here’s the catch:
I have about 200 TCP mode proxies configured. They all should be health-checked by the external LB, one by one. With the above configuration, I would have to define 200 additional health-check frontends, each using one dedicated TCP port, because this configuration is not intended to work:

*** NOTE CONFIG BELOW DOES NOT WORK, just an example ***
frontend HEALTH-checker
      bind 10.0.0.1:80 
      mode http

      acl svc1_dead nbsrv(svc1)  lt 1
      monitor-uri /health/svc1
      monitor fail if svc1_dead

      acl svc2_dead nbsrv(svc2)  lt 1
      monitor-uri /health/svc2
      monitor fail if svc2_dead

Or have a different approach:

Let haproxy answer to specific URLs with the status of the requested frontend:
GET /health/{frontend_name} => reply with HTTP/200 if frontend is up, HTTP/503 if frontend is down, HTTP/508 if this frontend does not exist.

Is there any way to configure HAProxy to have this functionality? If not: Can I add this to the haproxy wishlist?
Any thoughts on this? Or is there any way to have a similar functionality I missed?

Mathias Weiersmueller


#2

Create a backend (in http mode) dedicated to the 503 error (perhaps even with a customer error message), and redirect to it when there are no servers available.

So something like the below:

listen Test
 bind :2291
 use_backend 503 if { nbsrv  lt 1 }
 server test-src2 10.0.0.254:80
listen Test2
 bind :2292
 use_backend 503 if { nbsrv lt 1 }
 server test-src3 10.0.0.99:80 disabled
backend 503
 mode http
 errorfile 503 /etc/haproxy/503.http

When you customized the 503 error file, make sure to include HTTP headers and use DOS line endings (CR-LF).