不使用 ASR 将虚机还原到另一个数据中心

时间:2022-04-26 00:35:06

背景

在 Azure 上可能会遇到一个场景是将一台虚机搬到另一台数据中心,在不借助 ASR 的情况下我们该如何做? 因为 ASR 在云上更多的场景是用于灾备到异地。对于虚机的相关信息主要的是磁盘和网络信息,所以我们可以通过 Powershell 对虚机的磁盘打 snapshot, 然后 copy 至 新的数据中心还原出来。

前提

  1. 安装 Azure 相关的 Module
    1. Import-Module AzureRM
  2. Azure 账号及 Powershell 登录
    1. Login-AzureRmAccount -EnvironmentName AzureChinaCloud
  3. 准备一套备迁移的虚机环境

步骤

  • 先对源机器停机
$rgName = "XXX"
$newRgName = "XXX"
$vmName = "XXX"
$location = "XXX"
$newLocation = "XXX"
$storageaccount = "XXX"
$storageaccountName = "XXX"
$storageType = 'Premium_LRS'
$virtualNetworkName = 'XXX'
$virtualMachineName = 'XXX'
$virtualMachineSize = 'Standard_DS2_v2'


Stop-AzureRmVM -ResourceGroupName $rgName -Name $vmName
  • 对源虚机的磁盘打 Snapshoot
$vm = get-azureRmVm -ResourceGroupName $rgName -Name $vmName
$OSDiskName=(Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName).StorageProfile.OsDisk.Name
$dataDiskNames = (Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName).StorageProfile.DataDisks.Name
$DiskNameArray = New-Object System.Collections.ArrayList
$DiskNameArray.add($OSDiskName)
$DiskNameArray.add($dataDiskNames)
$snapshotArray = New-Object System.Collections.ArrayList
foreach ($diskName in $DiskNameArray) {
    $Disk = Get-AzureRmDisk -ResourceGroupName $rgName -DiskName $diskName
    $SnapshotConfig = New-AzureRmSnapshotConfig -SourceUri $Disk.Id -CreateOption Copy -Location $Location
    $snapshotName = $diskName + "_SnapShot"
    $Snapshot=New-AzureRmSnapshot -Snapshot $snapshotConfig -SnapshotName $snapshotName -ResourceGroupName $rgName
    $snapshotArray.add($Snapshot)
}
  • 对源虚机开机
Start-AzureRmVM -ResourceGroupName $rgName -Name $vmName
  • 将 Snapshots 拷贝至另一数据中心
$destContext = New-AzureStorageContext -StorageAccountName $storageaccount -StorageAccountKey $storageaccountkey
$blobsArray = New-Object System.Collections.ArrayList
foreach($snapshot in $snapshotArray){
    $snapshotName = $snapshot.Name
    $sas = Grant-AzureRmSnapshotAccess -ResourceGroupName $rgName -SnapshotName $snapshotName -DurationInSecond 3600 -Access Read
    $destBlob = $snapshotName + ".vhd"
    $blob = Start-AzureStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestContainer $storageContainer -DestContext $destContext -DestBlob $destBlob
    $blobsArray.add($blob)
}
  • 对这些拷贝过来的 PageBlob 还原成新数据中心的管理磁盘
$newDisks = New-Object System.Collections.ArrayList
foreach($blob in $blobsArray){
    $blobUri = "https://" + $storageaccount + ".blob.core.chinacloudapi.cn/" + $storageContainer + "/" + $blob.Name
    $length = $blob.Name.Length
    $diskName = $blob.Name.substring(0, $length - 4)
    $diskConfig = New-AzureRmDiskConfig -AccountType $storageType -Location $newLocation -CreateOption Import -SourceUri $blobUri
    $newDisk = New-AzureRmDisk -Disk $diskConfig -ResourceGroupName $newRgName -DiskName $diskName
    $newDisks.add($newDisk)
}
  • 利用还原出来的管理磁盘以及新的数据中心的虚拟网络创建出虚机
$VirtualMachine = New-AzureRmVMConfig -VMName $virtualMachineName -VMSize $virtualMachineSize
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -ManagedDiskId $newDisks[0].Id -CreateOption Attach -Linux

$i = 0
foreach($newDisk in $newDisks){
    if($i -gt 0)
    {
        $VirtualMachine = Add-AzureRmVMDataDisk -VM $VirtualMachine -ManagedDiskId $newDisk.Id -CreateOption Attach -Lun 0 -Caching None
    }
    $i = $i + 1
}

$publicIp = New-AzureRmPublicIpAddress -Name ($VirtualMachineName.ToLower()+'_ip') -ResourceGroupName $newRgName -Location $newLocation -AllocationMethod Dynamic
$vnet = Get-AzureRmVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $newRgName
$nic = New-AzureRmNetworkInterface -Name ($VirtualMachineName.ToLower()+'_nic') -ResourceGroupName $newRgName -Location $newLocation -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $publicIp.Id
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $nic.Id
$newVM = New-AzureRmVM -VM $VirtualMachine -ResourceGroupName $newRgName -Location $newLocation

技能小贴士

  • 安装某一个特定版本的 AzureRm Module
Install-Module -Name AzureRM -RequiredVersion 6.8.1
  • 查看 AzureRM 的安装版本
Find-Module AzureRM
  • 查看 Powershell 中 AzureRM 模块调用出错异常堆栈
Resolve-AzureRmError -Last

提问????

  1. 是不是可以把原系统里的用户、hostname 等等带到新的数据中心?
  2. 是不是可以把原系统里的网络信息带到新的数据中心?
  3. 如何升级 AzureRM module 到某一特定版本?

Ref:

  1. https://docs.azure.cn/zh-cn/powershell-install-configure

  2. https://docs.microsoft.com/en-us/powershell/module/azurerm.compute/?view=azurermps-6.9.0#virtual_machines

  3. https://docs.microsoft.com/en-us/powershell/azure/uninstall-azurerm-ps?view=azurermps-6.9.0#uninstall-from-powershell