HAproxy 1.5.8 How do I configure Cookie based stickiness?

Vanessa Bullock picture Vanessa Bullock · Nov 23, 2014 · Viewed 35k times · Source

Our application requires cookie based sticky sessions, so we want to use HAproxy to balance incoming traffic towards a farm of IIS servers.

We are using the following config which seems to work on the lab (round-robin working fine and session preserved), but fails when applied in producion with more that 3k concurrent users:

frontend Front_http

bind :80
mode http
default_backend backend_http
stats enable
capture cookie ASP.NET_SessionId len 32
maxconn 10000

frontend Front_https

mode http
default_backend backend_https
bind *:443 ssl crt /etc/haproxy/cert.pem 
capture cookie ASP.NET_SessionId len 32
maxconn 10000

backend backend_http

 balance roundrobin
 option forwardfor
 stick-table type ip size 20k expire 5m
 appsession ASP.NET_SessionId len 64 timeout 5m request-learn prefix
 server Server_1 192.168.10.81:80 cookie Server_1
 server Server_2 192.168.10.81:80 cookie Server_2
 server Server_3 192.168.10.81:80 cookie Server_3

backend backend_https

 balance roundrobin
 option forwardfor
 stick-table type ip size 20k expire 5m
 appsession ASP.NET_SessionId len 64 timeout 5m request-learn prefix
 server Server_1 192.168.10.81:80 cookie Server_1 ssl verify none
 server Server_2 192.168.10.81:80 cookie Server_2 ssl verify none
 server Server_3 192.168.10.81:80 cookie Server_3 ssl verify none
 http-request set-header X-Forwarded-Port %[dst_port]
 http-request add-header X-Forwarded-Proto https if { ssl_fc }

From the HAProxy 1.5.8 documentation I understand cookie based stickiness is achieved with command "appsession", but I don't understand the role other commands play, like "capture cookie" or "stick-table", are they necessary at all when using appsession? Can anyone help me understand how they work, and advise if you detect anything wrong with our config.

Answer

Baptiste picture Baptiste · Nov 24, 2014

First of all, could you explain what "does not work" or which problems are you facing with your current configuration?

There are a few issues in your current configuration: - appsession stickness does not resist to a reload. It means stickiness is lost after each reload of HAProxy - you may have a typo in your SSL backend, since you're forwarding SSL traffic to port 80, which is the same port you used for clear HTTP.

HAProxy allows many ways to do cookie based persistence.

  • cookie insertion: HAProxy set up itself a cookie:

    backend mybk
      [...]
      cookie SERVERID insert indirect nocache
      [...]
      server s1 10.0.0.1:80 check cookie s1
      server s2 10.0.0.2:80 check cookie s2
    
  • cookie prefix: HAProxy uses an existing cookie 'usually application one) and prefix its value by the server name:

    backend mybk
      [...]
      cookie ASP.NET_SessionId prefix nocache
      [...]
      server s1 10.0.0.1:80 check cookie s1
      server s2 10.0.0.2:80 check cookie s2
    
  • stick table: HAProxy learn and use the application cookie, without modifying it:

    backend mybk
      [...]
      stick-table type string len 64 size 100k expire 15m
      stick store-response res.cookie(ASP.NET_SessionId)
      stick match req.cookie(ASP.NET_SessionId)
      [...]
      server s1 10.0.0.1:80 check 
      server s2 10.0.0.2:80 check
    

Note: you should use a peers section to keep the data synchronized between 2 HAProxys and when reloading the configuration Note2: the expire parameter should match your application cookie timeout

Last but not least, HAProxy will report you flags about cookie based persistence (understand the one with the cookie keyword) in your log lines. That way, you'll know the status of the request (was there a cookie, was it valid, etc...) and the action taken by HAProxy (insert a new cookie, etc...)

You can have a look at this blog page to get more information about HAProxy: http://blog.haproxy.com/2012/03/29/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/

Baptiste