iRule cookie persistence and pool redirect
Hi all, base on the on below setup...
- When Pool A/NodeA1 goes down, we expect URI /beta/ requests to be sent to Pool B, as nodeA2 can't accept URI /beta/ requests.
- However, when Pool A/NodeA1 goes down, we see the LTM sending URI /beta/ requests to Pool A/nodeA2.
- F5 support said cookies have precedence over iRule and the cookie will try to honor it's persistence, hence why traffic is still being sent to Pool A / nodeA2(A1 is down at that point).
Strangely in lab I have a different behavior from the LTM. Whether it's an new or a subsequent request, the source_addr persistence record will show the connection for 3mins(default timeout value). During that time pressing F5 and CTRL-F5 will force the client's browser to reinitiate the communication. When I reinitiate, despite having received a cookie, previously, for Pool A / nodeA1 -- I also get a new cookie for Pool B / node B1 and connect to node B1 successfully. That behavior is what I'm expecting in production, but that's not the case.
Should I be adding more to the iRule, in order to maninpulate the cookies, or any suggestions of what can be at cause?
SETUP
LTM contains:
- cookie persistence with fallback source_addr
- Pool A with member nodeA1(priority 15 ) & nodeA2(priority 5); with min-active 1
- Pool B with member NodeB1 only
nodeA1 = 10.10.10.1
nodeA2 = 10.10.10.2
nodeB1 = 10.20.20.21
And an iRule that should mainly redirect like this:
if { PoolA/nodeA1 is down + URI equal "/beta/"} {
then send it to Pool B
}
else { send it to Pool A }
Here is the iRule:
when HTTP_REQUEST {
set sslex 0
if { ([string tolower [HTTP::uri]] starts_with "/beta/") && ([LB::status pool Alpha-Pool member 10.10.10.1 443] eq "down") } {
set sslex 1
set sni_value "betaServer.lab.com"
HTTP::header replace Host "betaServer.lab.com"
set uri [string map -nocase {"/beta /" "/"} [HTTP::uri]]
HTTP::uri $uri
pool Beta-Pool
} else {
set sslex 0
set sni_value "lab.com"
pool Alpha-Pool
} }
when SERVERSSL_CLIENTHELLO_SEND {
# SNI extension record as defined in RFC 3546/3.1
# https://support.f5.com/csp/article/K41600007
if { $sslex > 0 } {
SSL::extensions insert [binary format SSScSa* 0 [expr { [set sni_length [string length $sni_value]] + 5 }] [expr { $sni_length + 3 }] 0 $sni_length $sni_value]
}
}
Tests were done in the production LTM instead, by creating a temporary VIP with same pool members. A few users were able to test via the temporary VIP, and everything was working as expected. Yet, it wasn't working on the production VIP.
I end-up creating a PoolC containing nodeA1 ONLY for /beta/ URI ONLY. That way /beta/ URI would never reach nodeA2 when nodeA1 is down.
If PoolC/nodeA1 is UP, then PoolC will be used. Otherwise, it will hit the 2nd condition, redirecting /beta/ to PoolB. Problem solved.