Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

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.

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

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

0
Comments on this Answer
Comment made 19-Aug-2016 by Kram 2

I modified the http_request in the irule to client_accepted - since the VS doesn't use any http profile. i'm getting an error : TCL error: - invalid command name "pool_a" while executing "$static::primary_pool"

Also, would you be able to brief on what exactly does the irule do?

0
Comment made 19-Aug-2016 by Kai Wilke 6942

Hi Kram,

I duno why your script tries to execute $static::primary_pool. I guess you've tried to fix my provided code (it have had two missing $ signs in the [pool] related lines) and somehow broke the code. However...

I've updated the provided code example to include comments and did a quick rearanged the logic to make it easier to understand...

Cheers, Kai

0
Comment made 19-Aug-2016 by Kram 2

Hi Kai,

Thank you very very much! - it worked like a charm! Appreciate your help!

0
Comment made 19-Aug-2016 by Kram 2

Hi Kai,

Just wanted to clarify - the below line: table add "status_$static::primary_pool" "backup" indefinite indefinite

When "indefinite" is added - the connection will remain in the memory indefinitely or until the failback is triggered? i just wanted to understand if this might cause any memory leak.

0
Comment made 19-Aug-2016 by Kai Wilke 6942

Hi Kram,

You're welcome.

And dont worry about memory leaks. Its only the "backup" text-string to that is getting stored in the session table. So just a few bytes wasted... :-)

Cheers, Kai

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

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 </html>"   
     } else { 
        pool backup
0
Comments on this Answer
Comment made 18-Aug-2016 by Kram 2

Hi,

Sorry i missed to mention the failover condition. The failover should be triggered when 3 servers are failed in primary pool. The failback to be triggered when all 4 servers are available in the primary pool.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

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
    }
}
0
Comments on this Answer
Comment made 02-Sep-2016 by BinaryCanary

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.

0
Comment made 02-Sep-2016 by Kai Wilke 6942

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

0
Comment made 02-Sep-2016 by BinaryCanary

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;

...

0
Comment made 02-Sep-2016 by Kai Wilke 6942

Hi F5Knuckles,

I didn't recognized your answer as a critique towards my irule. I was just interested in a technical discussion, to explain the pros and cons of the different coding styles... :-)

Cheers, Kai

1
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

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

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

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 }

0