Forum Discussion

rdessert_76127's avatar
rdessert_76127
Icon for Nimbostratus rankNimbostratus
Jul 27, 2012

Load balancing to a domain name vs a pool

My organization has a website that has some of its content local and some located at a cloud provider. I have an existing irule which forwards traffic to different pools based upon the URI's. I have a pool defined for our cloud provider containing a public IP address for a load balancer VIP.

 

 

My organization decided to change cloud providers and the new provider demands the use of a domain name vs an IP address for their resources, therefore I can no longer use a pool because pool members can only be an IP address.

 

 

I've found some stuff on devcentral regarding the NAME::lookup and RESOLV::lookup commands which leads me to believe this is the route I'll need to go down.

 

 

Does anyone have any reccomendations?

 

My existing irule is:

 

when HTTP_REQUEST {

 

if { [HTTP::host] equals "site.com" } {

 

HTTP::respond 301 Location "http://www.site.com[HTTP::uri]"

 

} else {

 

log local0.alert "BEGIN Host:[HTTP::host]-[HTTP::uri]-[HTTP::path]"

 

switch -glob [string tolower [HTTP::uri]] {

 

"/" -

 

"/*" -

 

"/foo/*" -

 

"/bar/*"

 

{

 

log local0.alert "cloud_pool Host:[HTTP::host]-[HTTP::uri]"

 

pool cloud_pool

 

return

 

}

 

default {

 

pool def_pool

 

}

 

}

 

}

 

 

 

Thanks for any help / feedback!

 

 

Rich

 

  • Also, I'm thinking I'll have to specify a port somehow to go along with the resolved IP address. All traffic is http...
  • The only way the cloud server has any idea whether or not you used a host name to connect is by the value of the host header. You should be able to just replace the value of the host header before forwarding the request on to the pool representing the cloud server's IP. The change might not be reflected in the log entry because I think header information is parsed once and then [HTTP::host] will always return what was parsed before iRule execution, but that's a question for the gurus.

     

     

    {

     

    HTTP::header replace "Host" "www.cloudHostName.com"

     

    log local0.alert "cloud_pool Host:[HTTP::host]-[HTTP::uri]"

     

    pool cloud_pool

     

    return

     

    }

     

     

    If a connection is on any port other than 80 you will want to modify this to include the port at the end of the new host header value, but if the connection is on port 80, this should suffice.

     

     

    Let me know how it goes. I didn't do any testing but I think this should do the trick.
  • Thanks Brian, I appreciate the response...

     

     

    Let me clarify my predicament a bit. My problem is that the new cloud provider does data center failover using DNS and therefore will not provide me with a specific IP address that I can define in a pool. Instead, I need some way (via irule) for the LTM to check to see what IP address is currently resolving for the domain name the cloud provider gave us, and then send traffic to that IP address instead of a pool.

     

     

    Basically I need the functionality above to replace my current statement "pool cloud_pool" with a rule that obtains an IP address by performing a name lookup and then sends the traffic for the defined URI's to that IP address.

     

     

    Does that make sense?

     

     

    Thanks,

     

     

    Rich
  • Hi rdessert,

     

     

    You could use the methods that you outlined to solve your problem.

     

     

    Performs a DNS query, typically returning the A record for the indicated hostname, or the PTR record for the indicated IP address.

     

    Starting in v10.1, the RESOLV::lookup command has been introduced, which is the inline version of this command.

     

    NAME::lookup

     

     

    RESOLV::lookup performs a DNS query, returning the A record for the indicated hostname, or the PTR record for the indicated IP address.

     

    RESOLV::lookup

     

     

    1. Lookup the FQDN of the cloud Provider and save the resolved IP Address to a variable.

     

    2. Use the Node Command to direct the traffic to the IP Address (an example is on the bottom of the RESOLV::lookup Wiki Page).

     

     

     

    Select the first returned IP address as the destination IP (inherits the destination port from the client's destination port).

     

    when RULE_INIT {

     

    set static::dns_vs my_dns_vs

     

    }

     

    when CLIENT_ACCEPTED {

     

     

    Get IP(s) for hostname www.example.com against 4.2.2.1 name server

     

    set ips [RESOLV::lookup @$static::dns_vs -a "www.example.com"]

     

     

    Log result. If there are multiple IP's it could be a TCL list like {1.1.1.1 2.2.2.2 3.3.3.3}.

     

    log local0. "Looked up www.example.com and found $ips, parsed first element: [lindex $ips 0]"

     

     

    Check if the first list element was empty

     

    if {$ips eq ""}{

     

    Input wasn't an IP address, take some default action?

     

    } else {

     

    Select the IP

     

    node [lindex $ips 0]

     

    }

     

    }

     

     

     

    Hope this helps.