FQDN pool members, Least Connections Member SLB with Cookie Persistence in an iCall
Problem this snippet solves:
A lightweight SLB solution without LTM
Code :
sys icall script matt_dns {
app-service none
definition {
#
# Get the DNS records from the server and place them in a sorted list
set dns_raw [exec bash -c {dig +short matt.f5demo.com @10.128.20.252 A}]
#set dns_raw "10.128.20.51\n10.128.20.52\n10.128.20.53\n10.128.20.54"
set dns [split $dns_raw "\n"]
set dns_sorted [lsort $dns]
# Read the prevous DNS result from file, sorted to ensure formating etc
if { [catch { set dns_previous_file [open "/config/ifile/current_icall_dns" r] } err] } {
set dns_old ""
} else {
set dns_old [read $dns_previous_file]
close $dns_previous_file
set dns_sorted_old [lsort $dns_old]
}
# Writing the current DNS to a file
set dns_previous_file [open "/config/ifile/current_icall_dns" w+]
puts $dns_previous_file $dns_raw
close $dns_previous_file
set count 0
foreach a $dns_sorted {
set pn "pool_$a"
if { [catch { tmsh::show /ltm pool $pn } err] } {
# Create Pools if they don't exist
tmsh::log "Creating new pool for $a"
tmsh::create /ltm pool $pn \{ members add \{ $a:80 \}\}
} else {
# Enable the Pool member if it does exist (quicker to just enable it than to check if it is disabled)
tmsh::modify /ltm pool $pn \{ members modify \{ all \{ session user-enabled \} \} \}
}
lappend pn_list $pn
incr count
}
# Disable Pools no longer in use
foreach b $dns_sorted_old {
if {[lsearch -exact $dns_sorted $b]==-1} {
tmsh::log "not in current dns list, disabling $b"
set old_pn "pool_$b"
tmsh::modify /ltm pool $old_pn \{ members modify \{ $b:http \{ session user-disabled \} \} \}
# Not too keen to just staight delete these, my thoughts are to have another iCall running every say 20min looking for user-disabled pools (or could use something a particular monitor) and confirming no active sessions and then deleting
#tmsh::delete /ltm pool $old_pn
}
}
# If just one pool create a persistence cookie but no SLB (need a persistence record for the case when another member is dynamically added)
if { $count eq 1 } {
set persist [lindex $pn_list 0]
set Ratio_SLB "set selected $persist"
} else {
# If more than one pool
# Work out Total Connections
set total 0
foreach a $pn_list {
foreach obj [tmsh::get_status /ltm pool $a detail] {
set cc [tmsh::get_field_value $obj cur-sessions]
#set cc [expr double( { 100 * rand() })]
set total [expr double( { $total + $cc })]
lappend cc_list $cc
}
}
# Work out cumulative ratios for each pool
set percentage 0
incr count -1
set j 0
foreach a $pn_list {
if { $total != 0.0 } {
set percentage [expr double( { $percentage + ( $total - [lindex $cc_list $j] ) / ( $total * $count ) } ) ]
} else {
set percentage [expr double( {$percentage + ( 1.0 / ( $count + 1.0 ) ) } ) ]
}
tmsh::log "$percentage $total $count [lindex $cc_list $j]"
# Construct the Dynamic Ratio SLB and persistence components of the iRule
# First Pool
if { $j eq 0 } {
set Ratio_SLB "set Random_num \[expr \{ rand() \}\]
if \{ \$Random_num < $percentage \} \{
set selected $a
\}"
set persist [concat $a " -" \n]
# Middle Pools, if there are any
} elseif { $j < $count } {
set Ratio_tmp " elseif \{ \$Random_num < $percentage \} \{
set selected $a
\}"
set Ratio_SLB [concat $Ratio_SLB $Ratio_tmp]
set persist [concat $persist $a " -" \n]
# Last Pool
} else {
set Ratio_tmp " else \{
set selected $a
\}"
set Ratio_SLB [concat $Ratio_SLB $Ratio_tmp]
set persist [concat $persist $a]
}
incr j
}
#tmsh::log "Test $Ratio_SLB"
#tmsh::log "$persist"
}
# Construct the whole iRule
set iRuleName "iCall_CookiePersist_RatioSLB"
set iRuleCode "
when HTTP_REQUEST timing on \{
switch \[HTTP::cookie pool_cookie\] \{
$persist \{
\#Persistence Record Exists
pool \[HTTP::cookie pool_cookie\]
set selected \"\"
\}
default \{
\#Load balancing decision required
$Ratio_SLB
pool \$selected
\}
\}
\}
when HTTP_RESPONSE timing on \{
if \{\$selected ne \"\"\} \{
\#set a persistence cookie
HTTP::cookie insert name pool_cookie value \$selected path \"/\"
\}
\}
"
# Create the iRule
# tmsh::log "$iRuleCode"
if { [catch { tmsh::modify ltm rule $iRuleName $iRuleCode } err] } {
tmsh::create ltm rule $iRuleName $iRuleCode
}
}
description none
events none
}Published Jun 22, 2016
Version 1.0mtaylornz
Nimbostratus
Joined July 24, 2011
mtaylornz
Nimbostratus
Joined July 24, 2011
1 Comment
- mtaylornz
Nimbostratus
Hey team I have a slight non functional issue with iCalls in general. Interested in advice. So we deploy our f5s in Sync Groups that we manually sync (I don;t think this is unusual). With iCalls running on each device we end up with Changes Pending status in Red all the time (both devices changed), which is really painful - not keen to move to Auto Sync, advise pls