从自定义映像创建 Azure VM

Creating Azure VM from custom image

我在 Azure 中存储了一个映像,我想从中启动多个 VM。我已经创建了一个模板,它将为我创建必要的资源,并且除了 VM 创建之外,所有这些都成功了。

使用 CreateOption.FromImage 运行部署大约 40 分钟,直到出现错误:

'OS Provisioning for VM 'vmName' did not finish in the allotted time. However, the VM guest agent was detected running. This suggests the guest OS has not been properly prepared to be used as a VM image (with CreateOption=FromImage). To resolve this issue, either use the VHD as is with CreateOption=Attach or prepare it properly for use as an image

CreateOption.FromImage 更改为 CreateOption.Attach 会立即出现以下错误:

Cannot attach an existing OS disk if the VM is created from a platform or user image.

我想通过模板实现的目标:

  1. 指向主图像
  2. 为主副本提供所需的目的地
  3. 将主图像复制到目标
  4. 创建虚拟机
  5. 将副本附加到 VM

下面是我用来部署的模板的 VM 部分:

{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[parameters('vmName')]",
  "location": "[resourceGroup().location]",
  "tags": {
    "displayName": "VirtualMachine"
  },
  "dependsOn": [
    "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]"
  ],
  "properties": {
    "osProfile": {
      "computerName": "[parameters('vmName')]",
      "adminUsername": "[parameters('adminUsername')]",
      "adminPassword": "[parameters('adminPassword')]"
    },
    "hardwareProfile": {
      "vmSize": "[variables('vmSize')]"
    },
    "storageProfile": {
      "osDisk": {
        "name": "[parameters('OSDiskName')]",
        "osType": "windows",
        "caching": "ReadWrite",
        "createOption": "FromImage",
        "image": {
          "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/', parameters('sourceStorageContainerName'), '/', parameters('sourceVHDName'), '.vhd')]"
        },
        "vhd": {
          "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/', parameters('vhdStorageContainerName'), '/', parameters('OSDiskName'), '.vhd')]"
        }
      }
    },
    "networkProfile": {
      "networkInterfaces": [
        {
          "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]"
        }
      ]
    }
  }
}

'OS Provisioning for VM 'vmName' did not finish in the allotted time. However, the VM guest agent was detected running. This suggests the guest OS has not been properly prepared to be used as a VM image (with CreateOption=FromImage). To resolve this issue, either use the VHD as is with CreateOption=Attach or prepare it properly for use as an image

如果您使用未经系统准备的映像创建 VM,可能会导致错误,因此请确保您的映像经过系统准备。

Cannot attach an existing OS disk if the VM is created from a platform or user image.

当您将 CreateOption 指定为 Attach(它将从专用磁盘创建虚拟机)时,请不要指定 SourceImageUri 参数。有关更多信息,请查看 this documentation.

中的“-CreateOption”

正如 Fei Han 所说,您的机器看起来不是通用化的(VM 的通用化通过创建通用映像来准备它,这意味着它删除了特定于实例的数据(路径、注册表项等)。

要通用化机器,您可以 运行 上面的脚本 (警告!这将使您无法再使用此 VM)

if( Test-Path $Env:SystemRoot\System32\Sysprep\unattend.xml ){ 
    rm $Env:SystemRoot\System32\Sysprep\unattend.xml -Force
}

& $env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /quiet /quit

while($true) { 
    $imageState = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State | Select ImageState; 

    if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { 
        Write-Output $imageState.ImageState; Start-Sleep -s 10  
    } else {
        break
    }
}

但是,我尝试在 Azure 门户中从这样的 VM(已经反序列化)创建 Azure 映像,我遇到了同样的错误。这就是为什么,我明确地将它传递给命令以将我的 VM 视为通用的:

$rgName = "rg-my-images"
$location = "Your Region"
$imageName = "vmimg-name-of-your-image"
$osVhdUri = "https://xxxxx.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.[ID of your image].vhd"


$imageConfig = New-AzImageConfig -Location $location
$imageConfig = Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized -BlobUri $osVhdUri
$image = New-AzImage -ImageName $imageName -ResourceGroupName $rgName -Image $imageConfig