HAProxy Change Farm and Soft Stop Server on current farm - haproxy

Im pretty new to load balancing and using HAProxy.
After doing a lot of reading and setting up my own development environment, I am unable to work out the following:
I have a bank of web servers which traffic is being balanced across, how do I soft stop these servers whilst i fail over to a new bank?
My test congif looks like this:
frontend front-end-test
maxconn 2000
bind 192.168.0.10:8666
use_backend back-end-test-a
backend back-end-test-a
mode http
balance roundrobin
option forwardfor
server machine1 10.1.1.92:44410 weight 1 maxconn 2000 check
server machine2 10.1.1.92:44420 weight 1 maxconn 2000 check
backend back-end-test-b
mode http
balance roundrobin
server machine3 10.1.1.92:44430 weight 1 maxconn 2000 check
server machine4 10.1.1.92:44440 weight 1 maxconn 2000 check
To change banks the config would be updated and the hot restart used:
frontend front-end-test
maxconn 2000
bind 192.168.0.10:8666
use_backend back-end-test-a
To
frontend front-end-test
maxconn 2000
bind 192.168.0.10:8666
use_backend back-end-test-b
So to recap, I need to update the config so my backend farm changes but any requests for the original servers still need to be served by them.
Is this possible?
Adam

Normally, if I want to change backends, I would switch it right away (as in change to use_backend back-end-test-b) and do a graceful reload by delaying SYN packets (new incoming connections) before restarting the haproxy service. Ex:
iptables -I INPUT -p tcp --dport 8666 --syn -j DROP
sleep 1
service haproxy restart
iptables -D INPUT -p tcp --dport 8666 --syn -j DROP
The delay should allow running requests to finish before that service restarts and applies the new config.
This may not work for long running transactions though.

Related

Send request with self signed certificates to backend

The Haproxy documentation (http://cbonte.github.io/haproxy-dconv/1.7/intro.html#3.3.2) lists as a basic feature:
authentication with the backend server lets the backend server it's really the expected haproxy node that is connecting to it
I have been attempting to do just that and have been unable to. So here's the question:
How do I send a request off to a backend with self signed certificates for authentication. The front-end request that uses this backend, is just http.
Here's my haproxy.cfg file:
global
maxconn 4096
daemon
log 127.0.0.1 local0
defaults
log global
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5s
timeout client 15min
timeout server 15min
frontend public
bind *:8213
use_backend api if { path_beg /api/ }
default_backend web
backend web
mode http
server blogweb1 127.0.0.1:4000
backend api
mode tcp
acl clienthello req.ssl_hello_type 1
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
server blogapi 127.0.0.1:8780
I eventually got this to start working. I believe what was throwing me off was the fact that after doing a haproxy -f <configFile> -st it didn't actually close the process like I thought it would. So, none of my changes/updates took. I kill -9 the tens of haproxy service and reran the command (haproxy -f ) and now it's working.
Now, this is a hypothesis, albeit one I am very confident in. I will still present my final configuration just in case someone will glean something from here. I used https://www.haproxy.com/doc/aloha/7.0/deployment_guides/tls_layouts.html. That link answers the question I had of "how do you authenticate to the backend using ssl" like the docs say you can.
global
maxconn 4096
daemon
log 127.0.0.1 local0
defaults
log global
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5s
timeout client 15min
timeout server 15min
frontend public
bind *:443
mode http
use_backend api if { path_beg /api/ }
backend api
mode http
option httplog
server blogapi 127.0.0.1:4430 ssl ca-file <caFile.Pem> crt <clientCert.pem> verify required

How to configure haproxy to use a different backend for each request

I have an Haproxy 1.5.4. I would like to configure the haproxy to use a different backend for each request. This way , I want to ensure that a diffeent backend is used for each request. I curently use the following config:
global
daemon
maxconn 500000
nbproc 2
log 127.0.0.1 local0 info
defaults
mode tcp
timeout connect 50000ms
timeout client 500000ms
timeout server 500000ms
timeout check 5s
timeout tunnel 50000ms
option redispatch
listen httptat *:3310
mode http
stats enable
stats refresh 5s
stats uri /httpstat
stats realm HTTPS proxy stats
stats auth https:xxxxxxxxxxx
listen HTTPS *:5008
mode tcp
#maxconn 50000
balance leastconn
server backend1 xxx.xxx.xxx.xxx:125 check
server backend1 xxx.xxx.xxx.xxx:126 check
server backend1 xxx.xxx.xxx.xxx:127 check
server backend1 xxx.xxx.xxx.xxx:128 check
server backend1 xxx.xxx.xxx.xxx:129 check
server backend1 xxx.xxx.xxx.xxx:130 check
......
simply change the balance setting from leastconn to roundrobin
from the haproxy manual for 1.5 :
roundrobin Each server is used in turns, according to their weights.
This is the smoothest and fairest algorithm when the server's
processing time remains equally distributed. This algorithm
is dynamic, which means that server weights may be adjusted
on the fly for slow starts for instance. It is limited by
design to 4095 active servers per backend. Note that in some
large farms, when a server becomes up after having been down
for a very short time, it may sometimes take a few hundreds
requests for it to be re-integrated into the farm and start
receiving traffic. This is normal, though very rare. It is
indicated here in case you would have the chance to observe
it, so that you don't worry.
https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-balance

Can haproxy be configured to understand SSL sessions without being sticky to time

Am using HAProxy version haproxy-1.4.24 on a SLES 11 SP3 server. I need to load balance (using least connections or round robin) between 3 servers which talk only SSL. A session from client to server starts with client/server handshake followed by a series of "chatty" messages and then close of session.
I do not want to use stick src directive since it needs a time limit argument, making my load balancing ineffective.
Below is the configuration file am using. Can someone let me know how to achieve per session stickiness (one client sticks to one server until the SSL session ends)?
global
log /dev/log local0
log /dev/log local1 notice
#chroot /var/lib/haproxy
#stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
#user haproxy
#group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend localnodes
bind *:80
bind *:443
mode tcp
default_backend nodes
backend nodes
mode tcp
balance roundrobin
stick-table type ip size 200k expire 30m
stick on src
server s1 s1.mydomain.com:443 check
server s2 s2.mydomain.com:443 check
server s3 s3.mydomain.com:443 check

haproxy not allowing external traffic through

I set up and haproxy on a mesosphere cluster and set up three web servers using marathon. Now I am trying to load balance between them using this config
global
daemon
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
defaults
log global
retries 3
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
listen stats
bind 127.0.0.1:9090
balance
mode http
listen apiserver
bind 0.0.0.0:80
mode tcp
balance leastconn
server apiserver-3 10.132.62.240:31000 check
server apiserver-2 10.132.62.243:31000 check
server apiserver-1 10.132.62.242:31000 check
Now if I am in the VPN I can connect to the server normally - however externally I am unable to do that.Other Services manage to use the ports without problems (both local and global) but haproxy can't seem to work. If I put haproxy in a docker container it works , however I don't want to do that

How can I make HAProxy reject TCP connections when all backend servers are down

We are using HAProxy to forward incoming TCP connections to a separate server that uses a raw TCP. The issue that we are seeing is that the client connection is accepted and then closed rather then rejected immediately. Since we have enabled a health check is there any way for HAProxy to unbind from the port so that the initial connection fails?
listen custom_forward
mode tcp
bind *:11144
default-server inter 10m fastinter 20s downinter 1m maxconn 100
server custom_server hostname:10144 check
You want to explicitly reject the connection if backend servers are down:
acl site_dead nbsrv lt 1
tcp-request connection reject if site_dead
Or acl site_dead nbsrv(backend_name) lt 1 where backend_name is the name of a different backend.
nbsrv documentation
acl documentation
tcp-reject documentation