Scenario
I've got a haproxy farm of 3 (apache) webservers. 2 are actively balanced, and the third is a backup normally.
Every so often, I want to take the third server out of the backup role and make it a 'patch' server. But I want to do this without changing the url (eg, I don't want to use patch.mysite.com)
What I want to happen is, I visit http://mysite.com/patch
and have haproxy give the server a cookie for later use in an ACL, but remove the /patch
and send a GET /
to the backend server.
Where I'm at now is the ACL is working fine, but the reqrep is not removing the /patch request before sending it to the backend.
Config:
global
log 127.0.0.1 local0 info
maxconn 25000
daemon
spread-checks 2
defaults
log global
mode http
balance roundrobin
option httplog
option redispatch
option abortonclose
option forwardfor
option http-server-close
frontend webfarm :80
# FILTERING
acl acl_patch path_end /patches
use_backend patch if acl_patch
default_backend default_farm
backend default_farm
cookie SERVERID insert indirect
server prod1 192.168.100.18:80 cookie live01 check
server prod2 192.168.100.22:80 cookie live02 check weight 2
server prod3 192.168.100.20:80 cookie live03 check backup
# do not let this cookie tell our internal IP address
rspidel ^Set-cookie:\ IP=
backend patch
cookie SERVERID insert indirect
server prod3 192.168.100.20:80 cookie live03
reqrep ^([^\ ]*)\ /patch \1\ /
# do not let this cookie tell our internal IP address
rspidel ^Set-cookie:\ IP=
The haproxy log still specifies a GET /patch
being sent to the backend. What am I missing about reqrep (I don't care about anything after the /patch directory)?
First, your rule should also keep the HTTP version part.
Second, why don't you use the "force-persist" statement for this ? It's designed exactly for this role. Just find something in your request that makes it different from your visitors', set a cookie to access it, then you can use this server. This me chanism was made precisely for maintenance operations without having to make the server appear as up for other users.
Alternatively in your case you could also use the "redirect" method, as it supports the "set-cookie" option; In your frontend, you would then replace the use_backend rule with something like this :
Your browser would then learn this cookie and redirect to the /, where server 3 will handle the request. There's even a clear-cookie option that can be used to get rid of the stickiness if you want.