Azure アプリケーションゲートウェイ(Application Gateway)でセッション アフィニティの設定方法をまとめます。セッションアフィニティは、同一セッションを同じ仮想マシンに振り分け続ける設定でアプリケーションがステートレスに設計されていない場合の回避策の設定です。このようなアプリケーションはクラウドネイティブのThe Twelve-Factor Appの思想に反するため理想ではありませんが、いわゆるクラウドリフト・シフトの案件ではステートレスではないアプリケーションの方が多数派で避けては通れない設定です。
前提
公式ドキュメント
参考になる公式ドキュメントを以下に示します。
事前設定
以下、リソースグループを作成します。
az group create --name MyResourceGroup --location japaneast
以下、仮想ネットワークを作成します。
az network vnet create \ --resource-group MyResourceGroup \ --name MyVnet \ --address-prefix 172.16.0.0/16 az network vnet subnet create \ --resource-group MyResourceGroup \ --name Subnet01 \ --vnet-name MyVnet \ --address-prefixes 172.16.1.0/24 az network vnet subnet create \ --resource-group MyResourceGroup \ --name Subnet02 \ --vnet-name MyVnet \ --address-prefixes 172.16.2.0/24
アプリケーションゲートウェイを作成します。
az network public-ip create \ --resource-group MyResourceGroup \ --name MyPublicAddress \ --sku Standard az network application-gateway create \ --name MyAppGateway \ --resource-group MyResourceGroup \ --capacity 2 \ --sku Standard_v2 \ --public-ip-address MyPublicAddress \ --vnet-name MyVnet \ --subnet Subnet01
アプリケーションゲートウェイ配下に仮想マシンスケールセットを配置します。
az vmss create \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --image UbuntuLTS \ --vm-sku Standard_B1s \ --admin-username azureuser \ --ssh-key-values ~/.ssh/authorized_keys \ --vnet-name MyVnet \ --subnet subnet02 \ --app-gateway MyAppGateway \ --backend-pool-name appGatewayBackendPool \ --custom-data /dev/stdin << 'EOF' #!/bin/bash apt-get -y install nginx echo "this is ${HOSTNAME}" > /var/www/html/index.html EOF
セッションアフィニティ
設定
セッションアフィニティ(Cookie persistence)は、バックエンド設定と呼ばれる項目で設定します。まずはデフォルトの状態で作成されるバックエンド設定名を調査します。以下showコマンドが示すように、デフォルト設定の場合は「appGatewayBackendHttpSettings」という名前の設定が作成されます。
az network application-gateway show \ --name MyAppGateway \ --resource-group MyResourceGroup \ --query "backendHttpSettingsCollection" [ { "affinityCookieName": null, "authenticationCertificates": null, "connectionDraining": { "drainTimeoutInSec": 1, "enabled": false }, "cookieBasedAffinity": "Disabled", "etag": "W/\"255f9581-1d27-4bc4-90dd-93291869a8db\"", "hostName": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/MyResourceGroup/providers/Microsoft.Network/applicationGateways/MyAppGateway/backendHttpSettingsCollection/appGatewayBackendHttpSettings", "name": "appGatewayBackendHttpSettings", "path": null, "pickHostNameFromBackendAddress": false, "port": 80, "probe": null, "probeEnabled": null, "protocol": "Http", "provisioningState": "Succeeded", "requestTimeout": 30, "resourceGroup": "MyResourceGroup", "trustedRootCertificates": null, "type": "Microsoft.Network/applicationGateways/backendHttpSettingsCollection" } ]
デフォルトの状態の「appGatewayBackendHttpSettings」はセッションアフィニティが無効になっています。
$ az network application-gateway http-settings show \ --gateway-name MyAppGateway \ --resource-group MyResourceGroup \ --name appGatewayBackendHttpSettings { "affinityCookieName": null, "authenticationCertificates": null, "connectionDraining": { "drainTimeoutInSec": 1, "enabled": false }, "cookieBasedAffinity": "Disabled", "etag": "W/\"255f9581-1d27-4bc4-90dd-93291869a8db\"", "hostName": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/MyResourceGroup/providers/Microsoft.Network/applicationGateways/MyAppGateway/backendHttpSettingsCollection/appGatewayBackendHttpSettings", "name": "appGatewayBackendHttpSettings", "path": null, "pickHostNameFromBackendAddress": false, "port": 80, "probe": null, "probeEnabled": null, "protocol": "Http", "provisioningState": "Succeeded", "requestTimeout": 30, "resourceGroup": "MyResourceGroup", "trustedRootCertificates": null, "type": "Microsoft.Network/applicationGateways/backendHttpSettingsCollection" }
セッションアフィニティを有効にし、さらにセッションアフィニティが使用するクッキー名を指定します。クッキー名は任意の名前で差し支えないですが、以下はBIG-IPからの移行案件を想定し、BIG-IPデフォルト設定のクッキー名(JSESSIONID)を使用する例の紹介です。
az network application-gateway http-settings update \ --gateway-name MyAppGateway \ --resource-group MyResourceGroup \ --name appGatewayBackendHttpSettings \ --affinity-cookie-name JSESSIONID \ --cookie-based-affinity Enabled
動作確認
ブラウザによる動作確認
アプリケーションゲートウェイに付与されたパブリックIPアドレスを確認します。
$ az network public-ip show \ --resource-group MyResourceGroup \ --name MyPublicAddress \ --query "ipAddress" "20.89.93.32"
パブリックIPアドレスをブラウザに入力します。F5押下で何度かリロードし、何度リロードしても同一の仮想マシンへ負荷分散される事を確認します。
curlコマンドによる動作確認
初回アクセスは、curlコマンドに-vオプションを付与しHTTP responseヘッダーが出力されるようにします。
admin@mac19 ~ % curl -v 20.89.93.32 * Trying 20.89.93.32:80... * Connected to 20.89.93.32 (20.89.93.32) port 80 (#0) > GET / HTTP/1.1 > Host: 20.89.93.32 > User-Agent: curl/7.77.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Mon, 02 May 2022 14:21:31 GMT < Content-Type: text/html < Content-Length: 24 < Connection: keep-alive < Set-Cookie: JSESSIONID=053c62b66fc54f87f5b43aaace622ebc; Path=/ < Server: nginx/1.14.0 (Ubuntu) < Last-Modified: Mon, 02 May 2022 13:46:54 GMT < ETag: "626fe0ce-18" < Accept-Ranges: bytes < this is myscae302000003 * Connection #0 to host 20.89.93.32 left intact admin@mac19 ~ %
2回目以降はCookieをセットした状態で疎通確認をします。curlコマンドを何回実行しても同一の仮想マシンに負荷分散される事を確認します。
admin@mac19 ~ % curl -H 'Cookie: JSESSIONID=053c62b66fc54f87f5b43aaace622ebc;' 20.89.93.32 this is myscae302000003 admin@mac19 ~ % admin@mac19 ~ % admin@mac19 ~ % curl -H 'Cookie: JSESSIONID=053c62b66fc54f87f5b43aaace622ebc;' 20.89.93.32 this is myscae302000003 admin@mac19 ~ % admin@mac19 ~ % admin@mac19 ~ % curl -H 'Cookie: JSESSIONID=053c62b66fc54f87f5b43aaace622ebc;' 20.89.93.32 this is myscae302000003 admin@mac19 ~ %