f5 LTM irule - 可以在 irule 中生成池名称吗
f5 LTM irule - can a pool name be generated in an irule
我需要为许多类似的环境设置配置。每个都有一个遵循某种模式的不同主机名,例如env1、env2 等
我可以为每个环境使用一个池,并使用一个规则 select 一个基于主机名的池的单个虚拟服务器。
我更愿意做的是根据请求的主机名动态生成和 select 池名称,而不是在 switch 语句中列出每个池。更易于维护并自动处理新环境。
代码可能如下所示:
when HTTP_REQUEST {
pool [string tolower [HTTP:host]]
}
并且每个池名称都与主机名匹配。
这可能吗?或者有更好的方法吗?
编辑
我已经扩展了主机名池 selection。我现在正在尝试包括端口号。新规则如下所示:
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"
}
这是有效的,但我在日志中看到没有这样的池错误,因为端口 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 和 select 默认端口还是忽略它?
再编辑一次
重建虚拟服务器,现在错误消失了。 VS 的重建只是重命名它。我很确定我重新创建了完全相同的设置。
是的,您可以在字符串中指定池名称。只要你有一个同名的池,你在那里的东西就可以工作。虽然它没有显示这样做的示例,但您也可以查看 pool wiki page on DevCentral 了解更多信息。
顺便说一句,在我的环境中,我通常会创建后缀为 _pool
的池,以便在查看配置文件时将它们与其他对象区分开来。所以在我的 iRules 中,我会做这样的事情(本质上是一样的):
when HTTP_REQUEST {
pool "[string tolower [HTTP::host]]_pool"
}
迈克尔提到的简单案例有效。如果存在,我建议删除端口值:
when HTTP_REQUEST {
pool "pool_[string tolower [getfield [HTTP::host] : 1]]_[LB::server port]"
}
请记住,客户端可能会发送部分主机名。如果 DNS 搜索路径设置为 example.org
,则客户端可能会命中映射到 shared.example.org
的 shared/
,但是 HTTP::host header 将只有 shared
.某些 API 库可能会附加端口号,即使它在默认端口上也是如此。简单代码可能不会发送主机 header。恶意代码可能会发送完全伪造的 Host headers。您可以使用 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
不同的池中。我没有在此处包含 hsllog
和 errorpage
过程。他们转储日志数组以及其他传递的参数。
然后我们为不以 _HTTPS 结尾的池禁用服务器端 ssl。
注意:与动态生成的池名称一样,BIG-IP UI 不会在数据组内部查找池引用,因此该接口将允许您删除其中一个池,认为它不在使用。
我们使用 BigIPReport 来识别孤立池:
https://devcentral.f5.com/s/articles/bigip-report
我需要为许多类似的环境设置配置。每个都有一个遵循某种模式的不同主机名,例如env1、env2 等
我可以为每个环境使用一个池,并使用一个规则 select 一个基于主机名的池的单个虚拟服务器。
我更愿意做的是根据请求的主机名动态生成和 select 池名称,而不是在 switch 语句中列出每个池。更易于维护并自动处理新环境。
代码可能如下所示:
when HTTP_REQUEST {
pool [string tolower [HTTP:host]]
}
并且每个池名称都与主机名匹配。
这可能吗?或者有更好的方法吗?
编辑
我已经扩展了主机名池 selection。我现在正在尝试包括端口号。新规则如下所示:
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"
}
这是有效的,但我在日志中看到没有这样的池错误,因为端口 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 和 select 默认端口还是忽略它?
再编辑一次
重建虚拟服务器,现在错误消失了。 VS 的重建只是重命名它。我很确定我重新创建了完全相同的设置。
是的,您可以在字符串中指定池名称。只要你有一个同名的池,你在那里的东西就可以工作。虽然它没有显示这样做的示例,但您也可以查看 pool wiki page on DevCentral 了解更多信息。
顺便说一句,在我的环境中,我通常会创建后缀为 _pool
的池,以便在查看配置文件时将它们与其他对象区分开来。所以在我的 iRules 中,我会做这样的事情(本质上是一样的):
when HTTP_REQUEST {
pool "[string tolower [HTTP::host]]_pool"
}
迈克尔提到的简单案例有效。如果存在,我建议删除端口值:
when HTTP_REQUEST {
pool "pool_[string tolower [getfield [HTTP::host] : 1]]_[LB::server port]"
}
请记住,客户端可能会发送部分主机名。如果 DNS 搜索路径设置为 example.org
,则客户端可能会命中映射到 shared.example.org
的 shared/
,但是 HTTP::host header 将只有 shared
.某些 API 库可能会附加端口号,即使它在默认端口上也是如此。简单代码可能不会发送主机 header。恶意代码可能会发送完全伪造的 Host headers。您可以使用 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
不同的池中。我没有在此处包含 hsllog
和 errorpage
过程。他们转储日志数组以及其他传递的参数。
然后我们为不以 _HTTPS 结尾的池禁用服务器端 ssl。
注意:与动态生成的池名称一样,BIG-IP UI 不会在数据组内部查找池引用,因此该接口将允许您删除其中一个池,认为它不在使用。
我们使用 BigIPReport 来识别孤立池: https://devcentral.f5.com/s/articles/bigip-report