Forum Discussion
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:
- 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
- Michael_JenkinsCirrostratus
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
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 examplename1:value1|name2:value2|...
- DG Record Name:
example.com
- DG Record Value:
pool:my_pool|host:www.mynewhost.com
So in our iRule, we would check for
in the data groupexample.com
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.
- DG Record Name:
- bigipjr28_13978Nimbostratus
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_JenkinsCirrostratusTrue. 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)
- shaggy_121467Cumulonimbus
@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 } }
- bigipjr28_13978NimbostratusMaking sure I understand correctly as to what the code does. What its doing, upon a request checks the header comparing to the data group list where the pool(s) are going to refrerenced than goes to that pool..if anything else drop the connection
- bigipjr28_13978NimbostratusMaking sure I understand correctly as to what the code does. What its doing, upon a request checks the header comparing to the data group list where the pool(s) are going to refrerenced than goes to that pool..if anything else drop the connection
- bigipjr28_13978Nimbostratussorry about the dupliate comment must have submitted it twice. Thanks
- shaggyNimbostratus
@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 } }
- bigipjr28_13978NimbostratusMaking sure I understand correctly as to what the code does. What its doing, upon a request checks the header comparing to the data group list where the pool(s) are going to refrerenced than goes to that pool..if anything else drop the connection
- bigipjr28_13978NimbostratusMaking sure I understand correctly as to what the code does. What its doing, upon a request checks the header comparing to the data group list where the pool(s) are going to refrerenced than goes to that pool..if anything else drop the connection
- bigipjr28_13978Nimbostratussorry about the dupliate comment must have submitted it twice. Thanks
- bigipjr28_13978Nimbostratus
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
- shaggyNimbostratusit is configured separately from the iRule. in the configuration utility, navigate to Local Traffic | iRules | Data Group List
- Michael_JenkinsCirrostratusYou 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.
- bigipjr28_13978Nimbostratus
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.
- That´s just a trick to get folks messing around on DC and to see all the great stuff ... ;)
- bigipjr28_13978Nimbostratus
all great stuff guys, thanks for the input and help again!
- bigipjr28_13978NimbostratusA 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 ?
- bigipjr28_13978Nimbostratus
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_13978Nimbostratus
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
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com