🚀 Azure VM 复制,告别本地下载! (feat. Azure CLI)

大家好!在处理云环境时,经常需要备份虚拟机 (VM),或者将特定时间点的 VM 完全复制以创建测试环境。

许多人使用的常见方法可能如下:

  1. 创建 VM 磁盘的快照。📸
  2. 将快照作为 VHD 文件下载到本地计算机。(⏳ 漫长等待…)
  3. 将下载的 VHD 文件再次上传到 Blob 存储。(😩 又一次漫长等待…)
  4. 使用上传的 VHD 创建新磁盘,然后使用该磁盘创建新 VM。

这个过程是不是有点奇怪?明明只是将 Azure 中的数据移动到 Azure 的另一个位置,为什么非要经过我的计算机呢?这种方式耗时,浪费我的计算机网络带宽和存储空间,并且中间发生错误的概率也更高。

所以今天!我将详细介绍一种非常智能的方法,完全跳过这个低效的过程,直接在 Azure 内部将快照复制到 Blob 以复制 VM,并附带 Azure CLI 脚本。

🤔 核心原理:本地中转 vs Azure 直通

如果说传统方法是从首尔到釜山却非要绕道济州岛(我的电脑)的飞机,那么今天介绍的方法就像乘坐 KTX 直达目的地。🚅

核心就是 `az storage blob copy start` 这个 Azure CLI 命令。这个命令的作用是指示 Azure:“Azure,请你直接将位于 A 位置(快照)的数据复制到 B 位置(Blob 存储)!” 数据将完全不经过我们的计算机,通过快速稳定的 Azure 内部网络直接移动。

这被称为服务器端复制 (Server-Side Copy),它具有以下巨大优势:

  • ⚡️ 速度: 比本地网络速度快得多,无法比拟。
  • 👍 效率: 完全不占用我的计算机资源(CPU、网络、磁盘)。
  • 🔒 稳定性: 无需担心中间网络中断,稳定地复制大容量文件。

📜 完整脚本大公开!

百闻不如一见,对吧?下面是自动化所有这些过程的完整 Bash 脚本。您可以直接复制使用。

#!/bin/bash

# --- 用户配置变量 ---
# 请准确输入已创建的资源名称。
resourceGroup="gasbugs_group"      # 资源组
vmName="gasbugs"                   # 原始虚拟机
storageAccount="storageaccountgasbugs0" # 存储VHD的存储账户
containerName="blob-test"          # 存储VHD的容器

# 请根据需要设置新资源的名称。
snapshotName="new-snapshot-$(date +%s)" # 快照名称(为防止重复添加时间戳)
newDiskName="new-disk-$(date +%s)"      # 新磁盘名称
newVmName="new-vm-$(date +%s)"          # 新虚拟机名称

# --- 脚本执行 ---
echo ">> 1. 원본 VM의 OS 디스크 ID를 가져옵니다..."
osDiskId=$(az vm show --resource-group $resourceGroup --name $vmName --query "storageProfile.osDisk.managedDisk.id" -o tsv)
if [ -z "$osDiskId" ]; then echo "오류: OS 디스크 ID를 찾을 수 없습니다."; exit 1; fi
echo "   - OS Disk ID: $osDiskId"

echo -e "
>> 2. OS 디스크의 스냅샷을 생성합니다..."
az snapshot create --resource-group $resourceGroup --name $snapshotName --source $osDiskId
echo "   - 생성된 스냅샷: $snapshotName"

echo -e "
>> 3. 스냅샷에 접근할 수 있는 임시 SAS URL을 생성합니다..."
snapshotUrl=$(az snapshot grant-access --duration-in-seconds 3600 --name $snapshotName --resource-group $resourceGroup --query "accessSas" -o tsv)
echo "   - SAS URL이 성공적으로 생성되었습니다."

echo -e "
>> 4. 스냅샷을 Blob Storage로 서버 측 복사를 시작합니다 (로컬 다운로드 없음)..."
# 要复制的Blob的完整URL
sharedVhdUrl="https://$storageAccount.blob.core.windows.net/$containerName/$snapshotName.vhd"

az storage blob copy start 
    --account-name $storageAccount 
    --destination-blob "$snapshotName.vhd" 
    --destination-container $containerName 
    --source-uri $snapshotUrl

# 检查状态直到复制完成。
while true; do
    copy_status=$(az storage blob show --account-name $storageAccount --container-name $containerName --name "$snapshotName.vhd" --query "properties.copy.status" -o tsv)
    echo "   - 복사 상태: $copy_status"
    if [ "$copy_status" == "success" ]; then
        echo "   - Blob 복사가 완료되었습니다."
        break
    elif [ "$copy_status" == "failed" ]; then
        echo "오류: Blob 복사에 실패했습니다."
        exit 1
    fi
    sleep 15
done

echo -e "
>> 5. 스냅샷의 SAS URL 접근 권한을 해제합니다..."
az snapshot revoke-access --name $snapshotName --resource-group $resourceGroup

echo -e "
>> 6. 복사된 VHD Blob을 소스로 하여 새 관리 디스크를 생성합니다..."
az disk create --resource-group $resourceGroup --name $newDiskName --source $sharedVhdUrl
echo "   - 생성된 디스크: $newDiskName"

echo -e "
>> 7. 생성된 디스크를 사용하여 새 가상 머신을 생성합니다..."
az vm create --resource-group $resourceGroup --name $newVmName --attach-os-disk $newDiskName --os-type Linux --public-ip-address "" # 不带公共IP创建
echo "   - 생성된 VM: $newVmName"

echo -e "
✅ 모든 작업이 성공적으로 완료되었습니다."

###

🔬 脚本详细分析

我们来详细了解一下脚本是如何一步步运行的吧?

第1步:变量设置 ⚙️

在脚本顶部,设置要复制的目标 VM、资源组、存储 VHD 的存储账户等基本信息。为了防止多次运行脚本时名称重复,新创建的资源名称中添加了 `$(date +%s)`,以当前时间为基准创建唯一名称。

第2步:创建快照 📸

通过 `az vm show` 获取源 VM 的 OS 磁盘 ID 后,使用 `az snapshot create` 命令创建磁盘的特定时间点副本,即快照。

第3步:生成 SAS URL 🔑

`az snapshot grant-access` 扮演着非常重要的角色。它会生成一个包含临时密钥的 URL,该密钥允许在恰好 1 小时(3600 秒)内访问已创建的快照数据,即 SAS(共享访问签名)URL。这个 URL 就是我们数据的“直通票”。

第4步:服务器端复制和状态检查 ☁️➡️☁️

这是脚本的亮点!`az storage blob copy start` 命令将刚刚创建的 SAS URL 作为 `–source-uri`,并将目标 Blob 信息作为 `–destination-blob` 等参数传递。

命令执行后,Azure 会立即在后台开始复制。但是,我们需要等待复制完成才能进行下一步操作,对吧?因此,我们使用 `while` 循环,每隔 15 秒通过 `az storage blob show` 命令检查复制状态。当状态变为 `success` 时,循环退出并进入下一步。是不是很智能?

第5-7步:解除权限和创建资源 🏗️

复制完成后,为了安全起见,立即使用 `az snapshot revoke-access` 撤销 SAS URL。现在,以安全存储在 Blob 存储中的 VHD 文件的 URL 为源,执行 `az disk create` 创建新的托管磁盘。最后,使用此磁盘作为 OS 磁盘,通过 `az vm create` 创建最终的复制 VM,所有过程就完成了!

✨ 总结

现在,您无需再每次复制或备份 VM 时都将 VHD 文件下载到本地并上传,浪费时间。利用今天学到的服务器端复制方法,只需执行一次 Azure CLI 脚本,即可快速稳定地自动化整个过程。

您不妨利用此脚本创建自己的 VM 备份系统,或快速搭建开发/测试环境?


标签: Azure, VM, Virtual Machine, Snapshot, Blob, Storage, Azure CLI, Bash, Script, DevOps, IaC, Cloud, IT


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注