Forum Discussion
Linking Pool Selection between VIPs
You would need at least THREE things to make this possible:
-
A mapping rule - because there's no inherent relationship between the nodes in VIP 1 and the nodes in VIP 2, you need to establish some form of mapping (ie. VIP1-node1 = VIP2-node1). There's probably a few ways to do that, but I chose a simple string-based data group. Example:
10.70.0.1 := 10.70.0.4
10.70.0.3 := 10.70.0.5
where the value on the left is the local (app server) node, and the value on the right is the corresponding remote (license server) node.
-
A persistence mechanism - again, these are two separate VIPs/FQDNs for a web browser, and consequently separate connections/sessions. You therefore need a way to transmit persistence information (the app VIP's chosen node) to the remote (license server) VIP. If the users are local, this could probably be done with source address and a table entry, but for remote users your best bet is probably a cookie. Now the built-in cookie persistence profile doesn't have a domain attribute, so I had to create my own.
-
An iRule - this is COMPLETELY untested in a production environment, and I hard-coded the port numbers, but hopefully you'll see where I'm going. So there's TWO iRules:
iRule applied to the app server VIP:
when RULE_INIT {
set static::LICENSE_POOL "local-pool-other"
set static::LICENSE_MAP "license-server-mapping-dg"
}
when CLIENT_ACCEPTED {
set default_pool [LB::server pool]
}
when HTTP_REQUEST {
set this_domain [domain [HTTP::host] 2]
if { [HTTP::cookie exists "BIGipServerPersist"] } {
set persist_member "pool $default_pool member [b64decode [URI::decode [HTTP::cookie value "BIGipServerPersist"]]] 80"
eval $persist_member
}
}
when LB_SELECTED {
if the chosen server node is in the data group
if { [class match [LB::server addr] equals license-server-mapping-dg] } {
if the matching license server node is down
if { not ( [LB::status pool $static::LICENSE_POOL member [class match -value [LB::server addr] equals $static::LICENSE_MAP] 80] eq "up" ) } {
matching license server node is down - reselct a new local node and try again
LB::reselect
} else {
set persistval [URI::encode [b64encode [LB::server addr]]]
}
}
}
when HTTP_RESPONSE {
if { [info exists persistval] } {
HTTP::cookie insert name BIGipServerPersist value $persistval domain $this_domain
}
}
iRule applied to the license server VIP:
when RULE_INIT {
set static::LICENSE_MAP "license-server-mapping-dg"
}
when CLIENT_ACCEPTED {
set default_pool [LB::server pool]
}
when HTTP_REQUEST {
if { [HTTP::cookie exists "BIGipServerPersist"] } {
set persist_member "pool $default_pool member [class match -value [b64decode [URI::decode [HTTP::cookie value "BIGipServerPersist"]]] equals $static::LICENSE_MAP] 80"
eval $persist_member
}
}
The idea in the first iRule is that when the load balancing decision happens, it'll check the corresponding member in the license server pool. If that member is down, then it'll make a new local load balancing decision. Note that the LB_SELECTED event will fire, at most, only three times. After finding a good local node that matches a good remote node, I'll set a persistence cookie (with domain scope) in the HTTP response. Here I've just base64-encoded the IP address, but you can do whatever you want to obfuscate/encrypt the value. In each subsequent HTTP request I read this cookie and persist to the specified local node. You'll also need to change the static variables in RULE_INIT to match your license server pool name and the data group name.
In the second iRule I simply read the domain-scoped cookie and persist to the node specified in the data group lookup.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com