For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

heskez_36146's avatar
heskez_36146
Icon for Nimbostratus rankNimbostratus
Sep 30, 2015

Show maintenance page when everything is down

Hi There,

 

I've got the following challenge. We've two web servers put in a pool and is reachable by a VIP. When one of the two servers is down, it isn't a problem. When maintenance is needed we can produce a maintenance page by an irule. When both servers are down, the VIP is also down and therefore not possible to have a redirect irule to produce or the same maintenance page or an error page. What possibilities are there to produce such page when all servers are down?

 

Regards, Erik

 

7 Replies

  • Hi Erik,

    The VIP shouldn't go down at all. The VIP should stay up, so you would need an iRule to query the number of pool members that are up and if they are less than 1, carry out a HTTP::redirec to a specific webpage (i recommend an externally hosted page for obvious reasons).

     

       if { [active_members poolname] < 1 } {
            log local0. "No pool member a available in poolname"   
                HTTP::respond 302 noserver Location "http://www.somewebsite.com"
        return
    }
    

     

    Hopefully this helps.

    Cheers,

    Thomas.

  • Salim_83682's avatar
    Salim_83682
    Historic F5 Account

    Hi,

     

    You can use the Fallback Host feature within the HTTP profile assigned to your VS to redirect users elsewhere when your VS goes offline.

     

    Salim

     

  • Thank you for both your answers. I've done a quick test with the fallback host option, because it was de quickest and easiest way. Both members were offline and the vs went also offline, but the fallback host option redirect us to the configured error page somewhere on the web, fantastic! Fast and easy!

     

  • I was just working on this same problem. I came across a few sections in the DevCentral Codeshare:

    Both had great tips. I ended up combining them, though, because I want to return a 503 instead of 200. The code I'm using now runs at the end of my iRules (priority 1000). Between my first HTTP_REQUEST block and that final one, I do bits of processing that may change the pool. So by the time I get to my error handling at the end, I want to make sure I'm only doing this for pages that would be sent to the default pool. I certainly don't want this happening for every image and style sheet request that comes through! I think I need to constrain this even more, though. One of the Codeshare examples filtered on GET requests; that's probably wise.

     

     

     do initial HTTP request processing
    when HTTP_REQUEST priority 100 {
        set DEBUG 1
    
        set uri [HTTP::uri]
    
         Derive a default pool name from our virtual server name
         WARNING: This assumes our VS and pool use the same name.
        set virtual_name [virtual name]
    
        set default_pool [getfield $virtual_name "/" 3]
        ...
    }
    
    when HTTP_REQUEST priority 1000 {
        set log_label "(VS $virtual_name) final"
        set final_pool [getfield [LB::server pool] "/" 3]
    
         If our selected pool is down, show a maintenance page and trigger a retry in $retry_interval seconds
        if { $final_pool eq $default_pool && [active_members $final_pool] < 1 } {
    
             sets the timer to return client to host URL
            set retry_interval 30
            log local0. "$log_label: --> pool $final_pool down; retrying in $retry_interval seconds"
    
             Use the Host header value for the responses if it's set.  If not, use the VIP address.
            if {[string length [HTTP::host]]}{
                set retry_host [HTTP::host]
            } else {
                set retry_host [IP::local_addr]
            }
    
            set retry_uri [HTTP::uri]
            set iframe_src {https://MY_MAINTENANCE_LINK}
            set respond_content "Maintenance\n\nRetrying your request in $retry_interval seconds\n"
    
            HTTP::respond 503 content $respond_content {Content-Type} {text/html}
            return
        }
    }
    

     

    I have a bit of CSS in there, but the gist of the response is that it's sending back a 503 code, then following up with some short HTML to show a "retrying in $retry_interval seconds" message. Just below that, it includes an iframe that loads a maintenance page (see MY_MAINTENANCE_LINK above). I don't know if that's good or bad behavior for a 503 page, but it will let our web development team own the content of the maintenance page and let me handle how it's used.

     

  • I can't seem to edit my previous answer, but there's a duplicate set of closing

    tags in there. Here's a corrected version that's also a bit more readable in the short texture that the LTM web UI provides:

            set respond_content "
    
      Maintenance
      
    
    
      
        Retrying your request in $retry_interval seconds
        
      
      
      
    
    \n"
    
  • Robert_Teller_7's avatar
    Robert_Teller_7
    Historic F5 Account

    If you want to keep things simple i would use the Fallback attributes within the HTTP Profile. When all nodes are down the status code of 500 will be returned to the client, this will trigger the 302 redirect to the specified value in the fallback-host field

     

    ltm profile http HTTP_v2 {
        app-service none
        defaults-from http
        fallback-host http://redirect.com/ladningpage
        fallback-status-codes { 500 }
    }
  • Stupid question, but how is this going to work if all LTM pool members are down, which means the VS will go down, and then the DNS delegation answer provided by GTM goes down. Users trying to hit the DNS URL name are SOL. They will never get directed to the LTM hosting the maintenance page.

     

    My use case: LTM pool>> LTM VS>> iQuery>> GTM hosting WideIP

     

    Am I missing something simple here?