Azure 在以前服務管理模式 (Service Management Mode) 下最大的問題之一就是無法快速佈建大量的虛擬機器,這個問題雖然在管理機制升級到資源管理模式 (Resource Management Mode) 後似乎有改善的狀況,但在 ARM 初期,只是改變了 VM 各資源的組成方式,沒有真正解決快速部署的問題,這個問題一直到 Azure 發表了虛擬機器擴展集 (VMSS) 後才真的得到解決,不過網路上用的幾乎都是使用 Resource Template 的作法,這篇文章要教授如何使用 Azure PowerShell 來做到這件事,而且還是用自訂的作業系統映像,而不是平台本身的。
虛擬機器擴展集 (Virtual Machine Scale Set) 是 Azure 轉進資源管理觀點之後的代表作之一,以往要佈建大量虛擬機器,只能使用 PowerShell 跑迴圈,或是用 REST API 寫程式呼叫的作法來處理,一台虛擬機器可能要花上 10-20 分鐘建置,若是要建個 100 台,那最少也要 1000 分鐘,等於要花上 41 個小時都不停,才能完成佈建,時間成本實在太高,VMSS 正式將這個問題解決了,它可以利用平行佈建的方式,一次快速佈建很多虛擬機器,經過我的實測,以 PowerShell 指令方式佈建 10 台 VM,要花上 1 個多小時,而使用 VMSS,只要約 20 分鐘。
VMSS 是以 ARM (Azure Resource Management) 範本為基礎的技術,早期它還在 Preview 的時候,看到的教學幾乎都是編輯範本,即使到現在,微軟官方還是建議以範本方式處理,但是 ARM 範本的 JSON 結構複雜 (不是因為 JSON 本身,而是資源類型太多了,還有相依性之類的要管理),微軟雖然也釋出了像 Azure Resource Explorer、Visual Studio 的 Azure Resource Template、在入口網站直接能看到資源轉成的 Resource Template 等工具,但是仍然無法降低它的門檻。所幸微軟還是有提供 REST API 以及指令如 Azure PowerShell 和 Azure CLI 等佈建 VMSS 的作法。VMSS 是一個能快速佈建多虛擬機器的環境,因此它會有一些需求,像是它要求要有一個虛擬網路與子網路 (用來部署虛擬機器);一個負載平衡器以及一個對外的公用 IP 等,有了這些才能開始佈建 VMSS。
首先,請先用 PowerShell 登入 Azure,指令為 Login-AzureRmAccount
,若你的 Azure 帳戶有使用多個訂閱,而且登入的預設訂閱不是你要用的,請再使用 Select-AzureRmSubscription
切換到你想使用的訂閱,接著,請按下列步驟進行。
1. 建立一個資源群組,這個資源群組會在後面經常使用到。
$groupName = "vmssgroup"
$location = "eastasia"
$group = New-AzureRmResourceGroup -Name $groupName -Location $location -Force
2. 建立虛擬網路,本文使用的位址空間是 10.0.0.0/8,子網路的位址空間則是 10.1.0.0/16,可容納超過 1000 台虛擬機器。
$subnetName = 'vmsubnet'
$subnet = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix "10.1.0.0/16"
$vnetName = 'vmssnetwork'
$vnet = New-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $groupName -Location $location -AddressPrefix "10.0.0.0/8" -Subnet $subnet
$vnet = Get-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $groupName
$subnetId = $vnet.Subnets[0].Id
3. 建立一個公用 IP 位址,它會用在待會建立的負載平衡器的對外介面上,且若沒有這個 IP,除非使用 VPN 連到虛擬網路,否則無法由外界存取。
$publicIp = New-AzureRmPublicIpAddress -Name "vmssnetpip" -ResourceGroupName $groupName -Location $location -AllocationMethod Dynamic -DomainNameLabel "testingvm"
$publicIp = Get-AzureRmPublicIpAddress -Name "vmssnetpip" -ResourceGroupName $groupName
4. 建立負載平衡器,負載平衡器需要的設定比較多,包括對公用網路的組態 (Front-end IP Configuration)、對私人網路的位址池 (Backend Address Pool)、輸入 NAT 池 (Inbound NAT Pool)。
公用網路的組態,要將剛才建的公用 IP 設定繫結起來,而私人網路的位址池,只要給它個名稱就好,後面會有子網路的關聯。
$frontAddressConfig = New-AzureRmLoadBalancerFrontendIpConfig -Name "vmsslb-frontpool" -PublicIpAddress $publicIp
$backAddressPool = New-AzureRmLoadBalancerBackendAddressPoolConfig -Name "vmsslb-backpool"
接著是輸入 NAT 池,可在這裡定義公用網路與私人網路的埠對應。在這裡我定義 3000-3999,共 1000 個埠,對應到內網的 Port 3389,也就是允許外面使用 RDP 協定連到 VMSS 內的 VM。
$inboundNatPool = New-AzureRmLoadBalancerInboundNatPoolConfig -Name "vmsslb-inboundnatpool" -FrontendIpConfigurationId $frontAddressConfig.Id -FrontendPortRangeStart 3000 -FrontendPortRangeEnd 3999 -Protocol Tcp -BackendPort 3389
接下來,就可以建立負載平衡器了。
$lb = New-AzureRmLoadBalancer -Name "vmsslb" -ResourceGroupName $groupName -Location $location -FrontendIpConfiguration $frontAddressConfig -BackendAddressPool $backAddressPool -InboundNatPool $inboundNatPool
$lb = Get-AzureRmLoadBalancer -Name "vmsslb" -ResourceGroupName $groupName
5. 設定 VMSS 虛擬機的網路位址來源組態,VMSS 會依照虛擬機器的順序配給 IP,以及前面定義的公用網路埠號。
$vmssIpConfig = New-AzureRmVmssIpConfig -Name "nic" -LoadBalancerInboundNatPoolsId $lb.InboundNatPools[0].Id -LoadBalancerBackendAddressPoolsId $lb.BackendAddressPools[0].Id -SubnetId $subnetId
6. 建立 VMSS 的組態,決定 VMSS 要部署在哪個位置 (資料中心)、內含的 VM 數量 (在本例是 10 台)、VM 等級 (在本例為 D1 v2) 以及更新原則。
$vmcount = 10
$vmssConfig = New-AzureRmVmssConfig -Location $location -SkuCapacity $vmcount -SkuName "Standard_D1_v2" -UpgradePolicyMode Automatic
7. 設定 VMSS 的網路介面組態,來源由前面設定的 VMSS 網路位址來源 IP 組態供應,這個設定會在每台 VM 上建立網路介面卡 (NIC)。
Add-AzureRmVmssNetworkInterfaceConfiguration -VirtualMachineScaleSet $vmssConfig -Name $subnetName -Primary $true -IpConfiguration $vmssIpConfig
8. 設定 VMSS 虛擬機器的作業系統基本設定,包含電腦名稱的前綴字、登入 VM 的帳戶名稱與密碼,帳戶名稱與密碼必須符合 Azure 的規範。
Set-AzureRmVmssOsProfile -VirtualMachineScaleSet $vmssConfig -ComputerNamePrefix "demovm" -AdminUsername "demouser" -AdminPassword "PaSS#W0Rd"
9. 設定 VMSS 的儲存設定,這個設定會指定映像的來源,以及每台 VM 的 OS Disk 的存放位置,目前 VMSS 要求映像來源和 OS Disk 的存放位置必須在同一個儲存帳戶內。
本文使用的是自訂的作業系統映像檔,因此要設定-Image
參數,指定作業系統映像檔的位置。
Set-AzureRmVmssStorageProfile -VirtualMachineScaleSet $vmssConfig -Image "https://myimagevhds.blob.core.windows.net/vhds/customosimage.vhd" -OsDiskCaching ReadWrite -OsDiskCreateOption FromImage -OsDiskOsType Windows -Name "vmssOsDisk"
若是要使用平台的映像檔,可參考微軟文件。
10. 設定 VMSS 虛擬機器的 VM Extensions,這個也可以不用,本文使用的是 BGInfo。
Add-AzureRmVmssExtension -VirtualMachineScaleSet $vmssConfig -Name "BGInfo" -Publisher "Microsoft.Compute" -Type "BGInfo" -TypeHandlerVersion "2.1"
11. 最後,使用前面的 VMSS 組態佈建 VMSS。
New-AzureRmVmss -Name "vmss" -ResourceGroupName $groupName -VirtualMachineScaleSet $vmssConfig
在佈建的過程中,可以到 Azure Portal 去看,可看到 VMSS 會一次部署指定數量的 VM,而不像以往 PowerShell 那樣一個一個建。
若需要一次停止所有的 VMSS 內的 VM,可使用下列指令。
Stop-AzureRmVmss -VMScaleSetName "vmss" -ResourceGroupName $groupName
References:
Creating Virtual Machine Scale Sets using PowerShell cmdlets