PVE 虚拟机相关 

Last Update: 2023-09-21

目录

Guest 系统

Windows 系

windows web console 鼠标不同步

显卡用默认配置的话是没有这种现象的。这个问题出现在使用 SPICE 显卡模拟功能的情况下。

虚拟机有个配置项为 tablet: <boolean> (default = 1) ,它用来启用 / 禁用被模拟出的,使用绝对坐标的 USB 指针设备。通常只有启用了该设备才能在 VNC 中使用鼠标的绝对坐标,从而使得 host 和 guest 的鼠标设备同步。

QEMU-KVM 文档 https://qemu-project.gitlab.io/qemu/system/devices/usb.html 里这么描述 usb-tablet 设备:

Pointer device that uses absolute coordinates (like a touchscreen). This means QEMU is able to report the mouse position without having to grab the mouse. Also overrides the PS/2 mouse emulation when activated.

tablet: 0 是使用 spice 终端的默认配置 (即 qm set <vmid> --vga qxl),所以出现了 Host 的鼠标和 VNC 终端内的鼠标位置不同步的现象。

如果一台主机上运行了多台通过 VNC 终端访问的虚拟机,可以考虑在全局配置里禁用该参数,以节省不必要的上下文切换。

要在尽可能少地改动配置、尽量减少影响范围的情况下,解决鼠标同步问题,需要连接到 PVE 主机,使用 sudo vim /etc/pve/qemu-server/<vm_id>.conf 对单台虚拟机配置进行修改。加入以下语句:

...
tablet: 1
# tablet: yes 也行,随后会自动地被 PVE 改写成 tablet: 1
...

最后重启 windows 虚拟机即可解决问题。

Windows Server 2008 R2 设备管理器里出现 device ID 为 ACPI\QEMU\VGID 的未知设备

这是因为 Windows 7 默认没有原生的 VM Generation ID (PVE 的一个特性) 支持。只能手动安装补丁包到系统中。

下载 Hyper-V integration components update (All supported x64-based versions of Windows 7) 然后传输到虚拟机中,并安装: Dism /online /Add-Package /PackagePath:C:\<package>.cab

Windows 7 上的 virtio-win 在安装 virtio-win-gt 时报 VdService failed to start

virtio-win 官方兼容 win7 的最后一个版本是 virtio-win-0.1.173-4。但是这个版本还有一些问题。

在使用 virtio-win-gt-x64.msi 装驱动时,Spice Agent 相关的驱动有些问题,会导致 rdservice 不能启动,进而导致安装失败。

必须在 Custom Setup 阶段将 Spice Agent 组件设为 Feature will be installed when required 以跳过安装 Spice Agent 组件才能继续后面的安装过程。

但是要注意,如果 virtio-win-0.1.173-4 用在 Windows Server 2008R2 上,那么 virtio-win-gt-x64.msi 除了 Spice Agent 之外什么都装不上,而且唯一要装的 Spice Agent 还有问题,所以跑完什么都没装上。所有驱动必须自己手动装上去。

Linux 系虚拟机笔记

openwrt 无法关闭

可能是 openwrt 系统里缺 QEMU Guest Agent 这个包。

ssh 进 openwrt,安装 qemu-ga 即可:

opkg update
opkg install qemu-ga

如果使用的固件没有 opkg 一类的包管理器,那么只能在重新编译的时候把 qemu-ga 一起编译进去。

通用的性能优化方法

磁盘映射与 VertIO SCSI 控制器

第一步,获取硬盘信息。SSH 连接到 PVE 物理机执行 ls /dev/disk/by-id/ 得到硬盘 ID 的第一列大概长这样:

# 这是一块硬盘的 ID
ata-HGST_HUS728T8TALE6L4_VDGW2G2D
# 这是上面 ID 对应硬盘的一个分区
ata-HGST_HUS728T8TALE6L4_VDGW2G2D-part1
# 这是上面 ID 对应硬盘的另一个分区
ata-HGST_HUS728T8TALE6L4_VDGW2G2D-part2
ata-HGST_HUS728T8TALE6L4_VGGP235G
ata-HGST_HUS728T8TALE6L4_VGGP235G-part1
ata-HGST_HUS728T8TALE6L4_VGGP235G-part2
ata-INTEL_SSDSC2BA400G3_BTTV501203BG400HGN
ata-MK0800GCTZB_BTTV5295004K800JGN
ata-MK0800GCTZB_BTTV5295004K800JGN-part1
ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2EMU56607
ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2EMU56607-part1
dm-name-Intel400GS3700-vm--130--disk--0
dm-name-pve-root

第二步,映射硬盘,命令为 qm set <vm_id> -<controller_type><controller_id> /dev/disk/by-id/<disk_id><vm_id> 是虚拟机的真实 id, <controller_type> 是对应的控制器类型, <controller_id> 是该类型未被占用的通道,PVE 支持 sata[0-5] 以及 scsi[0-13]

比如执行这样的命令:

qm set 130 -scsi1 /dev/disk/by-id/ata-MK0800GCTZB_BTTV5295004K800JGN

得到的输出是这样的:

update VM 130: -scsi1 /dev/disk/by-id/ata-MK0800GCTZB_BTTV5295004K800JGN

在这条命令执行后,物理机上的磁盘 (不论是 SATA 还是 SAS 接口) 被默认的 VirtIO SCSI 控制器模拟成普通的 scsi 磁盘,在系统中显示为 /dev/sd[a-z] 。这个控制器在老版本的 PVE 需要特别指定,即在命令后加 -scsihw virtio-scsi-pci (至少 PVE 6 不用手动写这个参数)。

常用的控制器类型有 SATA, VirtIO (也叫 VirtIO blk), VirtIO SCSIVirtIO SCSI single

<controller_type>virtio (这种控制器通常被称为 VirtIOVirtIO blk),虚拟硬盘在系统中显示为 /dev/vd[a-z] 。这是一种较老的半虚拟化控制器,就功能而言,它已被 VirtIO SCSI 控制器取代。

如果在 WebUI 里编辑 SCSI 控制器,可以在选项中看到 VirtIO SCSI 和 VirtIO SCSI single:

注: 在 PVE 7.3 之前,VirtIO SCSI 是默认的控制器;之后,VirtIO SCSI single 是默认的控制器。

不论主板上插了 SATA 接口的盘还是 SAS 接口的盘,CPU 核心多主频低的时候用 VirtIO SCSI single 控制器,CPU 核心少主频高的时候用 VirtIO SCSI 控制器。

如果 guest 太老,不支持 VirtIO SCSI 控制器,则可以把 -scsi[0-13] 换成 -sata[0-5] 来使用 SATA 控制器。

虚拟机迁移

踩坑

虚拟机第二次备份时出错

PVE 虚拟机备份在默认情况下只存储一份,如果设定了定时备份任务,那么旧的备份会被删除。

修改方法: Web UI -> 数据中心 -> 存储 -> 双击备份所在位置的 ID -> Backup Retention -> 自定义备份文件存储逻辑。

这里的设置要参考 PVE 文档,或者直接去搜 Proxmox Backup Server - Prune Simulator 这是 PVE 官方做的备份模拟器。

移动虚拟磁盘后旧磁盘无法删除

SSH 登录到 PVE 物理机,执行 qm rescan --vmid <vm_id> 后,未使用的磁盘会出现在 Web UI 上,此时可以删除。

如果还不能删,重启 PVE 物理机再从 Web UI 上删除。

也可以用命令 pvesm free <volume_id>pvesm free <storage_id>:<disk_id> (比如 pvesm free local-lvm:vm-105-disk-1pvesm free local-lvm:vm-105-disk-1) 删除虚拟磁盘。

导出虚拟机

第一步,生成备份文件。选中虚拟机 -> 备份 -> 立即备份 -> 选定备份参数 -> 备份

第二步,找到备份文件。如果使用 PVE local 存储,那么在 /var/lib/vz/dump 内有 .vma.gz 压缩文件和 .log 日志文件。

最后下载这两个文件自行备份。

从 img 文件导入虚拟机

第一步,正常创建一个虚拟机,过程中:

  1. 操作系统: 不使用任何介质;
  2. 硬盘: 随便选,反正要删掉的。

第二步,删除默认创建的硬盘: 选中虚拟机 -> 硬件 -> 选中硬盘 (比如 scsi0) -> 分离 -> 选中未使用的磁盘 -> 删除

第三步,把 img 文件传入 PVE 宿主机。

第四步,添加磁盘。用 SSH 连接到宿主机,执行命令导入硬盘,格式为:

qm importdisk <vm_id> /<img_file_path>/<img_file> <disk_id>

比如: qm importdisk 150 ./openwrt.img local-lvm

第五步,添加导入的磁盘: 选中虚拟机 -> 硬件 -> 选中未使用的磁盘 -> 编辑 -> 添加

第六步,调整启动顺序: 选中虚拟机 -> 选项 -> 引导顺序 -> 编辑 -> 选中硬盘,拖到第一位。

虚拟机与模板的互转

虚拟机可以在 Web UI 里转成模板。

模板转虚拟机,删除 /etc/pve/qemu-server/<vm_id>.conf 文件里的 template: 1 行。

此时,虚拟机已可以正常启动。

虚拟机转模板后,虚拟机磁盘的名称也会由 vm-<vm_id>-disk-<disk_id> 变成 base-<vm_id>-disk-<disk_id> ,比如 vm-3000-disk-0 变成 base-3000-disk-0。

视需要更新虚拟磁盘的名称。但在更新虚拟磁盘名称后也要更新 /etc/pve/qemu-server/<vm_id>.confscsi0: <storage_id>:<vm_id>/<disk_name>.<disk_format>,size=<size>,ssd=1 的磁盘信息。

比如,scsi0: Intel400S3710:3000/base-3000-disk-0.qcow2,size=32G,ssd=1 更新为 scsi0: Intel400S3710:3000/base-3000-disk-0.qcow2,size=32G,ssd=1。

让 qcow2 虚拟机硬盘文件大小与实际使用空间相等

虚拟机内部写零操作

Linux 虚拟机

如果文件系统为 ext 系列,使用 zerofree 这个包能做到只对非 0 块写 0,减少非必要的写入,延长硬盘寿命。具体操作方法为:

  1. 用 Ubuntu 或者 Debian 的 live 镜像进入体验系统。
  2. 执行 =sudo apt install -y zerofree= 安装软件。
  3. 执行 =sudo zerofree /dev/sda{2-3}= 对分区写 0 后退出体验系统。

如果文件系统为 xfs 或者其他,那么只能用最基础的方法:

# 创建一个全 0 的大文件,对于所有的块写 0
dd if=/dev/zero of=/null.dat
# 删除这个文件
rm -f /null.dat
Windows 虚拟机

在 windows 虚拟机上,下载微软 SysinternalsSuite 套件,执行里面的 sdelete.exe: =.\sdelete.exe -z c:=

导出精简后的磁盘文件

raw 格式虚拟磁盘文件导出到 qcow2:

# --sparse=always 稀疏拷贝,忽略全 0 数据
cp --sparse=always vm500G.raw vm500G-new.raw
qemu-img convert -c -f raw -O qcow2 vm500G.raw vm500G.qcow2
# 删除第一条命令产生的 raw 文件
rm vm500G.raw

qcow2 格式的虚拟磁盘文件精简导出:

qemu-img convert -c -O qcow2 vm500G.qcow2 vm500G-mini.qcow2