Forum Discussion

bigipjr28_13978's avatar
bigipjr28_13978
Icon for Nimbostratus rankNimbostratus
Jan 28, 2015

Name Based Virtual Hosting irule efficiency

Hey guys,

 

we are currently going the route of name based virutual hosting with all of applications. After finding a terrific doc https://devcentral.f5.com/articles/name-based-virtual-hosting-with-ltm that pretty much explains what we need I have a few concerns on the best way to scale it. Here are my concerns:

 

  1. if have say we have 100 sites, I am guessing that the irule will not scale that well when HTTP_REQUEST { switch [HTTP::host] { iz.hotkittehs.com { pool hotkittehs } www.bukkitsgalor.org { pool bukkitsgalor } icanhaz.devcentral.f5.com { pool icanhaz } default { reject } } } } or will it ? is there another way to make it more scalable efficient? prehaps breaking it out into a couple of separate switch statement while maintaining the same piece of code..thoughts ?

Thanks

 

26 Replies

  • I have put in place the irule along with the custom health monitor for each application. We are testing out two applications and the two that applications that are using the monitor are working and directing traffic with and without the irule.

     

    Here is the setup:

     

    pool test1.pool nodes 10.1.1.1 10.1.1.2 monitor GET /f5-monitor/f5-monitor.jsp HTTP/1.1\r\nHost: test1.com\r\nConnection: Close\r\n\r\n

     

    pool test2.pool nodes 10.1.1.1 10.1.1.2 monitor GET /f5-monitor/f5-monitor.jsp HTTP/1.1\r\nHost: test2.com\r\nConnection: Close\r\n\r\n

     

    I am able to get to test1.com and test2 with and without the use of the irule or data groups. How's this happening since the nodes are using the same pair of apache servers that are serving up the host header information and properly being routed to each application?

     

    Thanks

     

  • I have put in place the irule along with the custom health monitor for each application. We are testing out two applications and the two that applications that are using the monitor are working and directing traffic with and without the irule.

     

    Here is the setup:

     

    pool test1.pool nodes 10.1.1.1 10.1.1.2 monitor GET /f5-monitor/f5-monitor.jsp HTTP/1.1\r\nHost: test1.com\r\nConnection: Close\r\n\r\n

     

    pool test2.pool nodes 10.1.1.1 10.1.1.2 monitor GET /f5-monitor/f5-monitor.jsp HTTP/1.1\r\nHost: test2.com\r\nConnection: Close\r\n\r\n

     

    I am able to get to test1.com and test2 with and without the use of the irule or data groups. How's this happening since the nodes are using the same pair of apache servers that are serving up the host header information and properly being routed to each application?

     

    Thanks

     

    • bigipjr28_13978's avatar
      bigipjr28_13978
      Icon for Nimbostratus rankNimbostratus
      A concern of is, how would this function from gtm prospective if we use a global configuration for our vips? So our setup is basically. GTM -> LTM ->POOL MEMBERS (webserver1, webserver2). If we only have to pool members and using hostheaders for all the applications and we wanted to failover between sites 1 and site 2 and since we use global config mode to manipulate that, wouldn't that fail all the applications over ?
  • irule is editor has helped alot I download it a a coulple of months ago..would awesome if there it came bundled with the devices so that all you have to do is just click a download link and than install it locally to your machine. Instead of going to the dev central directly.

     

    • StephanManthey's avatar
      StephanManthey
      Icon for MVP rankMVP
      That´s just a trick to get folks messing around on DC and to see all the great stuff ... ;)
  • if I was going to use a list that would just match against host headers would I just use a class ? is that something I do in the irule itself or done in tmos ? confused when it comes to some of the examples

     

    Thanks

     

    • Michael_Jenkins's avatar
      Michael_Jenkins
      Icon for Cirrostratus rankCirrostratus
      You would create the data group from the CLI (per @shaggy example), or through the F5 management GUI. Then you would utilize the data group within an iRule. If you want easy to manage iRule and Data Group management, I'd highly recommend downloading the iRule Editor (https://devcentral.f5.com/s/articles/iRule-Editor-Download). It makes it so much easier.
    • shaggy's avatar
      shaggy
      Icon for Nimbostratus rankNimbostratus
      it is configured separately from the iRule. in the configuration utility, navigate to Local Traffic | iRules | Data Group List
  • @michael j has it right - data groups are probably best for dealing with matching against a large list of items or matching against a list that changes often. A few of the biggest advantages to using data groups over "if/then" or "switch" logic are readability and you should rarely have to touch the iRule itself. Adding a new hostname/pool-name pair just requires adding an entry to a data-group.

    If you want to base the pool selection on the requested HTTP host header, you can try something like:

    A data group with string entries of name: HTTP hostname and value: pool-name

    ltm data-group internal test-dg {
        records {
            abc.com {
                data abc_pool
            }
            def.com {
                data def_pool
            }
        }
        type string
    }
    

    The associated iRule:

    when HTTP_REQUEST {
     test-dg is a string data-group where the entries are name:value pairs
     name is the requested HTTP host header, value is the associated pool-name
    
         check the requested HTTP host header against entries in data-group test-dg
        if { [class match [string tolower [HTTP::host]] equals test-dg ] } {
             if the HTTP host header is in test-dg
             send the request to the pool associated with the test-dg entry
            pool [class match -value [string tolower [HTTP::host]] equals test-dg ]
        } else {
             drop the request if the host header is not in test-dg
            drop
    }
    }
    
    • shaggy_121467's avatar
      shaggy_121467
      Icon for Cumulonimbus rankCumulonimbus
      Without oneconnect, the iRule will only make a decision for the first HTTP request sent across a user's TCP connection to the VS. If the user sends multiple HTTP requests using that connection, all subsequent requests across that TCP connection will follow the iRule decision based on the initial HTTP request. From the sol article referenced below - "When a OneConnect profile is enabled for an HTTP virtual server, and an HTTP client sends multiple requests within a single connection, the BIG-IP system is able to process each HTTP request individually." SOL7208: Overview of the OneConnect profile skip to "Content Switching" https://support.f5.com/kb/en-us/solutions/public/7000/200/sol7208.html
    • shaggy_121467's avatar
      shaggy_121467
      Icon for Cumulonimbus rankCumulonimbus
      i didn't have a chance to test it thoroughly, but that's the idea. i added comments to help clarify the commands. in order to use the iRule properly, the associated virtual server(s) will need a oneconnect profile.
  • shaggy's avatar
    shaggy
    Icon for Nimbostratus rankNimbostratus

    @michael j has it right - data groups are probably best for dealing with matching against a large list of items or matching against a list that changes often. A few of the biggest advantages to using data groups over "if/then" or "switch" logic are readability and you should rarely have to touch the iRule itself. Adding a new hostname/pool-name pair just requires adding an entry to a data-group.

    If you want to base the pool selection on the requested HTTP host header, you can try something like:

    A data group with string entries of name: HTTP hostname and value: pool-name

    ltm data-group internal test-dg {
        records {
            abc.com {
                data abc_pool
            }
            def.com {
                data def_pool
            }
        }
        type string
    }
    

    The associated iRule:

    when HTTP_REQUEST {
     test-dg is a string data-group where the entries are name:value pairs
     name is the requested HTTP host header, value is the associated pool-name
    
         check the requested HTTP host header against entries in data-group test-dg
        if { [class match [string tolower [HTTP::host]] equals test-dg ] } {
             if the HTTP host header is in test-dg
             send the request to the pool associated with the test-dg entry
            pool [class match -value [string tolower [HTTP::host]] equals test-dg ]
        } else {
             drop the request if the host header is not in test-dg
            drop
    }
    }
    
    • shaggy's avatar
      shaggy
      Icon for Nimbostratus rankNimbostratus
      Without oneconnect, the iRule will only make a decision for the first HTTP request sent across a user's TCP connection to the VS. If the user sends multiple HTTP requests using that connection, all subsequent requests across that TCP connection will follow the iRule decision based on the initial HTTP request. From the sol article referenced below - "When a OneConnect profile is enabled for an HTTP virtual server, and an HTTP client sends multiple requests within a single connection, the BIG-IP system is able to process each HTTP request individually." SOL7208: Overview of the OneConnect profile skip to "Content Switching" https://support.f5.com/kb/en-us/solutions/public/7000/200/sol7208.html
    • shaggy's avatar
      shaggy
      Icon for Nimbostratus rankNimbostratus
      i didn't have a chance to test it thoroughly, but that's the idea. i added comments to help clarify the commands. in order to use the iRule properly, the associated virtual server(s) will need a oneconnect profile.
  • Thanks for the great response. For me at least if the backend web servers are going to be using the same set apache ips I would have to create new pools containing the same set of ips, a seperate monitor, than add the pool to the irule that I pasted.

     

    • Michael_Jenkins's avatar
      Michael_Jenkins
      Icon for Cirrostratus rankCirrostratus
      True. To be thorough, you'd want to have separate pools with distinct monitors per application. If your requirements were more generic (i.e. you only care if the web server is up. you're not focused on specific web sites), you could have a single poo with a basic monitor checking just the root web site on the servers. If you need more specific checking (e.g. check that a login page comes up), you would need to have the different ones. The other option is to assign multiple monitors to a single pool, but the problem there comes because the monitors would be logically ANDed rather that ORed (so they both have to be up to be valid)
  • From my experience (as we do something similar in my organization), we've used data groups to handle all this (and parse the values to get information we need).

    Regarding how to interact with data groups, this wiki page gives links to the class, findclass and matchclass functions, which should help guide you in the right direction.

    For us, we sometimes use a format like

    name1:value1|name2:value2|...
    as the data group value (with a hostname or uri prefix as the name on the data group record). From there we parse out the parameters we need. So for example

    • DG Record Name:
      example.com
    • DG Record Value:
      pool:my_pool|host:www.mynewhost.com

    So in our iRule, we would check for

    example.com
    in the data group

    set host [string tolower [HTTP::uri]]
    if { [class match $host equals DATA_GROUP_NAME] } {
        set param [class match -value $host equals DATA_GROUP_NAME]
         Add some checking for data integrity if necesary
    
        set params [split $param "|"]
        set pool [getfield [lsearch -inline -glob $params "pool:*"] ":" 2]
        set host [getfield [lsearch -inline -glob $params "host:*"] ":" 2]
    
         Set the pool
        pool $pool
         Change the host
        HTTP::host $host
    }
    

    It's a simple example, and depending on the amount of traffic, may not be the most efficient way of doing it, but I've found it's the simplest, as we just add a record to the data group and don't have to touch the iRule.

    Hope this helps.