Microsoft Azureの仮想マシンスケールセットは、負荷に応じてスケールイン(台数減)が可能です。スケールインする時は、可用性セットを意識した台数減をしたり新しい仮想マシンを削除したりなどの「どのように削除するか」のポリシー定義が可能です。
前提
公式ドキュメント
参考になる公式ドキュメントを以下に示します。
事前設定
以下、リソースグループを作成します。
az group create --name MyResourceGroup --location japaneast
スケールインポリシー概要
スケールインポリシーは、仮想マシンのスケールイン(削除)時にどの順番で削除するかを定義する設定です。「Default」「NewestVM」「OldestVM」の3通りを定義設定できます。
Defaultのスケールインポリシー
概要
Defaultのスケールインポリシーは以下の順に削除します。
- 可用性ゾーン間で仮想マシンを均衡させます (スケール セットがゾーン構成でデプロイされている場合)
- 障害ドメイン間で仮想マシンを均衡させます (ベスト エフォート)
- インスタンス ID が最も大きい仮想マシンを削除します
仮想マシンスケールセットは、デフォルト設定の場合は可用性ゾーンを指定しません。言い換えれば、可用性ゾーンを明示指定した場合は可用性ゾーンが均等になるように仮想マシンが削除され、デフォルト設定の場合は障害ドメインが均等になるように仮想マシンが削除されます。
障害ドメインは明示指定しなくても、3つの障害ドメインに分割されます。
可用性ゾーンが均等になるように仮想マシンが作成・削除されます。仮想マシンの移動するわけではありません。可用性ゾーンに偏りが発生した場合は、作成・削除が発生しない限りは偏ったままになります。
スケールアウトルールの作成
ゾーンを指定して仮想マシンスケールセットを作成します。ゾーンを指定して仮想マシンスケールセットを作成した場合は、スケールイン(仮想マシン削除)時に、各ゾーンの仮想マシン数が均等になるように削除します。
az vmss create \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --image UbuntuLTS \ --vm-sku Standard_B1s \ --admin-username azureuser \ --ssh-key-values ~/.ssh/authorized_keys \ --zones 1 2 3 \ --instance-count 3 \ --custom-data /dev/stdin << EOF #!/bin/bash apt-get update apt-get -y install stress EOF
スケールアウトの設定をします。
az monitor autoscale create \ --resource-group MyResourceGroup \ --resource-type Microsoft.Compute/virtualMachineScaleSets \ --resource MyScaleSet01 \ --name Autoscale01 \ --min-count 3 \ --max-count 9 \ --count 3 az monitor autoscale rule create \ --resource-group MyResourceGroup \ --autoscale-name Autoscale01 \ --condition "Percentage CPU > 50 avg 5m" \ --scale out 3
負荷をかけます。
INSTANCE_IDS=$(az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --query "[].id" \ --output tsv ) az vmss run-command invoke \ --command-id RunShellScript \ --ids ${INSTANCE_IDS} \ --scripts 'nohup stress --cpu 1 --timeout 900 > /dev/null 2>&1 &'
スケールアウト後の可用性ゾーン確認
スケールアウト後に、どのようなゾーンに配置されているかを確認します。以下実行結果のように、各ゾーンに対して均等に仮想マシンが配置されます。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --query "[].{name:name, zone:zones[0]}" \ --output table Name Zone --------------- ------ MyScaleSet01_2 3 MyScaleSet01_4 2 MyScaleSet01_6 1 MyScaleSet01_7 2 MyScaleSet01_8 3 MyScaleSet01_9 1 MyScaleSet01_12 2 MyScaleSet01_13 3 MyScaleSet01_14 1
スケールインルールの作成
現在のスケールインポリシーを確認します。デフォルトの状態では「Default」と表示されます。この時の挙動は、可用性ゾーンが均等になるのを最優先にして、仮想マシンを削除します。
$ az vmss show \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --query scaleInPolicy { "forceDeletion": null, "rules": [ "Default" ] }
スケールインのルールを定義します。
az monitor autoscale rule create \ --resource-group MyResourceGroup \ --autoscale-name Autoscale01 \ --condition "Percentage CPU < 20 avg 5m" \ --scale in 1
スケールイン後の可用性ゾーン確認
スケールインルールを定義した約10分後の可用性ゾーンの配置を観察します。「可用性ゾーンが均一になるように」「インスタンスIDが大きい順に削除する」とのポリシーで仮想マシンの削除が行われている事が分かります。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet01 \ --query "[].{name:name, zone:zones[0]}" \ --output table Name Zone --------------- ------ MyScaleSet01_2 3 MyScaleSet01_4 2 MyScaleSet01_6 1 MyScaleSet01_7 2 MyScaleSet01_8 3 MyScaleSet01_9 1 MyScaleSet01_14 1
NewestVM/OldestVMのスケールインポリシー
概要
可用性ゾーンや障害ドメインが均等になるように仮想マシンが作成されます。仮想マシンのスケールイン(削除)は、可用性ゾーンや障害ドメインが均等になるように仮想マシンを削除します。もし、どの仮想マシンを削除しても均等さに差が発生しない場合は、Newest/Oldestな仮想マシンを優先的に削除します。
スケールアウトルールの作成
ゾーンを指定して仮想マシンスケールセットを作成します。
az vmss delete \ --resource-group MyResourceGroup \ --name MyScaleSet01 az vmss create \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --image UbuntuLTS \ --vm-sku Standard_B1s \ --admin-username azureuser \ --ssh-key-values ~/.ssh/authorized_keys \ --zones 1 2 3 \ --instance-count 3 \ --custom-data /dev/stdin << EOF #!/bin/bash apt-get update apt-get -y install stress EOF
スケールアウトの設定をします。
az monitor autoscale create \ --resource-group MyResourceGroup \ --resource-type Microsoft.Compute/virtualMachineScaleSets \ --resource MyScaleSet02 \ --name Autoscale02 \ --min-count 3 \ --max-count 9 \ --count 3 az monitor autoscale rule create \ --resource-group MyResourceGroup \ --autoscale-name Autoscale02 \ --condition "Percentage CPU > 50 avg 5m" \ --scale out 3
負荷をかけます。
INSTANCE_IDS=$(az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].id" \ --output tsv ) az vmss run-command invoke \ --command-id RunShellScript \ --ids ${INSTANCE_IDS} \ --scripts 'nohup stress --cpu 1 --timeout 900 > /dev/null 2>&1 &'
スケールアウト後の可用性ゾーン確認
作成された仮想マシンの可用性ゾーンを観察します。途中経過は以下のようになります。可用性ゾーンに偏りが発生しないのを最優先にし、可能な限りはOldestである可用性ゾーン2,3が優先的に削除している事が分かります。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].{instanceId:instanceId, zone:zones[0], name:name }" \ --output table InstanceId Zone Name ------------ ------ --------------- 12 2 MyScaleSet02_12 13 3 MyScaleSet02_13 17 1 MyScaleSet02_17 18 1 MyScaleSet02_18
最終的には以下のような構成になります。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].{instanceId:instanceId, zone:zones[0], name:name }" \ --output table InstanceId Zone Name ------------ ------ --------------- 12 2 MyScaleSet02_12 13 3 MyScaleSet02_13 18 1 MyScaleSet02_18
可用性ゾーン1の疑似障害
かなり極端なシナリオですが、ここで可用性ゾーン1の仮想マシンが全滅したとします。可用性ゾーン1の仮想マシンを全て削除します。
INSTANCE_IDS=$(az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[? zones[0]=='1'].instanceId" \ --output tsv ) az vmss delete-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --instance-ids $(echo ${INSTANCE_IDS} | tr '\n' ' ')
負荷をかけます。
INSTANCE_IDS=$(az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].id" \ --output tsv ) az vmss run-command invoke \ --command-id RunShellScript \ --ids ${INSTANCE_IDS} \ --scripts 'nohup stress --cpu 1 --timeout 420 > /dev/null 2>&1 &'
再び、仮想マシンが9台になった事を確認します。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].{instanceId:instanceId, zone:zones[0], name:name }" \ --output table InstanceId Zone Name ------------ ------ --------------- 2 3 MyScaleSet02_2 4 2 MyScaleSet02_4 7 2 MyScaleSet02_7 8 3 MyScaleSet02_8 12 2 MyScaleSet02_12 13 3 MyScaleSet02_13 15 1 MyScaleSet02_15 17 1 MyScaleSet02_17 18 1 MyScaleSet02_18
スケールインルールの作成
仮想マシンスケールセットのスケールインポリシーを「Default」から「OldestVM」へ変更します。
az vmss update \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --scale-in-policy OldestVM
スケールインのルールを定義します。
az monitor autoscale rule create \ --resource-group MyResourceGroup \ --autoscale-name Autoscale02 \ --condition "Percentage CPU < 20 avg 5m" \ --scale in 1
スケールイン後の可用性ゾーン確認
しばらく待ち、仮想マシンが配置されたゾーンを確認します。ゾーン1の仮想マシンのみが存在する事が分かります。このように状況によっては、「NewestVM」「OldestVM」は仮想マシンの偏りが発生してしまいます。
$ az vmss list-instances \ --resource-group MyResourceGroup \ --name MyScaleSet02 \ --query "[].{instanceId:instanceId, zone:zones[0], name:name }" \ --output table InstanceId Zone Name ------------ ------ --------------- 15 1 MyScaleSet02_15 17 1 MyScaleSet02_17 18 1 MyScaleSet02_18