如何将 Azure 托管磁盘克隆到不同的订阅中?

Posted

技术标签:

【中文标题】如何将 Azure 托管磁盘克隆到不同的订阅中?【英文标题】:How do I clone an Azure Managed Disk into a different subscription? 【发布时间】:2017-07-23 04:21:59 【问题描述】:

使用 Azure VM 和托管磁盘(使用 ARM 部署模型),我最近遇到了以下我想解决的问题:为了从托管磁盘中获取生产数据以进行测试,我想将生产数据磁盘从“生产订阅”克隆到“开发订阅”的托管磁盘中,我可以在其中安全地使用数据。

我们正在谈论大量数据(200 GB+),因此实际的“复制”过程将花费太多时间。我希望能够在半小时内实现自动化并提供新环境。

在订阅中克隆托管磁盘(假设它位于同一区域)非常简单快捷,我只需为 az disk create 命令指定一个 --source。这显然不适用于订阅,至少因为开发订阅的登录用户/服务主体无权访问生产订阅资源。

到目前为止我所尝试的:

使用az disk grant-access 检索托管磁盘的SAS URI;这个东西不被接受为 --sourceaz disk create 虽然(它说 VHD SAS 链接虽然可以工作......)

有什么想法吗?

【问题讨论】:

好吧,授予用户访问权限? 当相关用户是服务主体时,必须尝试这是否有效。怀疑它,因为那些属于订阅 afaik。 我很惊讶 sas uri 不能跨订阅工作 - 当您尝试运行 cmd 时磁盘是否在线?您可以在多个 subs 中授予 SP 权限(至少在同一个租户中,不确定跨租户)。另一种选择是尝试模板部署。 你可以通过PowerShell来完成,请参考这个link找到Start-AzureStorageBlobCopy 为服务主体授予对订阅的访问权限,即将其添加到订阅的角色中,是关键。太简单了。 【参考方案1】:

我这样做了:

$RG = "youresourcegroup"
$Location = "West US 2"
$StorageAccName = "yourstorage"
$SkuName = "Standard_LRS"
$Containername = "images"
$Destdiskname = “yorblob.vhd”
$SourceSASurl = "https://yoursaasurl"

Login-AzureRmAccount

New-AzureRmResourceGroup -Name $RG -Location $Location
New-AzureRmStorageAccount -ResourceGroupName $RG -Name $StorageAccName -SkuName $SkuName -kind Storage -Location $Location 

$Storageacccountkey = Get-AzureRmStorageAccountKey -ResourceGroupName $RG -Name $StorageAccName
$Storagectx = New-AzureStorageContext -StorageAccountName $StorageAccName -StorageAccountKey $Storageacccountkey[0].Value

$Targetcontainer = New-AzureStorageContainer -Name $Containername -Context $storagectx -Permission Blob


$sourceSASurl = $mdiskURL.AccessSAS
$ops = Start-AzureStorageBlobCopy -AbsoluteUri $SourceSASurl -DestBlob $Destdiskname -DestContainer $Containername -DestContext $Storagectx
Get-AzureStorageBlobCopyState -Container $Containername -Blob $Destdiskname -Context $Storagectx -WaitForComplete

在此之后,您将在订阅中获得托管磁盘的副本,该副本存储为常规 blob。

请注意,您应该从生产订阅获取 SAS URL,但在脚本中您应该登录到开发订阅。

接下来,您可以转到 Azure 门户并将 blob 转换为托管磁盘。

    转到 Azure 门户 --> 更多服务 --> 磁盘或直接浏览此 URL https://portal.azure.com/#create/Microsoft.ManagedDisk-ARM

    点击+添加

    选择源作为存储 blob

    使用源 blob 字段选择您的 vhd。

【讨论】:

【参考方案2】:

这是我编写的脚本,用于将每个 VM 的所有托管磁盘从一个订阅迁移到另一个订阅。希望对您有所帮助。

# This script will get ALL VMs in a subscription and then migrate the disks 
if the VM has managed disks
# Created by Joey Brakefield -- @kfprugger & https://www.linkedin.com/in/joeybrakefield/

#set global variables
$sourceSubscriptionId='6a1b5e5e-df06-4608-a7a2-6984f7abacd8'
select-azurermsubscription -subscriptionid $sourceSubscriptionId
$vms = get-azurermvm
$targetSubscriptionId='929e0340-bf36-45a2-8347-47f86b4715de'


#looping logic for each of the VMs that have managed disks
foreach ($vm in $vms) 
select-azurermsubscription -subscriptionid $sourceSubscriptionId

$vmrg = get-azurermresourcegroup -name $vm.ResourceGroupName
$vmname = $vm.name

Write-Host = "Working with: " $vmname " in " $vmrg -foregroundcolor Green 
Write-Host ""

#This command will only target managed disks because unmanaged use the storage account locations rather than the /disks provider URIs

if (Get-AzureRmDisk | ? $_.OwnerId -like "/subscriptions/"+$sourceSubscriptionId +"/resourceGroups/"+$vmrg.resourcegroupname+"/providers/Microsoft.Compute/virtualMachines/"+$vm.name)

#Sanity Check
#Read-host "Look correct? If not, CTRL-C to Break"
$manageddisk =  Get-AzureRmDisk | ? $_.OwnerId -like "/subscriptions/"+$sourceSubscriptionId +"/resourceGroups/"+$vmrg.resourcegroupname+"/providers/Microsoft.Compute/virtualMachines/"+$vm.name
Select-AzureRmSubscription -SubscriptionId $targetSubscriptionId
#check to see if RG exists in the new CSP/Subscription 

Get-AzureRmResourceGroup -Name $vmrg.resourcegroupname -ev notPresent -ea 0
write-host "Checking to see if"$vmrg.resourcegroupname"exists in subscriptionid"$targetSubscriptionId -foregroundcolor Cyan
Write-Host ""
if ($notPresent)

    new-azurermresourcegroup -name $vmrg.resourcegroupname -location $vmrg.location
    "Resource Group " + $vmrg.resourcegroupname + " has been created"
     else "Resource Group " + $vmrg.resourcegroupname +  " already exists"
    # Move the disks after all checks are done
    foreach ($disk in $managedDisk)
        $managedDiskName = $disk.Name
        $targetResourceGroupName = $vmrg.resourcegroupname

        $diskConfig = New-AzureRmDiskConfig -SourceResourceId $disk.Id -Location $disk.Location -CreateOption Copy 

        New-AzureRmDisk -Disk $diskConfig -DiskName $Disk.Name -ResourceGroupName $targetResourceGroupName


【讨论】:

【参考方案3】:

您可以在 Azure CLI 中使用以下命令 -

# Source storage account name
STORAGE1=sourcestorage

#Security key of the source storage account
STORAGEKEY1= SampleKey0qNzttE/EX3hHfcFIzkQQmqXklRU2Z2uANICw==

#Container containing the source VHD
CONTAINER1=sourcevhds

# Name of VHD to be copied (name only, not full url)
DISK=DiskToBeCopied.vhd

#Specify the above properties for target
STORAGE2=targetstorage
STORAGEKEY2= SampleKeyAb6FYP3EqFVEcN2cc5wO QHzXvdc7Gzh1qRt0FXKq6w==
CONTAINER2= targetvhds

设置好以上参数后,在Azure CLI中执行以下命令——

azure storage blob copy start --account-name $STORAGE1 --account-key $STORAGEKEY1 --source-container $CONTAINER1 --source-blob $Disk --dest-account-name $STORAGE2 --dest-account-key $STORAGEKEY2 --dest-container $CONTAINER2

【讨论】:

以上是关于如何将 Azure 托管磁盘克隆到不同的订阅中?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Powershell 中的快照创建 Azure 托管磁盘

如何备份 Azure 自定义托管映像

Azure Rest API 附加现有托管磁盘

在Azure中创建虚机映像

我们如何使用管道将azure devops中的应用程序部署到具有不同订阅和组织的azure app服务

Azure运维系列11:Azure托管磁盘转非托管磁盘