前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >使用 pyvmomi 从一个集群克隆虚拟机到另一个集群

使用 pyvmomi 从一个集群克隆虚拟机到另一个集群

原创
作者头像
华科云商小徐
发布2025-02-07 14:02:16
发布2025-02-07 14:02:16
5900
代码可运行
举报
文章被收录于专栏:小徐学爬虫小徐学爬虫
运行总次数:0
代码可运行

要使用 pyvmomi 库从一个 vSphere 集群克隆虚拟机到另一个集群,可以按以下步骤进行操作:

  1. 连接到 vCenter。
  2. 获取源集群和目标集群。
  3. 克隆虚拟机(可以克隆到目标集群的资源池)。
  4. 配置和启动克隆的虚拟机。

1、问题背景

  • 我们有两个 VMware 数据中心,都连接到我们的 vCenter 服务器。所有 VMware 都为 5.5。我有一个 VM(不是模板),我试图使用 pyvmomi 以自动化的方式进行克隆。如果我指定要将 VM 克隆到与源 VM 相同的数据中心中的主机,则脚本可以正常工作。但是,如果我指定另一个数据中心中的主机,则克隆将失败,并出现 vmodl 错误:
    • 指定的参数不正确。
  • 据我所知,我在 RelocateSpec 和 CloneSpec 中设置了所有内容,以及实际的 CloneVM_Task 调用。对于正确的方向的任何提示,我们都将不胜感激。谢谢。

2、解决方案

  • 以下是用 Python 编写的脚本,演示了如何使用 pyvmomi 从一个集群克隆虚拟机到另一个集群:
代码语言:javascript
代码运行次数:0
复制
from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim, vmodl
import atexit
import sys
import time
import pprint
​
pp = pprint.PrettyPrinter(indent=4)
​
def WaitForTasks(tasks, si):
    global pp
    """
    Given the service instance si and tasks, it returns after all the
    tasks are complete
    """
    pc = si.content.propertyCollector
    task_result = None
    taskList = [str(task) for task in tasks]
​
    # Create filter
    objSpecs = [vmodl.query.PropertyCollector.ObjectSpec(obj=task) for task in tasks]
    propSpec = vmodl.query.PropertyCollector.PropertySpec(type=vim.Task, pathSet=[], all=True)
    filterSpec = vmodl.query.PropertyCollector.FilterSpec()
    filterSpec.objectSet = objSpecs
    filterSpec.propSet = [propSpec]
    filter = pc.CreateFilter(filterSpec, True)
​
    try:
        version, state = None, None
​
        # Loop looking for updates till the state moves to a completed state.
        while len(taskList):
            update = pc.WaitForUpdates(version)
            for filterSet in update.filterSet:
                for objSet in filterSet.objectSet:
                    task = objSet.obj
                    for change in objSet.changeSet:
                        if change.name == 'info':
                            state = change.val.state
                        elif change.name == 'info.state':
                            state = change.val
                        else:
                            continue
​
                        if not str(task) in taskList:
                            continue
​
                        if state == vim.TaskInfo.State.success:
                            #save info
                            task_result = task.info.result
​
                            # Remove task from taskList
                            taskList.remove(str(task))
                        elif state == vim.TaskInfo.State.error:
                            raise task.info.error
            # Move to next version
            version = update.version
    except Exception, e:
        print "Caught Exception in WaitForTasks : " + pp.pprint(e)
    finally:
        if filter:
            filter.Destroy()
​
    return task_result
​
​
​
"""
 Get the vsphere object associated with a given text name
"""
def GetObject(content, vimtype, name):
    obj = None
    container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
    for c in container.view:
        if c.name == name:
            obj = c
            break
    return obj 
​
​
def WaitForIP(target_machine):
    while target_machine.guest.ipAddress == None:
        print "Waiting for IP to be visible..."
        sys.stdout.flush()
        time.sleep(1)
​
​
def main():
    global pp
​
    try:
        si = None
        server = 'vcenter'
​
        try:
            si = SmartConnect(host=server, user='adminuser', pwd='password', port=443)
        except IOError, e:
            pass
        if not si:
            print "Could not connect to vCenter using specified username and password"
            return -1
​
        atexit.register(Disconnect, si)
​
        # Get references to the needed objects
        content = si.content
        source_machine = GetObject(content,[vim.VirtualMachine],'ubuntu14.04')
        destination_host = GetObject(content, [vim.HostSystem], 'vmhostname')
​
        if "bos" in destination_host.name:
            dsname = 'bosdatastore'
            dcname = 'Boston'
        else:
            dsname = 'reddatastore'
            dcname = 'Redmond'
​
        # Configure where the new machine is to be located
        rs = vim.VirtualMachineRelocateSpec()
        cs = vim.VirtualMachineCloneSpec()
        dc = GetObject(content, [vim.Datacenter], dsname)
        target_folder = dc.vmFolder
        rs.host = destination_host
        cs.location = rs
        cs.powerOn = False
​
        # Clone it
        tasks = [source_machine.CloneVM_Task(target_folder, 'newmachine', cs)]
        print "Clone initiated..."
        sys.stdout.flush()
        target_machine = WaitForTasks(tasks, si)
        print("Virtual Machine %s has been cloned successfully" % "newmachine")
​
        # update NIC settings if needed
        for dev in target_machine.config.hardware.device:
            if dev.deviceInfo.label == 'Network adapter 1':
                nic = dev
                break
​
        if nic.backing.deviceName != 'vlan1':
            net = GetObject(content,[vim.Network],'vlan2')
            vds = vim.vm.device.VirtualDeviceSpec()
            nic.backing.deviceName = 'vlan2'
            nic.backing.network = net
            nic.deviceInfo.summary = 'vlan2'
            vds.device = nic
            vds.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
            vmcs = vim.vm.ConfigSpec()
            vmcs.deviceChange = [vds]
            tasks = [target_machine.ReconfigVM_Task(vmcs)]
            print "Network change started..."
            sys.stdout.flush()
            WaitForTasks(tasks,si)
            print "Network update complete."
​
        # Power the machine on
        tasks = [target_machine.PowerOnVM_Task()]
        print "New machine is starting..."
        sys.stdout.flush()
        WaitForTasks(tasks,si)
​
        # Wait for target to have IP so we can save it
        WaitForIP(target_machine)
​
    except vmodl.MethodFault, e:
        print "Caught vmodl fault in main : " + pp.pprint(e)
    except Exception, e:
        print "Caught Exception in main : " + pp.pprint(e)
​
    print "Done."
​
# Start program
if __name__ == "__main__":
    main()

注意事项:

  • 替换相关的 vCenter、集群和虚拟机名称为你的实际配置。
  • 克隆的虚拟机默认不会启动(powerOn=False),如果需要,可以修改这个参数以便在克隆后启动虚拟机。
  • 你还可以根据需求自定义克隆规格(如网络、磁盘、存储等设置)。

这样,你就可以使用 pyvmomi 库从一个集群克隆虚拟机到另一个集群。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 注意事项:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档