政策式負載平衡

公共和私有應用程式負載平衡器都支援第 4 層和第 7 層負載平衡,資料流量會根據設定的政策和規則進行分散。 原則會定義送入要求符合與原則相關聯的規則時要採取的動作,這表示資料流量的配送方式。

第 7 層政策

您可以為 HTTP 和 HTTPS 監聽器定義政策。 對於每一個原則,您必須定義一或多個規則。 該政策僅在所有規則均符合時才會生效。

您可以將多項政策綁定至同一個監聽器。 一般而言,會先評估優先順序最低的原則。 每一個原則必須具有不同的優先順序。

如果傳入的請求不符合任何政策的規則,系統請求就會重定向到已設定的 HTTPS 重定向監聽器 (如果有的話)。 否則,系統會將要求重新導向至接聽器的預設儲存區。 HTTPS 重定向的優先順序高於 HTTP 監聽器上的預設池。

第 7 層原則支援下列動作:

  • 拒絕- 該請求遭駁回,並返回 403 回應。
  • 重定向 — 該請求將被重定向至已設定的 URL 及對應的回應碼。
  • 轉發至叢集 — 該請求將傳送至特定的後端叢集。
  • 轉送到偵聽器- 請求被傳送到特定的前端偵聽器。
  • HTTPS redirect- 請求重定向至 監聽器。HTTP HTTPS

原則內容

策略屬性說明
內容 說明
名稱 原則的名稱。 該名稱在接聽器內必須是唯一的。
動作 所有原則規則符合時要採取的動作。 可接受的值是 reject, redirect, forward_to_pool, forward_to_listener,和 https_redirect
優先順序 會根據遞增的優先順序來評估原則。
優先順序 會根據遞增的優先順序來評估原則。
URL 將要求重新導向至的 URL(如果動作設為 redirect 的話)。 您必須提供完整的 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 的前端監聽器。
接聽器 若動作設定為 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與後端之間進行。

如果您使用 HTTP / HTTPS Listener 與 SNI,請使用下列其中一種變通方法:

  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"
                    }
                }
            ]
        }'