Forum Discussion

Andy_Clark_1335's avatar
Andy_Clark_1335
Icon for Nimbostratus rankNimbostratus
Jul 19, 2016

Switch between default pool and another virtual server, per request

My CDN sends requests to public_vs, an external facing virtual server. public_vs sends the request to proxy_pool, a pool of proxy servers. The proxy servers make changes to the request and proxy it application_vs, a different virtual server on the same LTM. application_vs sends the requests to application_pool, a pool of application servers.

CDN -> public_vs -> proxy_pool -> proxy_app_node -> application_vs -> application_pool

Depending upon request headers (ex. "True-Client-IP: 1.2.3.4"), I want to bypass the pool of proxy servers, sending the request to application_vs.

CDN -> public_vs -> application_vs -> application_pool

Test public_vs

Default pool: simple application that does not forward the request to application_vs (for testing) Assigned iRule public_irule:

        when CLIENT_ACCEPTED {
          set i 0
          log local0. "Client accepted"
        }

        when HTTP_REQUEST {
          incr i 1
          set true_ip [HTTP::header value "True-Client-IP"]
          log local0. "public_vs request $i: $true_ip"
          if {"$true_ip" eq "1.2.3.4"} {
            log local0. "switching to application_vs"
            virtual "application_vs"
          }
        }

        when CLIENT_CLOSED {
          log local0. "Client session closed after $i requests"
        }
application_vs

Assigned the iRule application_irule:

        when HTTP_REQUEST {
          set barip [HTTP::header value "True-Client-IP"]
          log local0. "application_vs: $barip"
          HTTP::respond 200 content "application_vs" Content-Type "text/html"
        }
JMeter test plan

The CDN sends many requests over a single HTTP connection. This is replicated in JMeter using a single thread group with two HTTP requests pointing to public_vs. The first has the header "True-Client-IP: 192.168.76.1", the second has "True-Client-IP: 1.2.3.4".

Test Results

Ran the JMeter test for 5 iterations, watching the F5 LTM log:

        16:32:10 public_irule : Client accepted
        16:32:10 public_irule : public_vs request 1: 192.168.76.1
        16:32:10 public_irule : public_vs request 2: 1.2.3.4
        16:32:10 public_irule : switching to application_vs
        16:32:10 application_irule : application_vs: 1.2.3.4
        16:32:10 public_irule : public_vs request 3: 192.168.76.1
        16:32:10 application_irule : application_vs: 192.168.76.1
        16:32:11 public_irule : public_vs request 4: 1.2.3.4
        16:32:11 public_irule : switching to application_vs
        16:32:11 application_irule : application_vs: 1.2.3.4
        16:32:11 public_irule : public_vs request 5: 192.168.76.1
        16:32:11 application_irule : application_vs: 192.168.76.1
        16:32:11 public_irule : public_vs request 6: 1.2.3.4
        16:32:11 public_irule : switching to application_vs
        16:32:11 application_irule : application_vs: 1.2.3.4
        16:32:11 public_irule : public_vs request 7: 192.168.76.1
        16:32:11 application_irule : application_vs: 192.168.76.1
        16:32:11 public_irule : public_vs request 8: 1.2.3.4
        16:32:11 public_irule : switching to application_vs
        16:32:11 application_irule : application_vs: 1.2.3.4
        16:32:11 public_irule : public_vs request 9: 192.168.76.1
        16:32:11 application_irule : application_vs: 192.168.76.1
        16:32:11 public_irule : public_vs request 10: 1.2.3.4
        16:32:11 public_irule : switching to application_vs
        16:32:11 application_irule : application_vs: 1.2.3.4
        16:32:11 public_irule : Client session closed after 10 requests

2 Replies

  • virtual causes all subsequent requests for the current connection to go through the second virtual server.

     

    I've tried using OneConnect profiles as described in SOL9800. However, I believe that only works for balancing pools. I have also tried adding LB::detach.

     

    Any suggestions or insight?

     

  • You can do this for packets without "True-Client-IP": CDN -> public_vs -> application_pool

    instead of doing this: CDN -> public_vs -> application_vs -> application_pool

    You can use an iRule attached to public_vs that will send traffic without "True-Client-IP" to the application_pool. Use OneConnect with 255.255.255.255 netmask in order to preserve the client IP at the server level.

    when HTTP_REQUEST {
    if { [HTTP::header exists "True-Client-IP"] } {
    pool proxy_pool
    } else {
    pool application_pool
    }
    }