0

我需要为许多类似的环境设置配置。每个都有不同的主机名,遵循某种模式,例如 env1、env2 等。

我可以为每个环境使用一个池和一个带有 irule 的单个虚拟服务器,该 irule 根据主机名选择一个池。

我更喜欢做的是根据请求的主机名动态生成和选择池名称,而不是在 switch 语句中列出每个池。它更易于维护和自动处理新环境。

代码可能如下所示:

when HTTP_REQUEST {
  pool [string tolower [HTTP:host]]
}

并且每个池名称都与主机名匹配。

这可能吗?或者有没有更好的方法?

编辑

我已经扩展了我的主机名池选择。我现在正在尝试包含端口号。新规则如下所示:

when HTTP_REQUEST {
  set lb_port "[LB::server port]"
  set hostname "[string tolower [getfield [HTTP::host] : 1]]"
  log local0.info "Pool name $hostname-$lb_port-pool"
  pool "$hostname-$lb_port-pool"

}

这是有效的,但我在日志中看到 no-such-pool 错误,因为端口 0 请求以某种方式进入池中。它似乎是第一个请求,然后是具有合法端口的请求。

Wed Feb 17 20:39:14 EST 2016    info    tmm tmm[6519]       Rule /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST>: Pool name my.example.com-80-pool
Wed Feb 17 20:39:14 EST 2016    err tmm1    tmm[6519]   01220001    TCL error: /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST> - no such pool: my.example.com-0-pool (line 1) invoked from within "pool "$hostname-$lb_port-pool""
Wed Feb 17 20:39:14 EST 2016    info    tmm1    tmm[6519]       Rule /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST>: Pool name my.example.com-0-pool

是什么导致端口 0 请求?有什么解决方法吗?例如,我可以测试端口 0 并选择默认端口或忽略它吗?

再编辑一次

重建虚拟服务器,现在错误消失了。VS的重建只是重命名它。我很确定我重新创建了完全相同的设置。

4

2 回答 2

3

是的,您可以在字符串中指定池名称。只要您有一个同名的池,您所拥有的就可以工作。虽然它没有显示以这种方式执行此操作的示例,但您也可以查看DevCentral上的wiki 页面以获取更多信息。

顺便说一句,在我的环境中,我通常会创建带有后缀的池,_pool以便在查看配置文件时将它们与其他对象区分开来。所以在我的 iRules 中,我会做这样的事情(基本上是同样的事情):

when HTTP_REQUEST {
    pool "[string tolower [HTTP::host]]_pool"
}
于 2016-02-10T12:34:08.077 回答
1

迈克尔提到的简单案例有效。如果存在,我建议删除端口值:

when HTTP_REQUEST {
    pool "pool_[string tolower [getfield [HTTP::host] : 1]]_[LB::server port]"
}

请记住,客户端可能会发送部分主机名。如果 DNS 搜索路径设置为,example.org则客户端可能会点击shared/which maps to shared.example.org,但 HTTP::host 标头将只有shared. 一些 API 库可能会附加端口号,即使它位于默认端口上。简单代码可能不会发送 Host 标头。恶意代码可能会发送完全虚假的 Host 标头。您可以使用catch.

您还可以使用数据组将主机名映射到池。这允许多个主机使用同一个池。示例代码:

when HTTP_REQUEST {
    set host [string tolower [getfield [HTTP::host] ":" 1]]
    if { $host == "" } {
        # if there's no Host header, pull from virtual server name
        # we use: pool_<virtualserver>_PROTOCOL
        set host [getfield [virtual name] _ 2]
    } elseif { not ($host contains ".") } {
        # if Host header does not contain a dot, assume example.org
        set host $host.example.org
    }
    set pool [class match -value $host[HTTP::uri] starts_with dg_shared.example.org]
    if { $pool ne ""} {
        set matched [class match -name $host[HTTP::uri] starts_with dg_shared.example.org]
        set log(matched) $matched
        set log(pool) $pool
        if { [catch { pool $pool } ] } {
            set log(reason) "Failed to Connect to Pool"
            call hsllog log
            call errorpage 404 $log(reason) "https://[HTTP::host][HTTP::uri]" log
        }
    } else {
        call errorpage 404 "No Pool Found" "https://[HTTP::host][HTTP::uri]" log
    }
}

when SERVER_CONNECTED {
    if {!($pool ends_with "_HTTPS") } {
        SSL::disable serverside
    }
}

这允许host.example.org/path1在不同的池上,host.example.org或者host.example.org/path2通过在数据组中包含单独的条目。我没有在这里包括hsllogand errorpageprocs。他们转储日志数组以及其他传递的参数。

然后,我们为不以 _HTTPS 结尾的池禁用服务器端 ssl。

注意:与动态生成的池名称一样,BIG-IP UI 不会在数据组内部查找池引用,因此该界面将允许您删除这些池之一,认为它未在使用中。

我们使用 BigIPReport 来识别孤儿池: https ://devcentral.f5.com/s/articles/bigip-report

于 2019-08-27T17:06:59.163 回答