Forum Discussion

Jim_Bo's avatar
Jim_Bo
Icon for Nimbostratus rankNimbostratus
Apr 15, 2014

HTTP::cookie, SWITCH and multiple identical pools

Hello Everyone,

 

I must load balance a suite of applications across four nearly identical pools using a single virtual server; pool_a thru pool_d. The application team wants to distinguish between pools by specifying /$pool_name/ in HTTP::path but only on the very first query. All other subsequent queries are identical across the pools. I needed a method to determine whether the request had already been load balanced so I added cookie persistence. Please note I am not looking for a specific cookie just any BigIP cookie. Here is my pseudo-code.

 

    when HTTP_REQUEST {
      if [HTTP::cookie] exists "BIGIP*"
         then persist cookie
      else {
      switch -glob [string tolower [HTTP::path]] {
        "/pool_a*" {
            HTTP::path "/"
            pool "pool_a" } 
        "/pool_b*" {
            HTTP::path "/"
            pool "pool_b" }
        "/pool_c*" {
            HTTP::path "/"
            pool "pool_c" } 
        "/pool_d*" {
            HTTP::path "/"
            pool "pool_d" } 
        default { reject }
       } }
      }

I welcome any comments on the best method to accomplish this request. Forgive me, I am new at iRules. I have tried to get the app team to prefix every query with /$pool_name/ but they have resisted.

 

Thanks Jim

 

3 Replies

  • Just apply a persistence cookie profile to your virtual

    Then the iRule would be;-

    when HTTP_REQUEST {
        foreach ck [HTTP::cookie names] {
            if {$ck starts_with "BIGipServer"} {
                 Select pool based on part of cookie name
                pool [substr $ck 11]
                 Drop out of event - F5 will choose appropriate pool member based on cookie
                return
            }   
        }   
        switch -glob [string tolower [HTTP::path]] {
            "/pool_a*" {
                HTTP::path "/"
                pool "pool_a" } 
            "/pool_b*" {
                HTTP::path "/"
                pool "pool_b" }
            "/pool_c*" {
                HTTP::path "/"
                pool "pool_c" } 
            "/pool_d*" {
                HTTP::path "/"
                pool "pool_d" } 
            default { reject }
           } 
        }
    }
    
  • Jim_Bo's avatar
    Jim_Bo
    Icon for Nimbostratus rankNimbostratus

    Thank you for your response. Your code did what I asked but unfortunately my logic was faulty. After testing, we discovered that if a user needed to access the information in more than one of the pools, the BigIP cookies from previous queries would direct queries to incorrect pools. So it appears that I need to remove the pool name strings from the URIs or PATHs during HTTP requests and add them back in during HTTP responses based upon the pool which processed the request. I am not sure how to accomplish this request.

     

     when HTTP_REQUEST
     switch -glob [string tolower [HTTP::path]] {
        "/pool_a*" {
            set lbpath HTTP::path
            HTTP::path "/"
            pool "pool_a" } 
        "/pool_b*" {
            set lbpath HTTP::path
            HTTP::path "/"
            pool "pool_b" }
        "/pool_c*" {
            set lbpath HTTP::path
            HTTP::path "/"
            pool "pool_c" } 
        "/pool_d*" {
            set lbpath HTTP::path
            HTTP::path "/"
            pool "pool_d" } 
        default { reject }
       } 
    
       when HTTP_RESPONSE
       switch -glob [string tolower $lbpath ] {
        "/pool_a*" {
            HTTP::path "/pool_a/[HTTP::path]" } 
        "/pool_b*" {
            HTTP::path "/pool_b/[HTTP::path]" }
        "/pool_c*" {
            HTTP::path "/pool_c/[HTTP::path]" } 
        "/pool_d*" {
            HTTP::path "/pool_d/[HTTP::path]" } 
        default { reject }
       } 
  • add them back in during HTTP responses based upon the pool which processed the request.

    request uri is not in http response. to make it clearer, have you ever used http analyzer tool such as httpfox? it can show you how http request and response look like.

    httpfox

    https://addons.mozilla.org/en-US/firefox/addon/httpfox/

    about the irule, can't we just move persist cookie command inside switch case? e.g.

     config
    
    [root@ve11a:Active:In Sync] config  tmsh list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            cookie {
                default yes
            }
        }
        profiles {
            http { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 5
    }
    [root@ve11a:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      switch -glob [HTTP::path] {
        "/pool_a/*" {
          HTTP::path [string map {/pool_a/ /} [HTTP::path]]
          persist cookie
          pool pool_a
        }
        "/pool_b/*" {
          HTTP::path [string map {/pool_b/ /} [HTTP::path]]
          persist cookie
          pool pool_b
        }
        default {
          reject
        }
      }
    }
    }
    
     test (sending request wrong cookie but the right pool is picked up - can see from response cookie)
    
    [root@ve11a:Active:In Sync] config  curl -I http://172.28.24.10/pool_a/ -H "Cookie: BIGipServerpool_b=1875429576.20480.0000"
    HTTP/1.1 200 OK
    Date: Fri, 18 Apr 2014 08:04:06 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Sun, 09 Feb 2014 08:39:51 GMT
    ETag: "41879c-59-2a9c23c0"
    Accept-Ranges: bytes
    Content-Length: 89
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: BIGipServerpool_a=1707657416.20480.0000; path=/
    
    [root@ve11a:Active:In Sync] config  curl -I http://172.28.24.10/pool_b/ -H "Cookie: BIGipServerpool_a=1707657416.20480.0000"
    HTTP/1.1 200 OK
    Date: Fri, 18 Apr 2014 08:05:22 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Tue, 23 Apr 2013 06:46:40 GMT
    ETag: "418432-4b-8c2c3400"
    Accept-Ranges: bytes
    Content-Length: 75
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: BIGipServerpool_b=1875429576.20480.0000; path=/