基于Libvirt与KVM的Python虚拟机创建报错排查求助
问题:Python libvirt创建KVM虚拟机报错"Domain not found"
问题场景
在VM Workstation中运行的Ubuntu系统上,尝试通过Python的libvirt库程序化创建、启动、停止及删除KVM虚拟机,运行代码时触发如下错误。
运行代码
import libvirt def create_vm(name, memory): conn = libvirt.open() if conn is None: print('Failed to connect to the hypervisor') return try: # Check if the virtual machine already exists if conn.lookupByName(name): print(f'Virtual machine {name} already exists') return # Create the virtual machine xmlconfig = f''' <domain type='kvm'> <name>{name}</name> <memory unit='KiB'>{memory}</memory> <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type> <boot dev='hd'/> </os> <devices> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/disk_image.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> <interface type='network'> <mac address='52:54:00:aa:bb:cc'/> <source network='default'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> </devices> </domain> ''' conn.createXML(xmlconfig, 0) print(f'Virtual machine {name} created successfully') except libvirt.libvirtError as e: print(f'Failed to create virtual machine: {str(e)}') conn.close() # Usage example create_vm('my_vm', 1024)
报错信息
libvirt: QEMU Driver error: Domain not found: no domain with matching name 'my_vm' Failed to create virtual machine: Domain not found: no domain with matching name 'my_vm'
错误原因
- 存在性检查逻辑错误:
conn.lookupByName(name)方法在目标虚拟机不存在时,不会返回None,而是直接抛出libvirtError异常,该异常被后续的try-except捕获,导致程序误判为创建失败。 - XML配置缺失必填项:原配置缺少
currentMemory节点,libvirt要求必须同时定义memory(最大内存)和currentMemory(当前分配内存)。
修复方案
1. 修正虚拟机存在性检查逻辑
改用try-except捕获lookupByName的异常,以此判断虚拟机是否存在:
2. 补充XML必填配置项
添加currentMemory节点,确保配置符合libvirt要求。
3. 确保磁盘镜像存在
如果/var/lib/libvirt/images/disk_image.qcow2不存在,提前创建镜像文件:
qemu-img create -f qcow2 /var/lib/libvirt/images/disk_image.qcow2 10G
4. 确保运行用户权限
将当前用户加入libvirt组,避免权限问题:
sudo usermod -aG libvirt $USER newgrp libvirt
修正后的完整代码
import libvirt def create_vm(name, memory): conn = libvirt.open() if conn is None: print('Failed to connect to the hypervisor') return try: # 检查虚拟机是否存在:捕获lookupByName的异常 try: conn.lookupByName(name) print(f'Virtual machine {name} already exists') return except libvirt.libvirtError: # 虚拟机不存在,继续创建流程 pass # 构造完整的XML配置,补充currentMemory节点 xmlconfig = f''' <domain type='kvm'> <name>{name}</name> <memory unit='KiB'>{memory}</memory> <currentMemory unit='KiB'>{memory}</currentMemory> <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type> <boot dev='hd'/> </os> <devices> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/var/lib/libvirt/images/disk_image.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> <interface type='network'> <mac address='52:54:00:aa:bb:cc'/> <source network='default'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <!-- 添加控制台设备,方便后续管理 --> <console type='pty'> <target type='serial' port='0'/> </console> </devices> </domain> ''' # 创建并启动虚拟机(createXML会直接启动,若要只定义不启动,用defineXML) conn.createXML(xmlconfig, 0) print(f'Virtual machine {name} created and started successfully') except libvirt.libvirtError as e: print(f'Failed to create virtual machine: {str(e)}') finally: # 确保连接关闭 if conn is not None: conn.close() # Usage example:内存单位是KiB,1024*1024表示1GiB create_vm('my_vm', 1024*1024)
额外验证步骤
- 检查libvirt服务状态:
systemctl status libvirtd
- 确认KVM模块已加载:
lsmod | grep kvm
- 验证磁盘镜像路径权限:
ls -l /var/lib/libvirt/images/disk_image.qcow2
内容的提问来源于stack exchange,提问作者dija
相关产品推荐
相关产品推荐

