F5 BIG-IP iRules: Traffic Manipulation and Pool Selection - 夜莺博客

F5 BIG-IP iRules: Traffic Manipulation and Pool Selection

iRules are the reason BIG-IP can do things no declarative load balancer can: choose a pool based on a header value, rewrite a URI before it reaches the server, or serve a maintenance page when every member of a pool is down. They are also the most common source of production incidents on an F5, because a TCL error in a rule silently changes where traffic goes. This guide covers the patterns engineers actually deploy, with the syntax that avoids the usual traps.

How iRules Execute

An iRule is a TCL script attached to a virtual server. The virtual server fires events and the iRule reacts to them; only the events you declare are executed. The two most used are CLIENT_ACCEPTED, which fires once when the TCP handshake completes, and HTTP_REQUEST, which fires for every request on a connection that has an HTTP profile. That distinction matters: a rule that selects a pool in CLIENT_ACCEPTED cannot see the URI, because the request has not arrived yet.

when CLIENT_ACCEPTED {
    if { [IP::addr [IP::client_addr] equals 10.10.10.10] } {
        pool my_pool
    }
}

Routing by URI

Content switching by path is the classic use case. Test the URI with starts_with, contains or ends_with rather than regular expressions where possible - string operators are faster and easier to read.

when HTTP_REQUEST {
    if { [HTTP::uri] starts_with "/api/" } {
        pool api_pool
    } elseif { [HTTP::uri] contains "/images/" } {
        pool static_pool
    } else {
        pool web_pool
    }
}

Order of evaluation is top to bottom, and if several conditions match, the last executed pool command wins. Keep the list short and put the most specific prefixes first.

Routing by Header and User-Agent

when HTTP_REQUEST {
    switch -glob [string tolower [HTTP::header User-Agent]] {
        "*scooter*" - "*slurp*" - "*msnbot*" - "*googlebot*" {
            pool slow_webbot_pool
        }
        default {
            pool real_users_pool
        }
    }
}

Always lowercase the header before globbing; user agents arrive with inconsistent capitalisation and a case-sensitive match quietly falls through to the default pool.

Pool Selection on a Keep-Alive Connection

Pool selection persists across requests on the same TCP connection. A rule that picks a different pool on the second request may appear to do nothing, which confuses everyone debugging it. Two fixes exist: store the original pool and compare against it, or attach a OneConnect profile so the connection to the server side can be re-selected.

when CLIENT_ACCEPTED {
    set default_pool [LB::server pool]
}
when HTTP_REQUEST {
    if { [HTTP::uri] starts_with "/sc/" } {
        pool pool_sc
    } else {
        pool $default_pool
    }
}

Graceful Failure Handling

Never let a rule send traffic to a pool with no active members. Test member availability first, then use LB_FAILED as a safety net when the selected member does not respond.

when HTTP_REQUEST {
    if { [active_members web_pool] < 1 } {
        HTTP::respond 503 content "Service temporarily unavailable"
        return
    }
    if { [HTTP::uri] ends_with ".gif" } {
        if { [LB::status pool img_pool member 10.1.2.200 80] eq "down" } {
            pool img_backup_pool
        } else {
            pool img_pool member 10.1.2.200 80
        }
    } else {
        pool web_pool
    }
}

when LB_FAILED {
    LB::reselect pool web_pool
    log local0. "Selected server did not respond; reselected from web_pool"
}

LB::reselect must precede the new pool command if a member has already been chosen, otherwise the reselection is ignored.

Header and Payload Manipulation

when HTTP_REQUEST {
    HTTP::header remove "X-Internal-Header"
    HTTP::header replace "Host" "www.example.com"
}
when HTTP_RESPONSE {
    HTTP::header insert "X-Cache" "HIT"
}

Payload rewrites require collecting the body first with HTTP::collect, which buffers the response in memory. Do not use payload rewriting on large objects; the memory cost scales with concurrency. When you only need to inspect or modify headers, header commands are always the better choice.

Deploying Without Breaking Production

Validate syntax in the iRule editor, then attach the rule to a staging virtual server before the production one. Watch /var/log/ltm for TCL errors - a rule that throws an error is aborted at that event, which can leave traffic pointed at the previous pool. Keep a rollback copy of the working rule and remember that the last match wins, so an unconditional pool at the bottom of a rule overrides everything above it. For the non-scriptable parts of traffic management, see BIG-IP virtual server and health monitor configuration, and for an open-source comparison of content-switching syntax, HAProxy ACL content switching and SSL termination.

原文链接:https://clouddocs.f5.com/api/irules/pool.html