PaaS(WebApps)のオートスケーリングはとても楽で便利ですが、同じことをIaaS(VirtualMachine)でやろうとしたらどうなるかな?と思って構築しました。
せっかくなのでIaaSっぽく、閉域網(ExpressRoute)の環境で実現します。
Azure VirtualMachine ScaleSetsをExpressRouteのvNet内に構築します。
ポイントはパブリックロードバランサーではなく、インターナルロードバランサーを使用することです。
インターナルのVMSSはポータルからの作成はできないので、AzureCLI(CloudShell)でセットアップします。
VMSSの概要は公式ページ参照
Azure Virtual Machine Scale Sets とは
Cloud Shell起動
Cloud Shell Bashを選択します。手順は公式ページ参照。
Cloud Shell クイックスタート
VM作成
VMSSでは元となるOSイメージが必要なので、まずはVMを作ります。
- 変数を定義します
export RESOURCE_GROUP=[任意のリソースグループ名]
export NSG_NAME=${RESOURCE_GROUP}-NSG
export NIC_NAME=${RESOURCE_GROUP}-NIC
export VM_NAME=${RESOURCE_GROUP}-VM
export USER_NAME=[任意のユーザ名]
export USER_PASS=[任意パスワード]
- リソースグループを作成します
az group create --name $RESOURCE_GROUP --location japaneast
- ネットワークセキュリティグループ(NSG)を作成します
az network nsg create --resource-group $RESOURCE_GROUP --name $NSG_NAME
- NSGにRDP許可設定を追加します
az network nsg rule create \
--resource-group $RESOURCE_GROUP \
--nsg-name $NSG_NAME \
--name Allow-RDP-ALL \
--protocol tcp \
--priority 1000 \
--destination-port-range 3389 \
--access allow
- NSGにhttp許可設定を追加します
az network nsg rule create \
--resource-group $RESOURCE_GROUP \
--nsg-name $NSG_NAME \
--name Allow-HTTP-ALL \
--protocol tcp \
--priority 1001 \
--destination-port-range 80 \
--access allow
- SubnetIDを取得します(異なるリソースグループのSubnetを指定する場合、Subnet名ではなく、ID指定しないといけない為)
export SUBNET_ID=`az network vnet subnet show --name [ExRouteのSubnet名] --resource-group [ExRouteのリソースグループ名] --vnet-name [ExRouteのvNet名] --query id -o tsv`
- 仮想NICを作成します
az network nic create \
--resource-group $RESOURCE_GROUP \
--name $NIC_NAME \
--subnet $SUBNET_ID \
--network-security-group $NSG_NAME
- VMを作成します
az vm create --resource-group $RESOURCE_GROUP \
--name $VM_NAME \
--image win2016datacenter \
--location japaneast \
--nics $NIC_NAME \
--size Standard_DS1 \
--admin-username $USER_NAME \
--admin-password $USER_PASS
作成が完了すると、コマンド実行結果にPrivateIpAddressが出力される為、RDPで接続します。
ExpressRoute接続を想定しているため、パブリックIPは付与していません接続できたらPowerShellを立ち上げます
PowerShellプロンプトでIISをインストールします
Install-WindowsFeature -name Web-Server –IncludeManagementTools
Write-Output -InputObject “Azure!!! <br> VMSS!!!" > C:\inetpub\wwwroot\index.html
- 自PCのブラウザからPrivateIpAddress宛にアクセスし、Webページが表示されたらOKです
sysprep実行
イメージ作成前にWindowsServerを一般化します。
sysprepは作成したWindowsServer上で実行します。自PCで実行しないように注意してください!
sysprepは作成したWindowsServer上で実行します。自PCで実行しないように注意してください!
カスタムイメージ作成
一般化したVMからイメージを作成します
- Cloud Shellに戻り、VMが正常に停止されているか確認します
az vm get-instance-view -g $RESOURCE_GROUP -n $VM_NAME --query instanceView.statuses[1] -o table
「PowerState/stopped」が表示されていればOKです
VMのAzureリソース割り当てを解除します
az vm deallocate -g $RESOURCE_GROUP -n $VM_NAME
- VMを一般化します
このコマンドでsysprepされるわけではありません。Azureから見て一般化されたとみなすフラグを立てるコマンドです。
az vm generalize -g $RESOURCE_GROUP -n $VM_NAME
- イメージを作成します
az image create -g $RESOURCE_GROUP -n ${VM_NAME}-IMAGE --source $VM_NAME
- イメージ化したので、元となったVMは削除しておきます
az vm delete -g $RESOURCE_GROUP -n $VM_NAME --no-wait –y
- OSディスクも削除します
export OSDISK=`az disk list -g $RESOURCE_GROUP --query [].name -o tsv`
az disk delete -g $RESOURCE_GROUP -n $OSDISK --no-wait –y
- 仮想NICも削除します
az network nic delete -g $RESOURCE_GROUP -n $NIC_NAME
- ポータルからリソースグループの中を見てみると、カスタムイメージとNSGのみになっているはずです
NSGはVMSS作成時に使いまわすので残しています。
不要なリソースをキチンと削除することは重要です。
VMSS作成
- 変数を定義します
export RESOURCE_GROUP=[任意のリソースグループ名]
export NSG_NAME=${RESOURCE_GROUP}-NSG
export IMAGE_ID=`az image list --resource-group $RESOURCE_GROUP --query "[].id" -o tsv`
export SUBNET_ID=`az network vnet subnet show --name [ExRouteのSubnet名] --resource-group [ExRouteのリソースグループ名] --vnet-name [ExRouteのvNet名] --query id -o tsv`
export LB_NAME=${RESOURCE_GROUP}-LB
export BACKEND_POOL=LoadBalancerBackEnd
export FRONTEND_IP=LoadBalancerFrontEnd
export PROBE=LoadBalancerWebProbe
export RULE=weblb
export VMSS_NAME=${RESOURCE_GROUP}-VMSS
export USER_NAME=[任意のユーザ名]
export USER_PASS=[任意のパスワード]
- インターナルロードバランサーを作成します
az network lb create \
-g $RESOURCE_GROUP \
-n $LB_NAME \
--subnet $SUBNET_ID \
--backend-pool-name $BACKEND_POOL \
--frontend-ip-name $FRONTEND_IP
- ロードバランサーに正常性プローブを作成します
az network lb probe create \
-g $RESOURCE_GROUP \
--lb-name $LB_NAME \
-n $PROBE \
--port 80 \
--protocol tcp \
--interval 15 \
--threshold 5
- ロードバランサーに負荷分散規則を作成します
az network lb rule create \
-g $RESOURCE_GROUP \
--backend-port 80 \
--frontend-port 80 \
--lb-name $LB_NAME \
-n $RULE \
--protocol Tcp \
--backend-pool-name $BACKEND_POOL \
--floating-ip false \
--frontend-ip-name $FRONTEND_IP \
--probe-name $PROBE
- VMSSを作成します(ここではインスタンス1台構成で作ってます)
az vmss create \
-g $RESOURCE_GROUP \
-n $VMSS_NAME \
--nsg $NSG_NAME \
--load-balancer $LB_NAME \
--subnet $SUBNET_ID \
--image $IMAGE_ID \
--authentication-type password \
--admin-username $USER_NAME \
--admin-password $USER_PASS \
--backend-pool-name $BACKEND_POOL \
--instance-count 1
- 作成が完了したらロードバランサーのフロントエンドIPアドレスを取得します
az network lb show -g $RESOURCE_GROUP -n $LB_NAME --query frontendIpConfigurations[].privateIpAddress -o tsv
自PCのブラウザからフロントエンドIPアドレス宛にアクセスし、Webページが表示されたらOKです
せっかくなので手動でスケールアウトしてみます
az vmss scale -g $RESOURCE_GROUP -n $VMSS_NAME --new-capacity 2
まとめ
WebAppsがどんなに楽で便利かよく分かりました。
(VMSSでブルーグリーンデプロイメントとかもっと大変そうです・・・)
とはいえ、閉域網でVMが必要でオートスケーリングが必要なケースもあると思います。
その場合はVMSSを選択肢に入れてみてはいかがでしょうか(でもやっぱりレアかな・・・)
追記:2018/02/07
VMSSのインスタンスタイプやディスクタイプを指定して起動させる
VMSSの料金計算してて、そういえばディスクサイズってどうなんだろうと思って調べました。
デフォルトだとManagedDiskのStandard_LRSが設定されるようです。
なので、Windowsを初期イメージから立ち上げた場合は、S10(128GB)の使用量だけが料金として発生するということですね。
インスタンスタイプはStandard_D1_v2がデフォルトです。
では、インスタンスタイプとディスクタイプを指定してVMSSを作成してみます。
以下のように--vm-sku、--storage-skuオプションを付与します。
az vmss create \
-g $RESOURCE_GROUP \
-n $VMSS_NAME \
--nsg $NSG_NAME \
--load-balancer $LB_NAME \
--subnet $SUBNET_ID \
--image $IMAGE_ID \
--authentication-type password \
--admin-username $USER_NAME \
--admin-password $USER_PASS \
--backend-pool-name $BACKEND_POOL \
--instance-count 1 \
--vm-sku Standard_DS1_v2 \
--storage-sku Premium_LRS