使用 libvirt 配置虚拟机资源

LinuxBeginner
立即练习

简介

虚拟机管理不仅包括创建和启动域。运维人员经常需要接手已有的虚拟机,并修改其持久化资源定义:增加内存、提供更多虚拟 CPU、附加存储、启用自动启动,并确认运行中的状态与请求的配置一致。

在 libvirt 术语中,虚拟机称为域。持久化域拥有已保存的定义,可以将其理解为虚拟硬件蓝图,即使当前没有 QEMU 进程运行也是如此。启动域会根据该定义创建一个运行中的实例;停止域会移除运行中的实例,但会保留这份蓝图。本实验的核心就是理解持久化配置与运行时状态之间的区别。

在本实验中,一个名为 lfcs-config 的已关机 libvirt 域已经预先定义完成,其中包含一个小型启动磁盘、64 MiB 内存和 1 个 vCPU。你将先检查其基线配置,然后使用 virsh 资源管理命令重新配置它。实验环境未提供 /dev/kvm,因此 QEMU 使用软件模拟;磁盘中也没有安装客户机操作系统。不过,管理流程和 libvirt 的持久化配置都是真实有效的。

检查现有域配置

在本步骤中,你将先确认现有 lfcs-config 域的持久化配置和运行时状态,然后再进行修改。

进入项目目录。

cd /home/labex/project

列出所有域。--all 选项会包含已停止的域,因此 lfcs-config 应显示为 shut off 状态。

sudo virsh list --all

不使用 --all 时,virsh list 通常只显示处于活动状态的域。在扩展列表中看到已停止的域名,说明 libvirt 仍然保留着它的持久化定义,即使该虚拟机当前没有作为运行中的客户机消耗 CPU 时间。

查看域的摘要信息。

sudo virsh dominfo lfcs-config

dominfo 会汇总身份、生命周期、CPU、内存、持久化和自动启动等信息。此时应将这些内容视为基线,而不是目标状态:后续输出只应在你明确重新配置的字段上发生变化。

重点关注以下稳定配置字段:

Name:           lfcs-config
State:          shut off
CPU(s):         1
Max memory:     65536 KiB
Used memory:    65536 KiB
Persistent:     yes
Autostart:      disable

libvirt 在这里使用 KiB 表示内存。由于 1 MiB 等于 1024 KiB,因此 65536 KiB 就是 64 MiB。Persistent: yes 表示该定义会在关机后保留,而 Autostart: disable 表示 libvirt 启动其虚拟化服务时不会自动启动此域。

列出已附加的块设备。vda 是预先准备好的根磁盘,其源文件是现有的 qcow2 镜像。

sudo virsh domblklist lfcs-config --details

在此表中,Target 是提供给客户机使用的设备名称,Source 是存储其数据的主机路径。名为 vda 的 virtio 磁盘相当于连接到虚拟机的虚拟驱动器;qcow2 源文件则是该驱动器在主机上的后备镜像。

这份基线配置可以帮助你区分现有内容与后续步骤中将要进行的资源变更。

配置持久化内存和 vCPU

在本步骤中,虚拟机处于关机状态,你将增加该域的持久化最大内存、当前内存分配和 vCPU 数量。

libvirt 将最大内存上限与下次启动时分配的内存区分开来。首先将持久化最大内存设置为 128 MiB。--config 标志会修改已保存的域定义,而不是临时的运行时值。

sudo virsh setmaxmem lfcs-config 128M --config

最大内存上限必须足够容纳实际分配的内存。可以将 max memory 理解为虚拟机的内存容量,将 current memory 理解为正常使用时请求的内存量。由于该域当前处于关机状态,修改 --config 的行为是可预测的,并会在下次启动时生效。

将下次启动时分配的内存设置为 96 MiB。

sudo virsh setmem lfcs-config 96M --config

后缀 M 会让 virsh 按 MiB 解释该数值。稍后 dominfo 的输出会将 128 MiB 转换为 131072 KiB,将 96 MiB 转换为 98304 KiB;它们只是使用了不同的单位,表示的内存大小相同。

在设置当前持久化分配值为 2 个 CPU 之前,必须先提高 vCPU 的最大数量。

sudo virsh setvcpus lfcs-config 2 --config --maximum

这条 CPU 命令首先修改已保存定义中的上限,但不会直接分配 2 个可用的 vCPU。将最大值与当前分配值分开设置,可以让虚拟机定义预留未来扩展所需的容量。

将下次启动时使用的 vCPU 数量设置为 2。

sudo virsh setvcpus lfcs-config 2 --config

第二条命令会在新的上限范围内设置持久化分配值。顺序很重要:如果最大值仍为 1,却请求分配 2 个 vCPU,命令就会失败。

检查更新后的持久化定义。

sudo virsh dominfo lfcs-config

相关字段现在应显示:

CPU(s):         2
Max memory:     131072 KiB
Used memory:    98304 KiB

创建并附加持久化数据磁盘

在本步骤中,你将创建第二个 qcow2 镜像,并将其作为名为 vdb 的持久化 virtio 磁盘附加到虚拟机。

在 libvirt 的镜像目录中创建一个稀疏的 64 MiB qcow2 镜像。

sudo qemu-img create -f qcow2 /var/lib/libvirt/images/lfcs-config-data.qcow2 64M

该命令创建的是虚拟磁盘容器,而不是文件系统,也不是已挂载的目录。-f qcow2 选择 QEMU 的写时复制镜像格式,64M 设置其虚拟容量。新创建的稀疏镜像最初占用的主机存储空间会远小于其虚拟大小,并会随着客户机写入数据而逐渐增长。

允许本实验环境中的 QEMU 进程打开这个临时镜像。

sudo chmod 666 /var/lib/libvirt/images/lfcs-config-data.qcow2

权限模式 666 授予所有用户类别读取和写入权限。如此宽松的权限可以避免本实验受主机 QEMU 用户和组设置差异的影响,但不建议在生产环境中使用。在真实主机上,应根据本地 libvirt 服务的要求,采用适当的所有者、用户组、SELinux 标签或 AppArmor 策略。

将该文件附加到 lfcs-config。--target vdb 指定客户机中的块设备名称,--subdriver qcow2 记录镜像格式,--config 则修改下次启动时使用的持久化定义。

sudo virsh attach-disk lfcs-config \
  /var/lib/libvirt/images/lfcs-config-data.qcow2 \
  vdb --targetbus virtio --subdriver qcow2 --config

源路径属于主机;vdb 是客户机将看到的设备名称。--targetbus virtio 选择半虚拟化磁盘接口,Linux 客户机通常使用这种接口来获得更高的效率。由于该域处于关机状态,且命令使用了 --config,libvirt 会将设备记录到已保存的蓝图中,而不会尝试在线热插拔。

列出持久化的块设备配置。

sudo virsh domblklist lfcs-config --details

输出现在应同时包含 vda 和 vdb,其中 vdb 指向 lfcs-config-data.qcow2。

此时,镜像文件和域附加关系是两个独立的事实。单独创建 qcow2 文件并不会将其连接到虚拟机;以后卸载磁盘也不会自动删除其源文件。

启用自动启动并验证运行时状态

在本步骤中,你将启用域的自动启动功能,立即启动虚拟机,并将其运行时资源与持久化设置进行对比。

启用自动启动,让 libvirt 在虚拟化服务启动时自动启动此域。

sudo virsh autostart lfcs-config

自动启动是一个已保存的策略标志,并不表示立即启动该域。对于基础设施服务而言,这项功能很有用,因为主机或 libvirt 服务重启后,相关服务可以自动恢复运行。

使用更新后的持久化定义启动该域。

sudo virsh start lfcs-config

启动操作会根据你编辑过的已保存定义创建 QEMU 进程,其中包括 2 个 vCPU、新的内存限制以及两块磁盘。命令只会报告域已启动;dominfo 和 domblklist 才能提供证据,证明其状态符合预期配置。

等待几秒,让 QEMU 进入运行状态。

sleep 3

检查域状态。它应处于运行状态,拥有 2 个 vCPU、128 MiB 最大内存,并且已启用自动启动。

sudo virsh dominfo lfcs-config

在这个使用软件模拟的域中,运行时的 Used memory 通常为 128 MiB,尽管持久化的 currentMemory 请求值为 96 MiB。这是因为客户机中没有操作系统或气球驱动程序与 libvirt 协作,以降低运行时内存分配。检查非活动 XML,以确认下次启动配置中仍记录着 96 MiB:

sudo virsh dumpxml lfcs-config --inactive | grep -E '<memory|<currentMemory|<vcpu'

dumpxml --inactive 请求的是已保存的定义,而不是 QEMU 当前的实时视图。管道会将 XML 传递给 grep,只显示内存和 CPU 元素。通过这种聚焦式对比,可以避免将预期中的运行时报告差异误判为配置失败。

稳定值应包括 <memory unit='KiB'>131072</memory>、<currentMemory unit='KiB'>98304</currentMemory> 以及值为 2 的 vCPU。这个对比说明,应分别检查持久化配置和运行时资源报告。

列出活动域中的磁盘。

sudo virsh domblklist lfcs-config --details

vda 和 vdb 都应出现。这说明 QEMU 启动时已经应用了已保存的配置。

停止虚拟机并确认持久化状态

在本步骤中,你将停止客户机进程,同时保留已配置的域、存储和自动启动设置。

由于实验磁盘中没有操作系统,无法完成正常的客户机关闭操作。使用 destroy 立即停止 QEMU 进程。此操作只会改变运行时状态,不会删除持久化域定义。

sudo virsh destroy lfcs-config

尽管名称中包含「destroy」,但 virsh destroy 更接近于切断电源,而不是删除虚拟机。这里使用它是因为本练习没有客户机操作系统或重要数据。对于真实运行中的客户机,应优先使用 virsh shutdown,让操作系统先刷新数据并正常停止。

确认域已停止。

sudo virsh domstate lfcs-config

输出应为:

shut off

最后一次检查持久化配置。

sudo virsh dominfo lfcs-config

预期的 shut off 状态只描述运行时状态。CPU、内存、磁盘附加关系和自动启动设置仍保留在持久化定义中。若要删除该定义,需要执行其他操作,例如 virsh undefine;即使取消定义,也不一定会删除其磁盘镜像文件。

列出所有域及其自动启动状态。已停止的 lfcs-config 域应仍然存在,并标记为自动启动。

sudo virsh list --all --autostart

现在,虚拟机已停止,但之后仍可使用你创建的资源配置重新启动。

总结

你接手了一个现有的 libvirt 域,并在不重写其 XML 的情况下修改了持久化资源配置。你增加了最大内存和分配内存,配置了 2 个 vCPU,创建并附加了第二个 qcow2 磁盘,启用了自动启动,在运行中的 QEMU 域中验证了配置,最后停止进程,同时保留了受 libvirt 管理的虚拟机。这正是单纯了解虚拟机生命周期与将虚拟机配置到指定目标状态之间的实际区别。