从模板克隆时如何将磁盘添加到 VM?

How to add a disk to VM when cloning from a template?

我找到了有关如何将磁盘添加到现有 VM 的 pyvmomi 示例,但我想自定义 VM 模板,然后进行克隆。设置 CPU 和内存非常简单,但是除了引导磁盘之外,向现有模板添加一个或多个磁盘,这让我望而却步。

# Add an additional 200 GB disk
new_disk_kb = int(20) * 1024 * 1024
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
disk_spec.device.backing.diskMode = 'persistent'
disk_spec.device.unitNumber = 3
disk_spec.device.capacityInKB = new_disk_kb

# vm configuration
vmconf = vim.vm.ConfigSpec()
vmconf.numCPUs = 8            # change the template's cpus from 4 to 8
vmconf.memoryMB = 16 * 1024   # change the template's memory from 4 GB to 16 GB
# change the template's disks from
#    1 250 GB boot, 1 x 200 GB disk
# to 
#    1 250 gB boot, 2 x 200 GB disks
vmconf.deviceChange = [ disk_spec ]  # something is not right
                               
clonespec = vim.vm.CloneSpec()
clonespec.location = relospec
clonespec.powerOn = True
clonespec.config = vmconf
clonespec.customization = customspec
task = template.Clone(folder = destfolder, name = vmname, spec = clonespec)

代码在没有 vmconf.deviceChange 的情况下也能正常工作。尝试添加磁盘后,我看到错误

Invalid configuration for device '0'.

Incompatible device backing specified for device '0'.

您收到的错误似乎表明您需要修复 unit_number。请记住,7 是为 scsi 控制器保留的 16 是 VMWare 支持的最大磁盘数(查看 sample code) .

我不熟悉 pyvmomi 工具,但在我看来,磁盘应该连接到 控制器 。如果没有控制器为设备供电,则 UnitNumber 没有意义。

When associating virtual devices with default devices, the controllerKey property should be reset with the key property of the controller [ here ]

你能试试上面的联想吗? (抱歉,我不太确定你应该使用 vmconf 还是 clonespec.config

controller = next( \
 (device for device in vmconf.hardware.device \
     if isinstance(device, vim.vm.device.VirtualSCSIController) \
 ), None)
disk_spec.device.controllerKey = controller.key

这个问题有多个移动部分,包括创建模板、修改模板和克隆 VM。

让我们先解决最简单的问题。您的这部分代码不正确:

new_disk_kb = int(20) * 1024 * 1024
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
disk_spec.device.backing.diskMode = 'persistent'
disk_spec.device.unitNumber = 3
disk_spec.device.capacityInKB = new_disk_kb

查看多个 pyvmomi 示例脚本后,我发现您没有正确设置 unitNumber。根据这些脚本,您需要确定磁盘数量并分配下一个 unitNumber 可用,我假设您的情况是 2 而不是 3.

下面的代码是从 add raw disk to vm pyvmomi 脚本中提取的。

spec = vim.vm.ConfigSpec()
# get all disks on a VM, set unit_number to the next available
unit_number = 0
controller = None
for device in vm.config.hardware.device:
    if hasattr(device.backing, 'fileName'):
        unit_number = int(device.unitNumber) + 1
        # unit_number 7 reserved for scsi controller
        if unit_number == 7:
            unit_number += 1
        if unit_number >= 16:
            print("we don't support this many disks")
            return -1
    if isinstance(device, vim.vm.device.VirtualSCSIController):
        controller = device
if controller is None:
    print("Disk SCSI controller not found!")
    return -1
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
rdm_info = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
disk_spec.device.backing = rdm_info
disk_spec.device.backing.compatibilityMode = disk_compatibility_mode
disk_spec.device.backing.diskMode = disk_mode
# The device_name will look something like
#     /vmfs/devices/disks/naa.41412340757396001d7710df0fdd22a9
disk_spec.device.backing.deviceName = device_name
disk_spec.device.unitNumber = unit_number
disk_spec.device.controllerKey = controller.key
spec.deviceChange = [disk_spec]

关于您想解决的其他问题。有几个 pyvmomi script that could be useful. One in particular is Clone VM,它提供了有关从您尝试创建的模板克隆 VM 的详细信息。

我不确定该脚本会有多大用处,因为您似乎正在寻找一个完整的解决方案来解决您的用例。

我建议查看这个旧的 Github project,它有很多用于创建模板、修改模板和克隆 VM 的有用代码。

关于您对使用已有一个磁盘(引导磁盘)的现有模板并在克隆过程中添加辅助磁盘的意见。

根据我对 VM 文档的解释,我目前认为这不可能,原因如下:

  1. VM 模板是虚拟机的主副本映像,包括 VM 磁盘、虚拟设备和设置。此模板可用于 VM 克隆过程。此模板是静态的,应被视为配置基准。

  2. 克隆过程中无法修改此模板。如果出于任何原因需要修改此静态模板,则需要使用新添加的内容重新创建它。这意味着需要将原始模板转换为VM,需要编辑此VM,然后再转换回新模板。

如果这不可能,您可以在新 VM 上克隆基线模板并使用 pyvmomi 添加磁盘 scripts 之一在您的 VM 上启用新磁盘。

我不知道你的确切用例,但我认为重新创建模板是合乎逻辑的选择,但你的用例可能更适合在克隆后创建新磁盘。

我之前提到的那个 GitHub 项目是使用基准模板克隆虚拟机,它也有一个 addDisks 功能。后者用于将新磁盘添加到在克隆过程中创建的 VM。

这是一个较旧的 pyvmomi issue,其中有人想要修改与正在克隆的模板相关的磁盘。建议 OP 在 post-clone 过程中执行此任务。

那个 GitHub 项目展示了如何使用基线模板并根据需要修改 VM 配置。从代码看来,它在克隆过程中使用 CloneSpec() 来修改 VM,而不是 post-clone 过程。

问题似乎出在代码的以下部分:

# Add an additional 200 GB disk
new_disk_kb = int(20) * 1024 * 1024
disk_spec = vim.vm.device.VirtualDeviceSpec()
disk_spec.fileOperation = "create"
disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
disk_spec.device = vim.vm.device.VirtualDisk()
disk_spec.device.backing = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()
disk_spec.device.backing.diskMode = 'persistent'
disk_spec.device.unitNumber = 2
disk_spec.device.capacityInKB = new_disk_kb

如果虚拟机已经有磁盘,启动磁盘,那么unitNumber应该从2开始。

我只是 运行 解决了这个将 RDM 磁盘添加到虚拟机的确切问题。

问题是:

disk_spec.device.backing = vim.vm.device.VirtualDisk.RawDiskMappingVer1BackingInfo()

您需要根据您的规范提供 backing.deviceName 和 backing.lunUuid。之后它会起作用。我有信心,因为我看到了完全相同的错误消息并且它为我修复了它。

您从 host.config.storageDevice.scsiLun 获取您感兴趣的 lun 的 lun uuid 和 deviceName。