基于策略的负载均衡
公共和私有应用负载平衡器都支持第 4 层和第 7 层负载平衡,根据配置的策略和规则分配数据流量。 当入局请求与与策略关联的规则匹配时,策略将定义要执行的操作,这表示流量的分布方式。
第7层策略
您可以为 HTTP 和 HTTPS 听众定义政策。 对于每个策略,必须定义一个或多个规则。 只有当该策略的所有规则均匹配时,该策略才会生效。
您可以将多个策略关联到一个监听器上。 通常,首先对具有最低优先级的策略求值。 每个策略必须具有不同的优先级。
如果传入请求不符合任何策略规则,系统请求将重定向到配置的 HTTPS 重定向侦听器(如果存在)。 否则,系统会将请求重定向到侦听器的缺省池。 HTTPS 重定向优先级高于 HTTP 侦听器上的默认池。
层 7 策略支持以下操作:
- 拒绝- 请求被拒绝,并返回 403 状态码。
- 重定向 ——该请求被重定向到已配置的 URL 以及相应的响应代码。
- 转发到池 ——将请求发送到特定的后端池。
- 转发给监听器- 将请求发送给特定的前端监听器。
- HTTPS 重定向 —— 请求重定向到 监听器。HTTP HTTPS
策略属性
| 属性 | 描述 |
|---|---|
| 名称 | 策略的名称。 名称在侦听器中必须唯一。 |
| 操作 | 所有策略规则匹配时要执行的操作。 可接受的值为 reject, redirect, forward_to_pool, forward_to_listener 和 https_redirect。 |
| 优先级 | 将根据优先级升序对策略求值。 |
| 优先级 | 将根据优先级升序对策略求值。 |
| URL | 在操作设置为 redirect 的情况下,请求将重定向到的 URL。 您必须提供一个完整的 URL 或URI的参数。 当使用 URL 时,所有传入流量将重定向到这个 URL。 使用 URI 参数时,可通过使用参数的传入值来保留传入流量请求的值。 URI 参数的默认值等于其原始输入值。 要保留输入的值,请将它们作为 {protocol}、{port}、{host}、{path} 和 {query} 提供。 例如,如果传入请求的主持人是 ibm.com,则默认值是 {host},等于传入的 ibm.com 值。 |
| HTTP 状态码 | 当操作设置为“redirect”或“https_redirect”时,应用程序负载均衡器返回的响应状态码。 允许的值包括:301、302、303、307 或 308。 |
| 目标 | 如果操作设置为 forward_to_pool,请求将转发到虚拟服务器实例的后端池。 或者,如果操作设置为 forward_to_listener,请求会被转发到同一 ALB 的前端监听器。 |
| 侦听器 | 如果 action 设置为 https_redirect,则请求将被重定向到的 HTTPS 监听器。 |
| URI | 请求重定向到的相对 URI (如果操作为 https_redirect)。 此属性可选。 |
第 7 层规则
规则定义了请求的匹配方式。 同时支持基于 URI 的路由和基于参数的路由。 支持以下五种规则类型。
| 类型 | 描述 |
|---|---|
hostname |
该请求与指定的 hostname 相匹配,例如 api.my_company.com。 |
header |
该请求与 HTTP header 字段及其值匹配,例如 Cookie: xxxx。 |
path |
该请求与 URL 中 hostname 之后部分的 path 匹配,例如 /index.html。 |
query |
该请求与 URL 中的 query 字符串匹配,例如 x=y。 query 字符串必须采用百分比编码,且区分大小写。 |
body |
针对 POST 的请求 body 采用表单编码格式。 该请求与请求体匹配,例如 key=value。 区分大小写。 |
sni_hostname |
在 TLS 协商过程中,“服务器名称指示”(SNI)扩展中提供的服务器与指定的SNI主机名相匹配。 |
要匹配一个请求,必须在规则中定义一个 condition 语句。 支持以下四种条件。
| 条件 | 求值类型 |
|---|---|
contains |
验证根据 type 提取的值是否包含 value 中指定的字符串。 |
equals |
验证根据 type 提取的值是否与 value 中指定的字符串完全一致。 |
matches_regex |
将根据 type 提取的值与 value 中指定的正则表达式进行匹配。 |
starts_with |
验证根据 type 提取的值是否以 value 中指定的字符串开头。 |
规则属性
下表描述了第7层策略规则属性。
| 属性 | 描述 |
|---|---|
type |
指定规则的类型。 可接受的值为 hostname,header,path,query 或 body。 |
condition |
指定用于评估该规则的条件。 支持的值包括 contains、equals 或 matches_regex。 |
field |
指定字段名称。 此字段仅适用于 header query 和 body 规则类型,并且不支持正则表达式和通配符。 例如,要匹配 HTTP 头中的 cookie,可以将该字段设置为 cookie。 当规则类型为 query 和 body 时,此字段是可选的。 此属性不适用于 sni_hostname 规则类型。 |
value |
待匹配的字符串。 该字段不支持通配符。 当 condition 设置为 matches_regex 时,系统支持正则表达式。 |
注:
- 如果规则类型为
header,那么field和value不允许使用以下字符:"(),/:;<=>?@[\]{}'。 - 如果规则类型为
body,那么field和value不允许使用以下字符:"'=,()&和空格。 - 如果规则类型为
query,那么field和value必须是百分比编码的字符串。
示例:制定政策和规则
以下层 7 示例显示了如何创建策略和规则并使其与侦听器相关联。
示例1:创建一个具有重定向策略的 HTTPS 侦听器
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" \
-d '{
"certificate_instance": {
"crn": "crn:v1:bluemix:public:cloudcerts:us-south:a/1111111111111111111111111111:22222222-3333-4444-5555-666666666666:certificate:77777777777777777777777777777777"
},
"connection_limit": 2000,
"port": 443,
"protocol": "https",
"policies": [
{
"name": "hostname_header",
"action": "redirect",
"priority": 1,
"target": {
"url": "https://www.examples.com/",
"http_status_code": 307
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "hostname",
"value": "abc.com"
}
]
},
{
"name": "header_cookie",
"action": "redirect",
"priority": 5,
"target": {
"url": "https://www.mycookies.com/",
"http_status_code": 302
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"name": "path_hostname",
"action": "redirect",
"priority": 10,
"target": {
"url": "https://www.myexamples.com/",
"http_status_code": 301
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "abc"
},
{
"condition": "equals",
"value": "/test",
"type": "path"
}
]
},
{
"name": "uri_redirect",
"action": "redirect",
"priority": 10,
"target": {
"url": "https://{host}:8080/{path}?{query}",
"http_status_code": 301
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "pqr"
}
]
}
]
}'
示例 2:创建将请求转发到资源池的策略,并将其与现有监听器关联
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners/$listenerId/policies" \
-d '{
"policies": [
{
"action": "forward",
"priority": 1,
"target": {
"id": "7df616da-4dd6-43d3-881d-801ae29e29fe"
},
"rules": [
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"action": "forward",
"priority": 5,
"target": {
"id": "0738-8061c411-0d50-4c79-b475-102666796434"
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
}
]
},
{
"action": "forward",
"priority": 10,
"target": {
"id": "0738-62914e09-3928-4d89-b7f7-1bb7a6d7fe85"
},
"rules": [
{
"condition": "matches_regex",
"type": "hostname",
"value": "abc[a-z]*.com"
}
]
},
{
"action": "forward",
"priority": 6,
"target": {
"id": "0738-62914e09-3928-4d89-b7f7-1bb7a6d7fe85"
},
"rules": [
{
"condition": "equals",
"type": "path",
"value": "/test/testtest"
}
]
}
]
}'
示例3:创建一个具有https重定向策略的 HTTP 监听器
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" \
-d '{
"connection_limit": 2000,
"port": 80,
"protocol": "http",
"policies": [
{
"name": "hostname_header",
"action": "https_redirect",
"priority": 1,
"target": {
"listener": {
"id": "0134-d578be10-31e3-46b3-8513-79babb852319"
},
"http_status_code": 307
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "hostname",
"value": "abc.com"
}
]
},
{
"name": "header_cookie",
"action": "https_redirect",
"priority": 2,
"target": {
"listener": {
"id": "0456-a578be10-31e3-46b3-8513-79babb852398"
},
"http_status_code": 302
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"name": "path_hostname",
"action": "https_redirect",
"priority": 5,
"target": {
"listener": {
"id": "0386-d898be10-21e3-66b3-9513-69babb852390"
},
"http_status_code": 301,
"uri": "/test/sample"
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "abc"
},
{
"condition": "equals",
"value": "/test",
"type": "path"
}
]
}
]
}'
第 4 层政策
您可以为 TCP 监听器定义策略。 对于每个策略,必须定义一个或多个规则。 与第 7 层策略类似,第 4 层策略优先级最低,只有在所有指定规则都匹配时才会应用。
如果传入的请求不符合任何策略的规则,客户端可能会收到 SSL 错误。
第 4 层策略支持以下操作:
- 转发到池- 请求被发送到特定的后端池。
- 转发给监听器- 将请求发送给特定的前端监听器。
第 4 层规则
第 4 层规则定义如何匹配请求,与第 7 层规则相同。 但只支持 sni_hostname 类型,其中 field 不适用,condition 和 value 属性与第 7 层规则相同。
“SNI 主机名”规则仅适用于 TCP 监听器。
IBM Cloud ALB 中的 SNI 连接到监听器,可让您根据主机名将流量路由到不同的后端池。 在池内,流量总是通过所选算法(循环、最少连接等)在所有成员之间进行负载平衡。 不能使用 SNI 挑选池内的特定成员。
如果使用的是带有协议 HTTP 或 HTTP 的后端池,则 ALB 在将客户端请求转发到后端池时不会设置 SNI。 这是因为ALB仅使用SNI来做出转发决策(如果配置了第7层规则),并且ALB会与后端进行独立的 TLS 握手(这与客户端的握手不同)。
如果您使用的是 TCP 协议作为后端,而非 HTTP /HTTPS,那么ALB将设置由消费者发送的SNI。 这是因为 TLS 的握手过程将直接在客户端与后端之间进行,而非在ALB与后端之间进行。
如果使用带有 SNI 的 HTTP / HTTPS 监听器,请使用以下变通方法之一:
- 在虚拟主机上使用通配符证书。 然后在不同的后端端口上只配置一个主机名。 例如,如果要按主机名路由到单个服务器,可以为每个主机名创建单独的池,并使用 SNI 路由到正确的池。
- 请将后端协议设置为 TCP 模式,而非HTTPS。 TCP 此模式将正确转发 SNI,并且如果您进行了相应配置,仍可基于 SNI 主机名规则进行负载均衡。
示例:使用 sni_hostname 规则创建一个 TCP 监听器
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" -d '{
"connection_limit": 2000,
"port": 443,
"protocol": "tcp",
"policies": [
{
"action": "forward_to_listener",
"name": "listener-forward-policy",
"priority": 4,
"rules": [
{
"condition": "equals",
"type": "sni_hostname",
"value": "www.example.com"
}
],
"target": {
"id": "r006-20275400-825e-4d9b-8177-076fdb4134cc"
}
}
]
}'