It’s trivial to do local backend health check, but what if we want to know if the server we are failing over is actually with healthy backends or if remote backends are down. Also, this task must make sure that clients get redirected to remote servers, not passed through local instance.
Lets say, we have 3 servers. For configuration management simplicity, all of them must have identical configuration.
frontend main_frontend
mode http
option httplog
bind *:443 ssl crt /path/cert.pem
acl local_server_dead nbsrv(local_backend) lt 1
use_backend remote_servers if local_server_dead
default_backend local_backend
frontend health_status
mode http
bind *:1443 ssl crt /path/cert.pem ca-file /path/ca-file.crt verify required
acl local_backend_down nbsrv(local_backend) lt 1
monitor-uri /testfile.html
monitor fail if local_backend_down
backend local_backend
mode http
option httplog
balance leastconn
server 127.0.0.1:9000 check
server 127.0.0.1:9001 check
backend remote_servers
mode http
option httplog
option httpchk HEAD /testfile.html HTTP/1.1\r\nHost:\ foo.bar.com
balance roundrobin
server server1 1.2.3.1:1443 redir https://server1.bar.com check ssl crt /path/cert.pem ca-file /path/ca-file.crt verify required
server server2 1.2.3.2:1443 redir https://server2.bar.com check ssl crt /path/cert.pem ca-file /path/ca-file.crt verify required
server server3 1.2.3.3:1443 redir https://server3.bar.com check ssl crt /path/cert.pem ca-file /path/ca-file.crt verify required
There are two different ACL-s which do the same thing. It is because haproxy does allow acl statements only inside frontend, listen and backend statements. And acl specified inside one frontend cannot be used within other frontend.
HTTPS connections to main_frontend are proxied to local_backend servers in the manner that all servers should have equal amount of connections.
If there are less than 1 healthy server in local_backend, connections are proxied to remote_server servers in round_robin fashion. Because we do redirect, we have no idea how many connections remote server has and roundrobin is the most equal possible distribution.
Redirection is done only if server is in UP state.
When all servers in local_backend are down, frontend health_status answers to health check requests from remote_servers with 503 instead of 200. This causes that server to go into state DOWN and it does not get any redirections.