Load Balance 4 URI over 2 IPs and rewrite http response location
I have been struggling with this and I hope someone can assist.
The challenge is twofold:
1. Need Virtual Server to load balance between 4 URIs which are spread over 2 Nodes.
2. When the webservers respond, they respond with a location which points to itself instead of the FQDN the client specified
I have tried solving with numerous variations of below iRules, but fail when the client receives the Nodes http://hostname:portnumber/URi/web2.exe (which isn't reachable from client network).
@1: Irule to load balance between 4 URIs:
Virtual Server name: vs_example.com
IP: 172.16.0.1
b. Pools:
pool_example1-uri-1_81
- node_01_10.0.0.1:81
pool_example1-uri-2_81
- node_01_10.0.0.1:81
pool_example2-uri-3_81
- node_02_10.0.0.2:81
pool_example2-uri-4_81
- node_02_10.0.0.2:81
c. iRule:
when HTTP_REQUEST {
# Check if the requested URI is either / or /CAisd/pdmweb.exe
if { [HTTP::uri] eq "/" or [HTTP::uri] eq "/CAisd/pdmweb.exe" } {
# Define the possible URIs and corresponding pools
set uri_pool_map {
/URi/web1.exe pool_example1-uri-1_80
/URi/web2.exe pool_example1-uri-2_80
/URi/web3.exe pool_example1-uri-3_80
/URi/web4.exe pool_example1-uri-4_80
}
# Initialize a list of available pools
set available_uri_pool_list {}
# Check the availability of each pool and add to the list if available
for {set i 0} {$i < [llength $uri_pool_map]} {incr i 2} {
set pool_name [lindex $uri_pool_map [expr {$i + 1}]]
if {[active_members $pool_name] > 0} {
lappend available_uri_pool_list [lindex $uri_pool_map $i] $pool_name
} else {
log local0. "Pool $pool_name is not available"
}
}
# If no pools are available, send an error response
if {[llength $available_uri_pool_list] == 0} {
HTTP::respond 503 content "Service Unavailable - No available pools"
return
}
# Select the next URI and corresponding pool in a round-robin fashion from available pools
set index [expr {[clock clicks -milliseconds] % ([llength $available_uri_pool_list] / 2)}]
set next_uri [lindex $available_uri_pool_list [expr {$index * 2}]]
set next_pool [lindex $available_uri_pool_list [expr {$index * 2 + 1}]]
# Log the selected URI and pool for troubleshooting
log local0. "Selected URI: $next_uri, Pool: $next_pool"
# Replace the URI with the selected one
HTTP::uri $next_uri
# Select the corresponding pool
pool $next_pool
}
}
@2. iRule to replace location in HTTP Response
when HTTP_RESPONSE_RELEASE {
if { [HTTP::header exists "Location"] } {
set location [HTTP::header "Location"]
log local0. "Original Location header: $location"
# Modify the Location header if it contains the internal server reference
if { $location starts_with "http://webserver1" || $location starts_with "http://webserver2" } {
set new_location [string map {
"http://webserver1:81" "https://172.16.0.1"
"https://webserver1:81" "https://172.16.0.1"
"http://webserver2:81" "https://172.16.0.1"
"https://webserver2:81" "https://172.16.0.1"
} $location]
HTTP::header replace "Location" $new_location
log local0. "Modified Location header: $new_location"
}
}
}