基于策略的负载均衡

公共和私有应用负载平衡器都支持第 4 层和第 7 层负载平衡,根据配置的策略和规则分配数据流量。 当入局请求与与策略关联的规则匹配时,策略将定义要执行的操作,这表示流量的分布方式。

第7层策略

您可以为 HTTP 和 HTTPS 听众定义政策。 对于每个策略,必须定义一个或多个规则。 只有当该策略的所有规则均匹配时,该策略才会生效。

您可以将多个策略关联到一个监听器上。 通常,首先对具有最低优先级的策略求值。 每个策略必须具有不同的优先级。

如果传入请求不符合任何策略规则,系统请求将重定向到配置的 HTTPS 重定向侦听器(如果存在)。 否则,系统会将请求重定向到侦听器的缺省池。 HTTPS 重定向优先级高于 HTTP 侦听器上的默认池。

层 7 策略支持以下操作:

  • 拒绝- 请求被拒绝,并返回 403 状态码。
  • 重定向 ——该请求被重定向到已配置的 URL 以及相应的响应代码。
  • 转发到池 ——将请求发送到特定的后端池。
  • 转发给监听器- 将请求发送给特定的前端监听器。
  • HTTPS 重定向 —— 请求重定向到 监听器。HTTP HTTPS

策略属性

政策属性说明
属性 描述
名称 策略的名称。 名称在侦听器中必须唯一。
操作 所有策略规则匹配时要执行的操作。 可接受的值为 reject, redirect, forward_to_pool, forward_to_listenerhttps_redirect
优先级 将根据优先级升序对策略求值。
优先级 将根据优先级升序对策略求值。
URL 在操作设置为 redirect 的情况下,请求将重定向到的 URL。 您必须提供一个完整的 URL 或URI的参数。 当使用 URL 时,所有传入流量将重定向到这个 URL。 使用 URI 参数时,可通过使用参数的传入值来保留传入流量请求的值。 URI 参数的默认值等于其原始输入值。 要保留输入的值,请将它们作为 {protocol}{port}{host}{path}{query} 提供。 例如,如果传入请求的主持人是 ibm.com,则默认值是 {host},等于传入的 ibm.com 值。
HTTP 状态码 当操作设置为“redirect”或“https_redirect”时,应用程序负载均衡器返回的响应状态码。 允许的值包括:301302303307308
目标 如果操作设置为 forward_to_pool,请求将转发到虚拟服务器实例的后端池。 或者,如果操作设置为 forward_to_listener,请求会被转发到同一 ALB 的前端监听器。
侦听器 如果 action 设置为 https_redirect,则请求将被重定向到的 HTTPS 监听器。
URI 请求重定向到的相对 URI (如果操作为 https_redirect)。 此属性可选。

第 7 层规则

规则定义了请求的匹配方式。 同时支持基于 URI 的路由和基于参数的路由。 支持以下五种规则类型。

第 7 层规则
类型 描述
hostname 该请求与指定的 hostname 相匹配,例如 api.my_company.com
header 该请求与 HTTP header 字段及其值匹配,例如 Cookie: xxxx
path 该请求与 URL 中 hostname 之后部分的 path 匹配,例如 /index.html
query 该请求与 URL 中的 query 字符串匹配,例如 x=yquery 字符串必须采用百分比编码,且区分大小写。
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 指定规则的类型。 可接受的值为 hostnameheaderpathquerybody
condition 指定用于评估该规则的条件。 支持的值包括 containsequalsmatches_regex
field 指定字段名称。 此字段仅适用于 header querybody 规则类型,并且不支持正则表达式和通配符。 例如,要匹配 HTTP 头中的 cookie,可以将该字段设置为 cookie。 当规则类型为 querybody 时,此字段是可选的。 此属性不适用于 sni_hostname 规则类型。
value 待匹配的字符串。 该字段不支持通配符。 当 condition 设置为 matches_regex 时,系统支持正则表达式。

  • 如果规则类型为 header,那么 fieldvalue 不允许使用以下字符: "(),/:;<=>?@[\]{}'
  • 如果规则类型为 body,那么 fieldvalue 不允许使用以下字符: "'=,()& 和空格。
  • 如果规则类型为 query,那么 fieldvalue 必须是百分比编码的字符串。

示例:制定政策和规则

以下层 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 不适用,conditionvalue 属性与第 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 监听器,请使用以下变通方法之一:

  1. 在虚拟主机上使用通配符证书。 然后在不同的后端端口上只配置一个主机名。 例如,如果要按主机名路由到单个服务器,可以为每个主机名创建单独的池,并使用 SNI 路由到正确的池。
  2. 请将后端协议设置为 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"
                    }
                }
            ]
        }'