Forum Discussion

Kram_259300's avatar
Kram_259300
Icon for Nimbostratus rankNimbostratus
Aug 18, 2016

Pool member failback

I have a requirement to select pool member based on the availability.

 

Primary pool has 4 servers & backup pool has 2 servers. I know failover can be triggered based on the prioriy group or writing an iRULE to verify the availablility using [LB::server pool]. But there is a catch on the failback from backup to primary pool should be triggered when all the 4 servers are active on the primary. Do you guys have any idea how this can be done?

 

Failover when 3 server fails in primary pool and failback when all severs are available in primary pool.

 

9 Replies

  • so the only way you can achieve this is via irule. You virtual server will use an irule to determine which pool to use. So your irule will need a line like this to determine when to use the Primary pool or backup pool.

     

      if { [active_members [LB::server pool] ] = 4 } { 
           pool  primary "   
         } else { 
            pool backup
    

     

  • Hi Kram,

    you may use the iRule below as a starting point. The iRule uses the table command to switch between a primary/backup mode to be able to apply different rule sets...

     

    when RULE_INIT {
        set static::primary_pool "pool_a"
        set static::backup_pool "pool_b"
    }
    when CLIENT_ACCEPTED {
         Check session table if backup mode is currently active
        if { [table lookup "status_$static::primary_pool"] eq "backup" } then {
             Backup mode is currently active. Applying Backup mode availability requirements. Check if primary pool has equal or more than 4 members.
            if { [active_members "$static::primary_pool"] >= 4] } then {
                  Primary pool has equal or more than 4 members. Switching back to primary pool and disable Backup mode.
                table delete "status_$static::primary_pool"
                pool "$static::primary_pool"
            } else {
                  Primary pool has less than 4 members. Using backup pool and keeping Backup mode active...
                pool "$static::backup_pool"
            }
             Exit the script...
            return
        }
         Backup mode is currently not active (default). Applying normal availability requirements. Check if primary pool has more than 1 members.
        if { [active_members "$static::primary_pool"] > 1] } then {
              Primary pool more than 1 member. Using primary pool and keeping Backup mode disabled...
            pool "$static::primary_pool"
        } else {
              Primary pool less than 2 available member. Using the backup pool and enable Backup mode in session table...
            table add "status_$static::primary_pool" "backup" indefinite indefinite 
            pool "$static::backup_pool"
        }   
    }
    

     

    Update: Changed the order of the script to make it easier to understand. Added additional comments, to explain what the purpose of each line is...

    Cheers, Kai

  • BinaryCanary_19's avatar
    BinaryCanary_19
    Historic F5 Account

    Hi guys,

    the following irule logic inspired by some of the comments above, seems a bit neater and should do the trick. You will need to adjust the pool names and pool member counts as required, and you can of course perform more complex calculations if you prefer.

    I did some basic testing, but i can't promise i caught all potential errors, so make sure to give it a whirl in a test environment first.

     

    when RULE_INIT {
        set static::pp "webpool" 
        set static::bp "backupwebpool" 
        set static::flag "flag"
    }
    
    when CLIENT_ACCEPTED {
        if { [table lookup $static::flag] eq "backup" && [active_members $static::pp] < 1 } {
            we're in backup mode 
            log local0. "backup mode"
            pool $static::bp
    
        }elseif { [active_members $static::pp] >= 1} {
           active mode
            log local0. "going back to active mode"
            table set $static::flag "active"
            pool $static::pp
    
        }else {
            backup mode needs to be enabled
            log local0. "enabling backup mode"
            table set $static::flag "backup"
            pool $static::bp
        }
    }
    

     

    • BinaryCanary_19's avatar
      BinaryCanary_19
      Historic F5 Account

      also, might be worth looking into priority group activation, a feature of pools that can do something similar to this without needing irules, and with probably better handling of cases like persistence than this irule.

       

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP

      Hi FKnuckles,

      I'm a big fan of the Priority Based Activation feature, but unfortunately you can't use this feature for the given requirement (different availability thresholds for failover and failback).

      Well, you're code uses just 3 instead of 4 different conditions and looks therefor indeed much cleaner. But on the other hand it does not cover the requirements of the OP and produces a slightly higher overhead. Let me try to compare the different iRules...

      Active Operation Scenario

      Your code:

       

      if [table lookup $static::flag] eq "backup"
      if [active_members $static::pp] >= 1
      table set $static::flag "active"
      pool $static::pp
      

       

      My Code:

       

      if [table lookup "status_$static::primary_pool"] eq "backup" 
      if [active_members "$static::primary_pool"] > 1]
      pool "$static::primary_pool"
      

       

      Performance Difference: Your code requires one additional table command execution.

      Functional Difference: None

      Active Operation Failover Scenario

      Your code:

       

      if [table lookup $static::flag] eq "backup"
      if [active_members $static::pp] >= 1
      table set $static::flag "backup"
      pool $static::bp
      

       

      My Code:

       

      if [table lookup "status_$static::primary_pool"] eq "backup" 
      if [active_members "$static::primary_pool"] > 1]
      table add "status_$static::primary_pool" "backup" indefinite indefinite 
      pool "$static::backup_pool"
      

       

      Performance Differences: None

      Functional Difference: None

      Backup Operation Scenario

      Your code:

       

      if [table lookup $static::flag] eq "backup"
      if [active_members $static::pp] < 1
      pool $static::bp
      

       

      My Code:

       

      if [table lookup "status_$static::primary_pool"] eq "backup" 
      if { [active_members "$static::primary_pool"] >= 4]
      pool "$static::backup_pool"
      

       

      Performance Differences: None

      Functional Difference: The OPs requirement is not covered. The requirement for triggering the failback is [active_members $static::pp] = 4 nodes.

      Backup Operation Failback Scenario

      Your code:

       

      if [table lookup $static::flag] eq "backup"
      if [active_members $static::pp] < 1
      if [active_members $static::pp] >= 1
      table set $static::flag "active"
      pool $static::pp
      

       

      My Code:

       

      if [table lookup "status_$static::primary_pool"] eq "backup" 
      if { [active_members "$static::primary_pool"] >= 4]
      table delete "status_$static::primary_pool"
      pool "$static::primary_pool"
      

       

      Performance Differences: Your code requires one additional [active_members $static::pp] command execution.

      Functional Difference: The OPs requirement is not covered.

      Cheers, Kai

    • BinaryCanary_19's avatar
      BinaryCanary_19
      Historic F5 Account

      Hi Kai,

      First off, Thanks for posting your original irule. I believe you solved the OP's question, which is much appreciated. This wasn't really a critique of your irule. The context in which I made this version was just expressly to improve readability for a different person who actually drew their inspiration from your solution. I did not attempt to tweak for performance in any way, and I posted this here just as a way of sharing an alternative version since the work was already done.

      I also didn't attempt to use the OP's numbers, understanding being that the user will place the numbers they desire.

      Talking of performance, strictly speaking, the "table set $static::flag active" is completely unnecessary in my version, as the "active" value is never really used. That's one quick optimisation that I spotted.

      Going further, the table set is probably totally unnecessary in fact, considering that the fallback to active pool always happens whenever the active pool is healthy. My version looks like this because I basically just took yours and tried to improve readability. I didn't approach OP's question from clean slate. It is possible that a simple solution could be devised where you simply need an

       

      if [primary pool available members less than 4] then 
          backup; 
      Else: 
          primary;
      

       

  • Hello

     

    I used the script/irule that Kai posted and works great (thank you Kai). But I notice if the connection/session is permanent, the irule doesn't work. I think I should use "reject" command, but I have no luck with write the right irule. Thank you in advance for any help.

     

    Peter

     

  • Hi

     

    I know it's old thread and the job is done but i wish to know if my method is possible. :D

     

    Is it possible to create 2 pool (Primary pool have 4 member, Backup pool have 6 member)

     

    then assign Primary pool as Default pool and write irule like this

     

    if [active_member Primary_pool < 4 ] { pool Backup_pool }