自动调整 Azure VM 大小的简便方法
Easy way to resize azure VM automatically
我们在 Azure 上有一个 VM,这个 VM 是一个 20 核的,非常昂贵。该虚拟机供公司的代理使用,工作时间为早上 8 点到下午 5 点。过了这个时间,就基本没用了
我想尝试通过在 5:10pm 之后将此虚拟机大小调整为 2 核大小并在 7:50am 上将其大小调整回 20 核来尝试降低成本。我已经手动执行此操作一个多星期了,这似乎节省了一大笔钱。
问题是我正在手动执行此操作,我想自动执行此操作。
我一直在读到,如果我配置了可用性集,就可以完成此操作。但是当创建这个虚拟机时,由于某种原因没有可用性集,需要重新创建虚拟机才能拥有一个,但这不是一个选项。
也许我可以使用 powershell 来做到这一点?我对 powershell 有非常基本的了解,所以我不知道如何做到这一点。
如果我可以创建一个 powershell 脚本并在特定时间使用 windows 到 运行 的计划任务,那就太好了。
要更改机器大小,您可以 运行 powershell
Get-AzureVM -ServiceName "MySvc1" -Name "MyVM3" | Set-AzureVMSize "Small" | Update-AzureVM
Here is example如何实现自动化。
但是如果你 运行 调整大小命令机器将重新启动,这也是一个问题,所以如果你使用一台机器,你将在一段时间内不会处理任何东西。
我还建议您查看 webjobs with queue。它会给你处理的灵活性
- 您将能够根据需求自动缩放(因此您将选择基本大小,一旦 cpu 使用量增长,您可以说再添加一个节点等等,如果 cpu减少 azure 将击落节点)
- 您可以使用队列来推送任务,webjob 会自动获取。
除非您先禁用加速网络,否则无法获得某些 VM 大小。
如果你像我一样,希望尽可能启用加速网络,只在不启用时禁用它,我将以下 powershell 模块放在一起,用于自动处理缩放 VM 并在必要时禁用加速网络。
param
(
[Parameter (Mandatory = $true)]
[object] $ResourceGroupName,
[Parameter (Mandatory = $true)]
[object] $VMName,
[Parameter (Mandatory = $true)]
[object] $NewVMSize
)
Function Get-TimeStamp {
return "[{0:yyyy-MM-dd} {0:HH:mm:ss}]" -f (Get-Date)
}
Write-Output "$(Get-TimeStamp) Importing Modules"
Import-Module -Name Az.Automation
Import-Module -Name Az.Compute
Import-Module -Name Az.Network
Import-Module -Name Az.Resources
Write-Output "$(Get-TimeStamp) Validating Arguments"
if (-Not $ResourceGroupName) {
Write-Error "$(Get-TimeStamp) Runbook was missing the expected ""ResourceGroupName"" property. Args were: $args"
exit 0
}
if (-Not $VMName) {
Write-Error "$(Get-TimeStamp) Runbook was missing the expected ""VMName"" property. Args were: $args"
exit 0
}
# Set the current automation connection's authenticated account to use for future Azure Resource Manager cmdlet requests.
Write-Output "$(Get-TimeStamp) Obtaining Service Principle Connection..."
$ServicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
Connect-AzAccount -ServicePrincipal -ErrorAction Stop `
-TenantId $ServicePrincipalConnection.TenantId `
-ApplicationId $ServicePrincipalConnection.ApplicationId `
-CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint | Write-Verbose
Set-AzContext -Subscription $ServicePrincipalConnection.SubscriptionID -ErrorAction Stop | Write-Verbose
Write-Output "$(Get-TimeStamp) Logged in as AzureRunAsConnection Service Principle"
# Get the VM to be scaled up or down
Write-Output "$(Get-TimeStamp) Retrieving VM Information"
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName -ErrorAction Stop
# Check if the VM already has the requested configuration
if ($vm.HardwareProfile.VmSize -eq $NewVMSize) {
Write-Output "$(Get-TimeStamp) Nothing to do! The VM already has the configuration $NewVMSize"
exit 1
}
# Collect information about the VM's network configuration
Write-Output "$(Get-TimeStamp) Retrieving Network Interface Information..."
$nic = Get-AzNetworkInterface -ResourceId $vm.NetworkProfile.NetworkInterfaces[0].id -ErrorAction Stop
try {
# Change the configuration
Write-Output "$(Get-TimeStamp) Changing VM Configuration..."
$vm.HardwareProfile.VmSize = $NewVMSize
Update-AzVM -VM $vm -ResourceGroupName $ResourceGroupName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Successfully updated the VM configuration to $NewVMSize"
} catch {
Write-Output "$(Get-TimeStamp) Handling error while changing VM Configuration..."
# Some VM configurations do not support accelerated networking. Try to correct that
if ($_.Exception.Message.Contains("VMSizeIsNotPermittedToEnableAcceleratedNetworking")) {
Write-Output "$(Get-TimeStamp) It appears as though the new VM Size was not accepted because it does not support Accelerated Networking."
Write-Output "$(Get-TimeStamp) Attempting to disable Accelerated Networking on the VM's network interface: $($nic.Name)..."
$nic.EnableAcceleratedNetworking = $False
try {
$nic | Set-AzNetworkInterface -ErrorAction Stop
} catch {
Write-Error "$(Get-TimeStamp) Error while disabling accelerated networking: $_"
throw
}
Write-Output "$(Get-TimeStamp) Done. Now trying to change the VM Configuration again..."
try {
Update-AzVM -VM $vm -ResourceGroupName $ResourceGroupName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Successfully updated the VM configuration to $NewVMSize"
} catch {
Write-Error "$(Get-TimeStamp) Unexpected error while updating the VM configuration after disabling accelerated networking: $_"
throw
}
} else {
Write-Error "$(Get-TimeStamp) Unexpected error while updating the VM configuration. Error code is: $($_.Exception.ErrorCode). Full Details: $_"
throw
}
} finally {
# Try to restore Accelerated Networking regardless of what actions succeeded/failed above
if (-Not $nic.EnableAcceleratedNetworking) {
Write-Output "$(Get-TimeStamp) Attempting to restore accellerated networking on the VM..."
try {
$nic.EnableAcceleratedNetworking = $True
$nic | Set-AzNetworkInterface -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Restored Accelerated Networking on the network interface: $($nic.Name)"
} catch {
# This is expected to fail if we have configured the VM to a size that does not support it.
Write-Output "$(Get-TimeStamp) Retrieving VM Information..."
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Accelerated Networking not supported on the network interface $($nic.Name) with the current VM size $($vm.HardwareProfile.VmSize)"
}
}
}
根据你的用例,你可能不需要服务原则的东西,我的是在 Azure Automation Runbook 中托管它。
发布本文时,这里有一些 VM 大小可供试用:
# SCALE UP: Here are the best-value memory optimized VM configurations as of 2021-01-01
# VM vCPUs RAM (GiB)
# Standard_E2as_v4 2 16
# Standard_E4as_v4 4 32
# Standard_E8as_v4 8 64
# Standard_E16as_v4 16 128
# Standard_E20as_v4 20 160
# Standard_E32as_v4 32 256
# Standard_E48as_v4 48 384
# Standard_E64as_v4 64 512
# Standard_E96as_v4 96 672 <- Note: sub-linear increase in RAM per cost makes this slightly worse value
#
# SCALE DOWN: Here are the lowest-cost VM configurations that meet the minimum-spec for windows 10
# VM vCPUs RAM (GiB) Cost/month
# Standard_B1ms 1 2 US.11
# Standard_B2s 2 4 US.37
# Standard_F1s 1 2 US.28
# Standard_DS1_v2 1 3.5 US.29
# Standard_DS1 1 3.5 US.21
# Standard_B2ms 2 8 US.74
# Standard_F2s_v2 2 4 US.76
# Standard_D2as_v4 2 8 US.08
# Standard_F2s 2 4 US.27
我们在 Azure 上有一个 VM,这个 VM 是一个 20 核的,非常昂贵。该虚拟机供公司的代理使用,工作时间为早上 8 点到下午 5 点。过了这个时间,就基本没用了
我想尝试通过在 5:10pm 之后将此虚拟机大小调整为 2 核大小并在 7:50am 上将其大小调整回 20 核来尝试降低成本。我已经手动执行此操作一个多星期了,这似乎节省了一大笔钱。
问题是我正在手动执行此操作,我想自动执行此操作。
我一直在读到,如果我配置了可用性集,就可以完成此操作。但是当创建这个虚拟机时,由于某种原因没有可用性集,需要重新创建虚拟机才能拥有一个,但这不是一个选项。
也许我可以使用 powershell 来做到这一点?我对 powershell 有非常基本的了解,所以我不知道如何做到这一点。
如果我可以创建一个 powershell 脚本并在特定时间使用 windows 到 运行 的计划任务,那就太好了。
要更改机器大小,您可以 运行 powershell
Get-AzureVM -ServiceName "MySvc1" -Name "MyVM3" | Set-AzureVMSize "Small" | Update-AzureVM
Here is example如何实现自动化。
但是如果你 运行 调整大小命令机器将重新启动,这也是一个问题,所以如果你使用一台机器,你将在一段时间内不会处理任何东西。
我还建议您查看 webjobs with queue。它会给你处理的灵活性
- 您将能够根据需求自动缩放(因此您将选择基本大小,一旦 cpu 使用量增长,您可以说再添加一个节点等等,如果 cpu减少 azure 将击落节点)
- 您可以使用队列来推送任务,webjob 会自动获取。
除非您先禁用加速网络,否则无法获得某些 VM 大小。
如果你像我一样,希望尽可能启用加速网络,只在不启用时禁用它,我将以下 powershell 模块放在一起,用于自动处理缩放 VM 并在必要时禁用加速网络。
param
(
[Parameter (Mandatory = $true)]
[object] $ResourceGroupName,
[Parameter (Mandatory = $true)]
[object] $VMName,
[Parameter (Mandatory = $true)]
[object] $NewVMSize
)
Function Get-TimeStamp {
return "[{0:yyyy-MM-dd} {0:HH:mm:ss}]" -f (Get-Date)
}
Write-Output "$(Get-TimeStamp) Importing Modules"
Import-Module -Name Az.Automation
Import-Module -Name Az.Compute
Import-Module -Name Az.Network
Import-Module -Name Az.Resources
Write-Output "$(Get-TimeStamp) Validating Arguments"
if (-Not $ResourceGroupName) {
Write-Error "$(Get-TimeStamp) Runbook was missing the expected ""ResourceGroupName"" property. Args were: $args"
exit 0
}
if (-Not $VMName) {
Write-Error "$(Get-TimeStamp) Runbook was missing the expected ""VMName"" property. Args were: $args"
exit 0
}
# Set the current automation connection's authenticated account to use for future Azure Resource Manager cmdlet requests.
Write-Output "$(Get-TimeStamp) Obtaining Service Principle Connection..."
$ServicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
Connect-AzAccount -ServicePrincipal -ErrorAction Stop `
-TenantId $ServicePrincipalConnection.TenantId `
-ApplicationId $ServicePrincipalConnection.ApplicationId `
-CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint | Write-Verbose
Set-AzContext -Subscription $ServicePrincipalConnection.SubscriptionID -ErrorAction Stop | Write-Verbose
Write-Output "$(Get-TimeStamp) Logged in as AzureRunAsConnection Service Principle"
# Get the VM to be scaled up or down
Write-Output "$(Get-TimeStamp) Retrieving VM Information"
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName -ErrorAction Stop
# Check if the VM already has the requested configuration
if ($vm.HardwareProfile.VmSize -eq $NewVMSize) {
Write-Output "$(Get-TimeStamp) Nothing to do! The VM already has the configuration $NewVMSize"
exit 1
}
# Collect information about the VM's network configuration
Write-Output "$(Get-TimeStamp) Retrieving Network Interface Information..."
$nic = Get-AzNetworkInterface -ResourceId $vm.NetworkProfile.NetworkInterfaces[0].id -ErrorAction Stop
try {
# Change the configuration
Write-Output "$(Get-TimeStamp) Changing VM Configuration..."
$vm.HardwareProfile.VmSize = $NewVMSize
Update-AzVM -VM $vm -ResourceGroupName $ResourceGroupName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Successfully updated the VM configuration to $NewVMSize"
} catch {
Write-Output "$(Get-TimeStamp) Handling error while changing VM Configuration..."
# Some VM configurations do not support accelerated networking. Try to correct that
if ($_.Exception.Message.Contains("VMSizeIsNotPermittedToEnableAcceleratedNetworking")) {
Write-Output "$(Get-TimeStamp) It appears as though the new VM Size was not accepted because it does not support Accelerated Networking."
Write-Output "$(Get-TimeStamp) Attempting to disable Accelerated Networking on the VM's network interface: $($nic.Name)..."
$nic.EnableAcceleratedNetworking = $False
try {
$nic | Set-AzNetworkInterface -ErrorAction Stop
} catch {
Write-Error "$(Get-TimeStamp) Error while disabling accelerated networking: $_"
throw
}
Write-Output "$(Get-TimeStamp) Done. Now trying to change the VM Configuration again..."
try {
Update-AzVM -VM $vm -ResourceGroupName $ResourceGroupName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Successfully updated the VM configuration to $NewVMSize"
} catch {
Write-Error "$(Get-TimeStamp) Unexpected error while updating the VM configuration after disabling accelerated networking: $_"
throw
}
} else {
Write-Error "$(Get-TimeStamp) Unexpected error while updating the VM configuration. Error code is: $($_.Exception.ErrorCode). Full Details: $_"
throw
}
} finally {
# Try to restore Accelerated Networking regardless of what actions succeeded/failed above
if (-Not $nic.EnableAcceleratedNetworking) {
Write-Output "$(Get-TimeStamp) Attempting to restore accellerated networking on the VM..."
try {
$nic.EnableAcceleratedNetworking = $True
$nic | Set-AzNetworkInterface -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Restored Accelerated Networking on the network interface: $($nic.Name)"
} catch {
# This is expected to fail if we have configured the VM to a size that does not support it.
Write-Output "$(Get-TimeStamp) Retrieving VM Information..."
$vm = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName -ErrorAction Stop
Write-Output "$(Get-TimeStamp) Accelerated Networking not supported on the network interface $($nic.Name) with the current VM size $($vm.HardwareProfile.VmSize)"
}
}
}
根据你的用例,你可能不需要服务原则的东西,我的是在 Azure Automation Runbook 中托管它。
发布本文时,这里有一些 VM 大小可供试用:
# SCALE UP: Here are the best-value memory optimized VM configurations as of 2021-01-01
# VM vCPUs RAM (GiB)
# Standard_E2as_v4 2 16
# Standard_E4as_v4 4 32
# Standard_E8as_v4 8 64
# Standard_E16as_v4 16 128
# Standard_E20as_v4 20 160
# Standard_E32as_v4 32 256
# Standard_E48as_v4 48 384
# Standard_E64as_v4 64 512
# Standard_E96as_v4 96 672 <- Note: sub-linear increase in RAM per cost makes this slightly worse value
#
# SCALE DOWN: Here are the lowest-cost VM configurations that meet the minimum-spec for windows 10
# VM vCPUs RAM (GiB) Cost/month
# Standard_B1ms 1 2 US.11
# Standard_B2s 2 4 US.37
# Standard_F1s 1 2 US.28
# Standard_DS1_v2 1 3.5 US.29
# Standard_DS1 1 3.5 US.21
# Standard_B2ms 2 8 US.74
# Standard_F2s_v2 2 4 US.76
# Standard_D2as_v4 2 8 US.08
# Standard_F2s 2 4 US.27