李守中

PVE 虚拟机笔记

Table of Contents

1 Guest 系统

1.1 Windows 系

1.1.1 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 虚拟机即可解决问题。

1.1.2 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

1.2 Linux 系虚拟机笔记

1.2.1 openwrt 无法关闭

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

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

opkg update
opkg install qemu-ga

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

2 通用的性能优化方法

2.1 磁盘映射与 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:

  • VirtIO SCSI 控制器 ( 在 WebUI 创建的虚拟机默认用这个控制器 ) 管理下,所有磁盘共用一个 I/O 控制器。
  • VirtIO SCSI single 控制器管理下,每个磁盘都会有独立的控制器,某些情况下会提升硬盘性能。

不论主板上插了 SATA 接口的盘还是 SAS 接口的盘,使用默认的 VirtIO SCSI 控制器可以提供最佳的性能和特性。

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

3 虚拟机迁移

3.1 踩坑

3.1.1 虚拟机第二次备份时出错

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

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

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

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

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 ) 删除虚拟磁盘。

3.2 导出虚拟机

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

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

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

3.3 从 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

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

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

3.4 虚拟机与模板的互转

虚拟机可以在 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。

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

3.5.1 虚拟机内部写零操作

3.5.1.1 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
3.5.1.2 Windows 虚拟机

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

3.5.2 导出精简后的磁盘文件

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


Last Update: 2023-05-18 Thu 09:03

Contact: [email protected]     Generated by: Emacs 27.1 (Org mode 9.3)

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议