Marek Skrobacki

Two tier loadbalancing on the F5 BigIP

Goal

I would like to have VIP which will be able to use two different loadbalancing algorithms simultaneously. This may sound weird for you, so here’s explanation. Long story short - let’s assume that VIP has servers A,B,C configured in the pool. The requirement is to distribute the load in following way: - requests distributed between servers A,B,C using predictive/least conn method - the requests for server B should hit the server on two different ports - 80% of the traffic on port 3306 and 20% on port 4040. Obviously the best method to use here would be “ratio member”.

The problem is that you can not do it directly on the VIP level.

Solution

The solution is to create two separate pools for this VIP and every time F5 selects server B on the level 1, iRule performs another iteration of load balancing algorithm using the other pool (named level2 pool). If the lb method on both (level 1 and 2) pools was round-robin, the decision flow will be:

On the pool level, the decision flow will be:

Source code

when CLIENT_ACCEPTED {
  # Save the name of the VIP's default pool
  set default_pool [LB::server pool]
  # number of lb failures are held in the variable in order to prevent loop
  set lb_fails 0
  set lb2_fails 0   
}
when LB_SELECTED {
  # if the selected member is DB103
  if { [IP::addr [LB::server addr] equals 172.16.172.138] } {
    # check if the number of failures of level2 pool selection
    # is lower than number of active members in it.
    # If yes then force F5 to make a decision which member from
    # level2 pool to use (using configured lb method).
    # If NOT, select another member from default level 1 pool.
    if { $lb2_fails < [active_members lbrepl-level2-db103] } {
        LB::reselect pool lbrepl-level2-db103
        #log local0.info "reselected   [LB::server]"
        incr lb2_fails
    } else {
        if { $lb_fails < [active_members $default_pool] } {
            LB::reselect $default_pool
            log local0. "No members available in level 2 pool. Will try to select another member from pool 1 level"
            incr lb_fails
        } else {
            # if there are no more members available in either pools, then close a connection.
            log local0. "No members available in Level 1 pool. Closing connection."
            TCP::close
        }
    }
  }  
}

Example usage

pool lbrepl-level2-db103 {
   lb method ratio
   members
      172.16.173.41:mysql
         ratio 8
         monitor snmp_monitor_lbrepl_DB103_3306
      172.16.173.41:4040
         ratio 2
         monitor snmp_monitor_lbrepl_DB103_4040
}
pool lbrepl-replica {
   lb method predictive
   monitor all snmp_monitor_lbrepl
   members
      172.16.172.98:mysql
      172.16.172.138:33333
         monitor tcp
      172.16.172.140:mysql
      172.16.172.141:mysql
         down
         session disable
      172.16.172.154:mysql
      172.16.172.204:mysql
      172.16.172.221:mysql
      172.16.173.40:mysql
      172.16.173.42:mysql
      172.16.173.43:mysql
      172.16.173.44:mysql
      172.16.173.141:mysql
      172.16.173.142:mysql
      172.16.173.143:mysql
}
virtual lbrepl-replica {
   snat automap
   pool lbrepl-replica
   destination 172.16.172.110:mysql
   ip protocol tcp
   vlans database enable
   rules lbreplica-twolevel
}
Bigip