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
- mtaylornzNimbostratusHey 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