QEMU(Quick Emulator的简称)是一种开源的虚拟机监视器,它模拟一个物理计算机。从运行QEMU的宿主系统的角度看,QEMU是一个用户程序,它可以访问许多本地资源,如分区、文件、网络卡,这些资源随后被传递给一个模拟的计算机,这个模拟的计算机将它们视为真实的设备。

在模拟的计算机中运行的客户操作系统访问这些设备,并且运行得就像是在真实的硬件上运行一样。例如,你可以将ISO镜像作为参数传递给QEMU,而在模拟计算机中运行的操作系统将会看到一个真实的CD-ROM被插入到CD驱动器中。

QEMU能模拟从ARM到Sparc的各种硬件,但{pve}只关心32位和64位PC克隆模拟,因为它代表了服务器硬件的绝大多数。PC克隆的模拟也是最快的之一,这归功于处理器扩展的可用性,这些扩展极大地加速了QEMU,特别是当被模拟的架构与宿主架构相同时。

Note
您可能偶尔会遇到术语_KVM_(基于内核的虚拟机)。这意味着QEMU正在运行,支持通过Linux KVM模块的虚拟化处理器扩展。在{pve}的上下文中,_QEMU_和_KVM_可以互换使用,因为QEMU在{pve}中将始终尝试加载KVM模块。

QEMU在{pve}内部以root进程运行,因为这是访问块和PCI设备所必需的。

模拟设备和半虚拟化设备

QEMU模拟的PC硬件包括主板、网络控制器、SCSI、IDE和SATA控制器、串行端口(完整列表可以在`kvm(1)`手册页面中看到),它们都是通过软件模拟的。所有这些设备都是现有硬件设备的精确软件等效物,如果在客户机中运行的操作系统有适当的驱动程序,它将会像在真实硬件上运行一样使用这些设备。这使得QEMU能够运行_未修改_的操作系统。

这确实会带来性能开销,因为在软件中运行原本应在硬件中运行的任务会给主机CPU带来大量额外工作。为了缓解这一问题,QEMU可以向客户操作系统呈现_半虚拟化设备_,在这种情况下,客户操作系统认识到它正在QEMU内部运行,并与虚拟机监视器合作。

QEMU依靠virtio虚拟化标准,因此能够提供支持paravirtualized virtio设备,这包括一个paravirtualized通用磁盘控制器、一个paravirtualized网络卡、一个paravirtualized串行端口、一个paravirtualized SCSI控制器等…​

Tip
强烈推荐在任何可能的情况下使用virtio设备,因为它们能大幅提升性能并且通常维护得更好。使用virtio通用磁盘控制器而不是仿真的IDE控制器,可以将顺序写入吞吐量翻倍,这是通过`bonnie++(8)`测量得到的。使用virtio网络接口能够提供高达仿真的Intel E1000网络卡三倍的吞吐量,这是通过`iperf(1)`测量得到的。脚注:[请参阅KVM wiki上的这个基准测试 https://www.linux-kvm.org/page/Using_VirtIO_NIC]

虚拟机设置

一般来说,{pve} 会尽量为虚拟机(VM)选择合理的默认设置。请确保您理解您所更改设置的含义,因为这可能会导致性能下降,或使您的数据处于风险之中。

通用设置

虚拟机的一般设置包括

  • Node:VM将运行在其上的物理服务器

  • VM ID:在这个{pve}安装中用于识别你的虚拟机的唯一编号

  • 名称:你可以用来描述虚拟机的自由形式文本字符串

  • 资源池:虚拟机的逻辑分组

操作系统设置

在创建虚拟机(VM)时,设置正确的操作系统(OS)可以让{pve}优化一些低级参数。例如,Windows OS期望BIOS时钟使用本地时间,而基于Unix的操作系统则期望BIOS时钟使用UTC时间。

系统设置

在创建虚拟机(VM)时,您可以更改新VM的一些基本系统组件。您可以指定希望使用的显示类型

此外,可以更改SCSI控制器。如果您计划安装QEMU Guest Agent,或者您选择的ISO镜像已经自动安装了它,您可能想要勾选“QEMU Agent”框,这让{pve}知道它可以使用其功能来显示更多信息,并更智能地完成一些操作(例如,关机或快照)。

{pve}允许以不同的固件和机器类型启动虚拟机,即SeaBIOS和OVMF。在大多数情况下,如果你计划使用PCIe直通,你仅需从默认的SeaBIOS切换到OVMF。

机器类型

机器版本

在QEMU中,每种机器类型都有版本,并且给定的QEMU二进制文件支持许多机器版本。新版本可能会带来对新功能的支持、修复或一般改进。然而,它们也会改变虚拟硬件的属性。为了避免从客户端的视角看到突然的改变,并确保虚拟机状态、实时迁移和带有RAM的快照的兼容性,新的QEMU实例将继续使用相同的机器版本。

对于Windows客户端,机器版本在创建时被固定,因为Windows对虚拟硬件的变化非常敏感 - 即使在冷启动之间也是如此。例如,不同机器版本可能会导致网络设备的枚举不同。其他操作系统,比如Linux,通常可以很好地处理这些变化。对于这些系统,默认使用“最新”的机器版本。这意味着,在一次全新的启动后,将使用QEMU二进制文件所支持的最新机器版本(例如,QEMU 8.1支持的最新机器版本就是每种机器类型的版本8.1)。

升级到更新的机器版本

对于QEMU中的非常旧的机器版本,可能会逐渐不被支持。举例来说,对于i440fx机型的1.4到1.7版本就是这种情况。预计这些机器版本的支持将在某一时刻被取消。如果您看到一个弃用警告,您应该将机器版本更换为更新的版本。首先确保有一个可用的备份,并且为硬件看到的更改做好准备。在某些情况下,可能需要重新安装某些驱动程序。您还应该检查使用这些机器版本(即`runningmachine`配置条目)拍摄的带有RAM的快照。不幸的是,快照的机器版本无法更改,因此您需要加载快照以从中挽救任何数据。

硬盘

总线/控制器

QEMU能够模拟多种存储控制器:

Tip
出于性能原因以及它们得到更好的维护,强烈推荐使用*VirtIO SCSI*或*VirtIO Block*控制器。
  • IDE控制器的设计可以追溯到1984年的PC/AT磁盘控制器。即使这种控制器已经被最新的设计所取代,你能想到的每一个操作系统都对它有支持,这使得它成为一个很好的选择,如果你想运行一个在2003年之前发布的操作系统。你可以在这个控制器上连接多达4个设备。

  • SATA(串行ATA)控制器,起源于2003年,其设计更加现代化,允许更高的数据吞吐量以及连接更多的设备。在这个控制器上,你可以连接多达6个设备。

  • SCSI 控制器,设计于 1985 年,通常在服务器级硬件上可以找到,并且可以连接多达 14 个存储设备。{pve} 默认模仿一个 LSI 53C895A 控制器。

    如果您追求性能,建议使用类型为 VirtIO SCSI 单一 的 SCSI 控制器,并为附加的磁盘启用 IO 线程 设置。这是从 {pve} 7.3 开始新创建的 Linux VMs 的默认配置。每个磁盘都将拥有自己的 VirtIO SCSI 控制器,QEMU 将在一个专用线程中处理磁盘的 IO 。Linux 发行版自2012年以来已支持此控制器,FreeBSD 从2014年开始支持。对于 Windows 操作系统,您需要在安装过程中提供一个包含驱动程序的额外 ISO 文件。

  • VirtIO Block控制器,通常简称为VirtIO或virtio-blk,是一种较旧型号的半虚拟化控制器。它已被VirtIO SCSI控制器所取代,后者在功能方面更为先进。

图像格式

在每个控制器上,你可以连接多个被模拟的硬盘,这些硬盘由位于配置的存储中的文件或块设备支持。存储类型的选择将决定硬盘映像的格式。呈现块设备的存储(LVM,ZFS,Ceph)将需要*原始硬盘映像格式*,而基于文件的存储(Ext4,NFS,CIFS,GlusterFS)则允许你选择*原始硬盘映像格式*或*QEMU映像格式*。

  • QEMU镜像格式是一种写时复制格式,允许快照等操作。 磁盘映像的精简配置。

  • 原始磁盘映像是硬盘的逐位映像,类似于什么 在Linux中执行`dd`命令操作块设备时,你会得到的结果。这种格式本身不支持细粒度配置或快照功能,需要存储层的配合来完成这些任务。然而,它可能比*QEMU镜像格式*快达10%。脚注:[详见此基准测试 https://events.static.linuxfound.org/sites/events/files/slides/CloudOpen2013_Khoa_Huynh_v3.pdf]

  • 如果你打算导入/导出,则*VMware镜像格式*只有在这种情况下才有意义。 将磁盘映像转换到其他超级管理程序。

缓存模式

设置硬盘的 Cache(缓存)模式将影响主系统如何通知客户系统块写入完成。No cache(无缓存)默认设置意味着,当每个块到达物理存储写入队列时,客户系统将被通知写入操作已完成,忽略主机页面缓存。这提供了安全性和速度之间的好平衡。

如果你希望{pve}备份管理器在对虚拟机进行备份时跳过某个磁盘,你可以对那个磁盘设置*不备份*选项。

如果你希望{pve}存储复制机制在启动复制作业时跳过某个磁盘,你可以在该磁盘上设置*跳过复制*选项。从{pve} 5.0版本开始,复制要求磁盘映像位于类型为`zfspool`的存储上,因此,当虚拟机配置了复制时,将磁盘映像添加到其他存储需要跳过该磁盘映像的复制。

修剪/丢弃

如果您的存储支持_薄置备_(请参阅{pve}指南中的存储章节),您可以在驱动上激活*Discard*选项。设置了*Discard*并且在支持_TRIM_的客户操作系统(注脚:TRIM, UNMAP, 和 discard https://en.wikipedia.org/wiki/Trim_%28computing%29)中,当VM的文件系统在删除文件后标记块为未使用时,控制器会将此信息传递给存储,然后存储会相应地缩小磁盘映像。为了使客户能够发出_TRIM_命令,您必须在驱动上启用*Discard*选项。一些客户操作系统还可能需要设置*SSD模拟*标志。注意,*VirtIO Block*驱动上的*Discard*仅支持使用Linux Kernel 5.0或更高版本的客户。

如果您希望将驱动器呈现给访客作为固态硬盘而不是旋转硬盘,您可以在该驱动器上设置*SSD仿真*选项。底层存储实际上被SSD支持并不是一个要求;这项功能可以与任何类型的物理介质一起使用。请注意,*SSD仿真*不支持在*VirtIO Block*驱动器上。

IO 线程

IO Thread 选项仅能在使用带有 VirtIO 控制器的磁盘,或当仿真控制器类型为 VirtIO SCSI single 时,与 SCSI 控制器一起使用。启用 IO Thread 后,QEMU将为每个存储控制器创建一个I/O线程,而不是在主事件循环或vCPU线程中处理所有I/O。其一大优点是更好的工作分配和底层存储的利用。另一个优点是降低了客户机在非常I/O密集的宿主工作负载情况下的延迟(挂起),因为主线程或vCPU线程均不会因磁盘I/O而被阻塞。

中央处理器

CPU插槽是PC主板上的一个物理插槽,您可以在其中插入CPU。这个CPU可以包含一个或多个内核,这些内核是独立的处理单元。无论您是拥有一个带有4个核心的单个CPU插槽,还是两个带有两个核心的CPU插槽,在性能方面大多是无关紧要的。然而,一些软件许可证取决于机器拥有的插槽数量,在这种情况下,将插槽数量设置为许可证允许的数量是有意义的。

增加虚拟CPU的数量(核心和插槽)通常会提高性能,尽管这在很大程度上取决于VM的使用方式。多线程应用程序当然会从大量虚拟CPU中受益,因为对于你添加的每一个虚拟cpu,QEMU都会在宿主系统上创建一个新的执行线程。如果你不确定自己的VM负载情况,通常设置*总核心*数量为2是一个安全的选择。

Note
如果所有虚拟机(VM)的核心数总和大于服务器上的核心数(例如,4个虚拟机,每个都有4个核心,总共16个核心,而机器只有8个核心),那么是完全安全的。在这种情况下,宿主系统将会在服务器核心之间平衡QEMU执行线程,就像你运行标准的多线程应用程序一样。然而,{pve}会防止你启动虚拟机,如果虚拟机的虚拟CPU核心数超过了物理上可用的核心数,因为这会由于上下文切换的成本而降低性能。

资源限制

cpulimit

除了虚拟核心的数量外,VM的可用“主机CPU时间”总量可以通过*cpulimit*选项设置。它是一个表示CPU时间的浮点数值,以百分比计,因此`1.0`等于`100%,`2.5`等于`250%`等等。如果一个单独的进程完全使用一个核心,它将有`100%`的CPU时间使用率。如果一个拥有四个核心的VM完全利用了它的所有核心,理论上它将使用`400%。实际上,使用率可能会更高一些,因为QEMU除了vCPU核心之外,还可以为VM外设有额外的线程。

当VM需要拥有多个虚拟CPU,因为它在并行运行一些进程时,这个设定可能会很有用,但是整个VM不应该能够同时让所有虚拟CPU都运行在100%。

例如,假设你有一台虚拟机,其能从拥有8个虚拟CPU中获益,但你不希望虚拟机使用全部8个核心全负荷运行 - 因为这将会过载服务器,并使得其他虚拟机和容器获得的CPU时间过少。为了解决这个问题,你可以将*cpulimit*设置为`4.0`(=400%)。这意味着,如果虚拟机通过同时运行8个进程充分利用所有8个虚拟CPU,每个vCPU将从物理核心获得最多50%的CPU时间。然而,如果虚拟机的工作负载仅仅充分利用了4个虚拟CPU,它仍然可以从一个物理核心获得高达100%的CPU时间,总共为400%。

Note
VM可以根据它们的配置,使用额外的线程,比如用于网络或IO操作,也包括实时迁移。因此,一个VM可能会使用比它的虚拟CPU所能使用的更多CPU时间。为了确保VM永远不会使用比分配给它的vCPUs更多的CPU时间,将*cpulimit*设置为与总核心数相同的值。

cpu单位

通过 cpuunits 选项,现今通常被称为CPU份额或CPU权重,你可以控制相比于其他正在运行的虚拟机(VM)一台VM可以获得多少CPU时间。这是一个相对权重,默认值为`100`(如果宿主机使用旧版的cgroup v1,则为`1024`)。如果你增加了某个VM的此值,调度器会相对于其他权重较低的VM优先考虑它。

例如,如果虚拟机100设置默认值为`100`,而虚拟机200被改变为`200`,那么后者虚拟机200将获得比第一个虚拟机100两倍的CPU带宽。

有关更多信息,请查看`man systemd.resource-control`,此处的`CPUQuota`对应于`cpulimit`,`CPUWeight`对应于我们的`cpuunits`设置。请访问其“注意事项”部分以获取参考资料和实现细节。

亲和力

使用*affinity*选项,您可以指定用于运行VM的vCPUs的物理CPU核心。周边VM进程,如I/O的进程,不会受此设置影响。注意,CPU亲和力不是一项安全功能

在某些情况下强制CPU *亲和性*是有意义的,但这会增加复杂性和维护工作。例如,如果你以后想添加更多的虚拟机(VM)或将虚拟机迁移到CPU核心更少的节点上。如果一些CPU被充分利用而其他CPU几乎处于闲置状态,这也容易导致异步,因此限制了系统的性能。

亲和性通过 taskset CLI 工具进行设置。它接受主机 CPU 号码(参见 lscpu)在 man cpuset 中的 List Format。这个 ASCII 十进制列表可以包含数字,但也包含数字范围。例如,亲和性 0-1,8-11(展开为 0, 1, 8, 9, 10, 11)将允许虚拟机仅在这六个特定的主机核心上运行。

CPU类型

QEMU能够模拟从486到最新的Xeon处理器的许多不同类型的*CPU类型*。每一代新处理器都添加了新特性,比如硬件辅助的3d渲染、随机数生成、内存保护等。此外,当前代处理器可以通过微代码更新进行升级,以修复错误或安全问题。

通常,你应该为你的虚拟机选择一个与主机系统的CPU类型密切匹配的处理器,因为这意味着主机CPU的功能(也称为_CPU标志_)将在你的虚拟机中可用。如果你想要完全匹配,你可以将CPU类型设置为*host*,在这种情况下,虚拟机将拥有与你的主机系统完全相同的CPU标志。

这有一个缺点。如果你想在不同的主机之间进行虚拟机的实时迁移,你的虚拟机可能会最终运行在一个拥有不同CPU类型或不同微代码版本的新系统上。如果传递给客户机的CPU标志缺失,QEMU进程将会停止。为了解决这个问题,QEMU也有其自己的虚拟CPU类型,{pve}默认使用这些类型。

后端默认使用的是’kvm64',它几乎可以在所有x86_64主机CPU上工作,而在创建新虚拟机时用户界面的默认设置是’x86-64-v2-AES',这要求主机CPU至少为英特尔的Westmere架构或AMD的第四代Opteron架构。

简而言之:

如果你不关心实时迁移,或者有一个同构的集群,其中所有节点都有相同的CPU和相同的微代码版本,请将CPU类型设置为主机,因为理论上这将为你的客户端提供最大的性能。

如果你关心实时迁移和安全性,并且你只有Intel CPU或者只有AMD CPU,选择你群集中最低代的CPU型号。

如果你关心在没有安全保护的情况下进行实时迁移,或者拥有混合了Intel/AMD的集群,请选择最低兼容的虚拟QEMU CPU类型。

Note
在Intel和AMD主机CPU之间进行的实时迁移没有保证能够正常工作。

QEMU CPU 类型

QEMU还提供了兼容于Intel和AMD主机CPU的虚拟CPU类型。

Note
为了缓解虚拟CPU类型的Spectre漏洞,你需要添加相关的CPU标志,请参见与Meltdown / Spectre相关的CPU标志

从历史上看,{pve}使用了’kvm64' CPU型号,启用了Pentium 4级别的CPU标志,因此对于某些工作负载来说,性能并不是很好。

在2020年夏天,AMD、Intel、Red Hat和SUSE合作定义了x86-64微结构的三个层次,这些层次建立在x86-64基线之上,并启用了现代标志。详情请参见[x86-64-ABI规范](https://gitlab.com/x86-psABIs/x86-64-ABI)。

Note
一些较新的发行版,如CentOS 9,现在以“x86-64-v2”标志为最低要求进行构建。
  • ''kvm64 (x86-64-v1): 与 Intel CPU >= Pentium 4、AMD CPU >= Phenom 兼容。

  • '‘x86-64-v2’:与 Intel CPU >= Nehalem、AMD CPU >= Opteron_G3 兼容。 与‘x86-64-v1’相比增加的CPU标志:‘+cx16’、‘+lahf-lm’、‘+popcnt’、‘+pni’、‘+sse4.1’、‘+sse4.2’、‘+ssse3’。'

  • ''x86-64-v2-AES: 与 Intel CPU >= Westmere、AMD CPU >= Opteron_G4 兼容。相较于 x86-64-v2 新增 CPU 标志:+aes'

  • '‘x86-64-v3’:兼容 Intel CPU >= Broadwell, AMD CPU >= EPYC。与‘x86-64-v2-AES’相比新增的CPU标志包括:‘+avx’, ‘+avx2’, ‘+bmi1’, ‘+bmi2’, ‘+f16c’, ‘+fma’, ‘+movbe’, ‘+xsave’。'

  • ''x86-64-v4: 兼容 Intel CPU >= Skylake,AMD CPU >= EPYC v4 Genoa。与 x86-64-v3 相比新增的 CPU 标志:+avx512f, +avx512bw, +avx512cd, +avx512dq, +avx512vl'

自定义CPU类型

您可以指定具有可配置功能集的自定义CPU类型。这些在配置文件`/etc/pve/virtual-guest/cpu-models.conf`中由管理员维护。有关格式详细信息,请参见`man cpu-models.conf`。

指定的自定义类型可以被任何拥有`/nodes`上`Sys.Audit`权限的用户选择。通过CLI或API为VM配置自定义CPU类型时,名称需要以’custom-'为前缀。

与Meltdown / Spectre相关的CPU标志

与Meltdown和Spectre漏洞相关的有几个CPU标志需要手动设置,除非你的虚拟机选择的CPU类型已经默认启用了它们。Meltdown攻击参见:https://meltdownattack.com/。

要使用这些CPU标志,需要满足两个要求:

  • 宿主CPU必须支持该功能并将其传播到客户机的虚拟CPU中。

  • 客户操作系统必须更新到一个能够缓解攻击并能够利用CPU功能的版本。

否则,您需要设置虚拟CPU的所需CPU标志,可以通过编辑Web界面中的CPU选项来设置,或者通过在虚拟机配置文件中设置’cpu’选项的’flags’属性来设置。

为了修补 Spectre v1、v2、v4 的漏洞,你的 CPU 或系统供应商还需要为你的 CPU 提供一个所谓的“微码更新”,详见 章节 固件更新。请注意,并非所有受影响的 CPU 都能更新以支持 spec-ctrl。

要检查{pve}主机是否存在漏洞,请以root身份执行以下命令:

for f in /sys/devices/system/cpu/vulnerabilities/*; do echo "${f##*/} -" $(cat "$f"); done

也有一个社区脚本可用于检测主机是否仍然易受攻击。脚注:[spectre-meltdown-checker https://meltdown.ovh/]

英特尔处理器

  • PCI设备ID

    这减少了名为“内核页表隔离(KPTI)”的Meltdown (CVE-2017-5754) 缓解措施对性能的影响,它有效地隐藏了内核内存,使其不被用户空间看到。没有PCID的情况下,KPTI是一个相当昂贵的机制[1]

    要检查{pve}主机是否支持PCID,请以root身份执行以下命令:

    # grep ' pcid ' /proc/cpuinfo

    如果这不返回空值,说明你的主机的CPU支持’pcid'。

  • "spec-ctrl"的中文翻译是“规格控制”。

    需要启用Spectre v1(CVE-2017-5753)和Spectre v2(CVE-2017-5715)修复,在retpolines不足够的情况下。默认包含在带有-IBRS后缀的Intel CPU型号中。对于没有-IBRS后缀的Intel CPU型号,必须明确地开启。需要更新的主机CPU微码(intel-microcode >= 20180425)。

  • ssbd

    要求启用 Spectre V4 (CVE-2018-3639) 修复。默认情况下,任何英特尔CPU型号都不包含此修复。所有英特尔CPU型号都必须明确开启此修复。需要更新的主机CPU微码(intel-microcode >= 20180703)。

AMD处理器

  • 抱歉,"ibpb"看起来不像是一个词或者可以直接翻译的内容。

    要求启用针对Spectre v1(CVE-2017-5753)和Spectre v2(CVE-2017-5715)的修复,在retpolines不足以应对时使用。默认包含在带-IBPB后缀的AMD CPU型号中。对于没有-IBPB后缀的AMD CPU型号,必须明确开启此功能。在它可以用于客户CPU之前,需要宿主CPU微码支持此功能。

  • virt-ssbd

    需要启用Spectre v4 (CVE-2018-3639)修复。在任何AMD CPU型号中默认不包括此修复。必须为所有AMD CPU型号明确打开此项。即使提供了amd-ssbd,为了最大程度的客户兼容性,也应该向客户提供此功能。请注意,在使用“host”cpu模型时,必须明确启用此功能,因为这是一个虚拟功能,实际的CPU中不存在。

  • amd-ssbd

    需要启用Spectre v4 (CVE-2018-3639)修补程序。默认情况下,没有任何AMD CPU型号包含此修补程序。必须为所有AMD CPU型号明确开启此功能。这提供了比virt-ssbd更高的性能,因此,如果可能,支持此功能的主机应始终向客户端展示此功能。尽管如此,为了最大限度地兼容客户端,也应该展示virt-ssbd,因为有些内核只知道virt-ssbd。

  • amd-no-ssb

    建议指示主机不易受到Spectre V4 (CVE-2018-3639) 的攻击。默认情况下,任何AMD CPU型号都不包括此项。未来的硬件CPU代将不会对CVE-2018-3639敏感,因此应通过暴露amd-no-ssb,告知客户端不启用其缓解措施。这与virt-ssbd和amd-ssbd是互斥的。

非一致内存访问

您也可以选择性地在您的虚拟机中模拟 NUMA 架构。NUMA架构的基础意味着,与其拥有一个对所有核心都可用的全局内存池,不如将内存分布在靠近每个插座的本地银行中。这可以带来速度的提升,因为内存总线不再是瓶颈。如果您的系统具有NUMA架构,我们建议激活此选项,因为这将允许在宿主系统上适当分配虚拟机资源。如果运行命令 numactl --hardware | grep available 返回的节点数超过一个,那么您的宿主系统就具有NUMA架构。此选项还必需用于在VM中热插拔核心或RAM。

如果使用了NUMA选项,建议将套接字的数量设置为宿主系统节点的数量。

虚拟CPU热插拔

现代操作系统引入了能力,可以在运行中的系统中热插拔CPU,以及在一定程度上热拔插CPU。虚拟化允许我们避免很多现实硬件在此类情况下可能引起的(物理)问题。然而,这仍然是一个相对较新且复杂的功能,因此其使用应限制在绝对需要的情况下。大部分功能可以通过其他,经过良好测试且不那么复杂的功能复制,参见资源限制

在{pve}中,插入的CPU最大数量总是`核心 * 插槽数`。如果想要以少于这个总核心数的CPU启动虚拟机,你可以使用*vcpus*设置,它表示在虚拟机启动时应该插入多少个虚拟CPU。

目前,这个功能只支持在Linux上,需要高于3.10版本的内核,推荐使用高于4.7版本的内核。

您可以按照下面的udev规则自动将新CPU设置为客户端中的在线状态:

SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"

将此保存在 /etc/udev/rules.d/ 下,文件名以 .rules 结尾。

注意:CPU热移除依赖于机器,并且需要虚拟机的配合。删除命令并不保证CPU的实际移除,通常它是一个通过目标依赖机制转发给客户操作系统的请求,比如在x86/amd64上使用ACPI。

内存

对于每个虚拟机,您可以选择设置固定大小的内存,或要求{pve}根据主机当前的RAM使用情况动态分配内存。

固定内存分配

当将内存和最小内存设置为相同的数量时,{pve} 将简单地分配您指定给虚拟机的数量。

即使在使用固定的内存大小时,气球设备也会被添加到虚拟机中,因为它能提供诸如客户端实际使用了多少内存的有用信息。通常,你应该保留*气球设备*启用状态,但如果你想禁用它(比如出于调试目的),只需取消选中*气球设备*或设置即可。

气球: 0

在配置中。

自动内存分配

当将最小内存设置低于内存时,{pve}将确保您指定的最小数量的内存始终可用于虚拟机,并且如果主机上的RAM使用率低于80%,将动态增加内存给客户端,直到达到指定的最大内存量。

当主机可用RAM不足时,虚拟机会释放一些内存回给主机,如果需要会进行交换正在运行的进程,并且作为最后手段启动oom杀手。主机和客户机之间的内存传递是通过在客户机内运行的特殊的`balloon`内核驱动完成的,该驱动会从主机抓取或释放内存页。脚注:[关于气球驱动内部工作原理的好的解释可以在这里找到 https://rwmj.wordpress.com/2010/07/17/virtio-balloon/]

当多个虚拟机使用自动分配设施时,可以设置一个*Shares*系数,它表示每个虚拟机应该占用的自由主机内存的相对量。假设你有四个虚拟机,其中三个运行HTTP服务器,最后一个是数据库服务器。为了在数据库服务器的RAM中缓存更多的数据库块,你希望在有空闲RAM时给数据库虚拟机优先权。为此,你为数据库虚拟机分配了3000的Shares属性,而将其他虚拟机的Shares设置保留为默认的1000。主机服务器有32GB的RAM,并且当前正在使用16GB,留下32GB。 * 80/100 - 16 = 9GB 的 RAM 需要被分配给虚拟机,作为它们配置的最小内存量之上的内存。数据库虚拟机将从额外的9 * 3000 / (3000 + 1000 + 1000 + 1000) = 4.5 GB 的 RAM 中受益,每个HTTP服务器将从1.5 GB 的 RAM 中受益。

所有在2010年之后发布的Linux发行版都包含了气球内核驱动程序。对于Windows操作系统,气球驱动程序需要手动添加,这可能会导致客户端速度减慢,因此我们不推荐在关键系统上使用它。

当为你的虚拟机分配RAM时,一个好的经验法则是始终为主机留出1GB的RAM。

网络设备

每个虚拟机可以有许多网络接口控制器(NIC),共有四种不同的类型:

  • Intel E1000 是默认的,并模拟了一张英特尔千兆网卡。 如果你追求最大性能,则应使用 VirtIO 半虚拟化的网卡。像所有VirtIO设备一样,客户操作系统应安装适当的驱动程序。 Realtek 8139 模拟了一种较旧的100 MB/s网络卡,只应当在模拟2002年之前发布的旧操作系统时使用。 vmxnet3 是另一种半虚拟化设备,只有在从另一个虚拟机管理程序导入虚拟机时才应该使用。

{pve}将为每个NIC生成一个随机的*MAC地址*,以便您的VM可以在以太网网络上被寻址。

你添加到虚拟机的网络接口卡可以遵循两种不同的模型之一:

在默认的*桥接模式*下,每个虚拟NIC都由主机上的_tap设备_(一种模拟以太网NIC的软件回环设备)支持。这个tap设备被添加到一个桥上,默认情况下是{pve}中的vmbr0。在这种模式下,虚拟机可以直接访问主机所在的以太网LAN。 在备选的*NAT模式*下,每个虚拟网卡只能与QEMU用户网络堆栈通信,其中内置的路由器和DHCP服务器可以提供网络访问。这个内置的DHCP将在私有的10.0.2.0/24范围内分配地址。NAT模式比桥接模式要慢得多,只应该用于测试。这种模式仅通过CLI或API可用,不能通过网页UI使用。

在创建VM时,您也可以通过选择*No network device*来跳过添加网络设备。

您可以为每个VM网络设备覆写*MTU*设置。选项`mtu=1`代表一种特殊情况,在这种情况下,MTU值将从底层桥继承。这个选项只适用于*VirtIO*网络设备。

多队列

如果你正在使用VirtIO驱动,你可以选择性地激活*多队列*选项。这个选项允许来宾操作系统使用多个虚拟CPU处理网络数据包,从而提高了数据包传输的总数量。

当在{pve}中使用VirtIO驱动时,每个NIC网络队列都会被传递到宿主内核,在那里队列将由vhost驱动生成的内核线程处理。通过激活这个选项,可以将每个NIC的_多个_网络队列传递给宿主内核。

当使用Multiqueue时,建议将其值设置为与您的客户端相同的vCPUs数量。请记住,vCPUs的数量等于为虚拟机配置的插槽数量与核心数的乘积。您还需要使用此ethtool命令,在虚拟机中的每个VirtIO NIC上设置多用途通道的数量:

ethtool -L ens1 combined X

其中X是虚拟机的vCPU数量。

要为Multiqueue配置Windows客户端,请安装https://pve.proxmox.com/wiki/Windows_VirtIO_Drivers[Redhat VirtIO Ethernet Adapter驱动程序],然后按照以下步骤调整NIC的配置。打开设备管理器,右键点击“网络适配器”下的NIC,并选择“属性”。然后打开“高级”选项卡,从左侧列表中选择“接收端缩放”(Receive Side Scaling)。确保其设置为“启用”。接下来,在列表中找到“RSS队列的最大数量”并将其设置为您的虚拟机的vCPU数量。一旦确认设置正确,点击“确定”以确认它们。

您应该注意,将Multiqueue参数设置为大于1的值会随着流量增加而增加主机和客户系统的CPU负载。我们建议仅在虚拟机需要处理大量传入连接时才设置此选项,例如当虚拟机作为路由器、反向代理或繁忙的HTTP服务器进行长轮询时。

显示

QEMU可以虚拟化几种类型的VGA硬件。一些例子包括:

  • std,默认值,模拟带有Bochs VBE扩展的显卡。

  • cirrus,这曾是默认设置,它模拟一个非常旧的硬件模块及其所有问题。这种显示类型只应在确实必要时使用,例如,如果使用Windows XP或更早版本。参考链接:[https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/ qemu: 使用cirrus被认为是有害的]

  • 'vmware,是一个与VMWare SVGA-II兼容的适配器。'

  • qxl,是QXL虚拟化显卡。选择此选项还将为虚拟机启用https://www.spice-space.org/[SPICE](一个远程查看协议)。

  • virtio-gl,通常被称为VirGL,是一种用于虚拟机内部的虚拟3D GPU,它可以将工作负载卸载到主机GPU,而不需要特殊(昂贵)的模型和驱动程序,也不需要完全绑定主机GPU,允许在多个客户端之间或与主机共同使用。

    Note
    VirGL 支持需要一些额外的库,这些库默认情况下不会安装,因为它们相对较大,而且并不是对所有GPU型号/供应商都开放源代码。对于大多数设置,你只需要执行:`apt install libgl1 libegl1

您可以通过设置’memory’选项,来编辑分配给虚拟GPU的内存量。这可以在虚拟机内启用更高的分辨率,特别是使用SPICE/QXL时。

由于内存被显示设备占据,为SPICE选择多显示器模式(例如,`qxl2`用于双显示器)会有一些影响:

  • Windows需要每个显示器都有一个设备,所以如果你的’ostype’是某个版本的Windows,{pve}会为虚拟机每个显示器提供一个额外的设备。每个设备都会获得指定数量的内存。

  • Linux虚拟机总是可以启用更多的虚拟显示器,但选择多显示器模式会将分配给设备的内存乘以显示器的数量。

选择`serialX`作为显示’type’会禁用VGA输出,并将网页控制台重定向到所选的串行端口。在这种情况下,配置的显示’memory’设置将被忽略。

VNC 剪贴板

你可以通过将`clipboard`设置为`vnc`来启用VNC剪贴板。

# qm set <vmid> -vga <displaytype>,clipboard=vnc

要使用剪贴板功能,您必须首先安装SPICE客户端工具。在基于Debian的发行版上,可以通过安装`spice-vdagent`来实现。对于其他操作系统,请在官方仓库中搜索,或查看:https://www.spice-space.org/download.html

一旦您安装了spice客户工具,您就可以使用VNC剪贴板功能(例如,在noVNC控制面板中)。然而,如果您正在使用SPICE、virtio或virgl,您将需要选择使用哪个剪贴板。这是因为如果`clipboard`设置为`vnc`,默认的*SPICE*剪贴板将被*VNC*剪贴板替换。

USB直通

有两种不同类型的USB直通设备:

  • 宿主机USB直通

  • SPICE USB 透传

主机USB直通作用是通过将主机的USB设备给予虚拟机来实现的。这可以通过供应商和产品ID完成,也可以通过主机总线和端口完成。

供应商/产品ID的格式如下:0123:abcd,其中*0123*是供应商的ID,*abcd*是产品的ID,意味着同一USB设备的两个部件有相同的ID。

总线/端口的表示格式如下:1-2.3.4,其中*1*代表总线,*2.3.4*代表端口路径。这代表了主机的物理端口(取决于USB控制器内部的顺序)。

如果在虚拟机(VM)启动时配置中存在某个设备,但该设备在宿主机上不存在,虚拟机可以无问题地启动。一旦设备/端口在宿主机上可用,它就会被直接传递。

Warning
使用这种USB直通方式意味着您不能在线将虚拟机移到另一个主机上,因为硬件仅在虚拟机当前所在的主机上可用。

第二种类型的透传是SPICE USB透传。如果你在虚拟机中添加了一个或多个SPICE USB端口,你可以动态地将本地USB设备从你的SPICE客户端透传到虚拟机中。这可以用来临时重定向输入设备或硬件加密狗。

它还可以在集群级别映射设备,以便它们可以与HA正确使用,同时检测到硬件变化,非根用户可以配置它们。有关详细信息,请参见资源映射

BIOS和UEFI

为了正确模拟计算机,QEMU需要使用固件。在常见的PC上,这通常被称为BIOS或(U)EFI,是启动虚拟机时最先执行的步骤之一。它负责进行基础硬件初始化,并为操作系统提供对固件和硬件的接口。默认情况下,QEMU使用*SeaBIOS*,这是一个开源的x86 BIOS实现。SeaBIOS是大多数标准设置的一个好选择。

一些操作系统(例如Windows 11)可能需要使用与UEFI兼容的实现。在这种情况下,你必须使用*OVMF*,它是一个开源的UEFI实现。脚注:[参见OVMF项目 https://github.com/tianocore/tianocore.github.io/wiki/OVMF]

有些情况下,SeaBIOS可能不是从中启动的理想固件,例如,如果你想进行VGA直通。脚注:[Alex Williamson在这方面有一篇很好的博客文章 https://vfio.blogspot.co.at/2014/08/primary-graphics-assignment-without-vga.html]

如果你想要使用OVMF,有几件事需要考虑:

为了保存如*启动顺序*之类的设置,需要有一个EFI磁盘。这个磁盘将被包括在备份和快照中,而且只能有一个。

你可以使用以下命令来创建这样一个磁盘:

# qm set <vmid> -efidisk0 <storage>:1,format=<format>,efitype=4m,pre-enrolled-keys=1

其中*<storage>*是您希望存储磁盘的位置,而*<format>*是该存储支持的格式。或者,您可以在虚拟机的硬件部分通过点击’添加' → 'EFI磁盘’通过web界面创建这样一个磁盘。

efitype 选项指定了应使用哪个版本的OVMF固件。对于新的虚拟机,应始终选择'4m',因为它支持安全启动并且分配了更多空间以支持未来的开发(这是GUI中的默认设置)。

'pre-enroll-keys 指定 efidisk 是否应预装有特定于发行版的和微软标准安全启动密钥。它还默认启用安全启动(尽管仍可以在 VM 内的 OVMF 菜单中禁用)。'

Note
如果您想在现有的虚拟机中开始使用Secure Boot(该虚拟机仍使用'2m' efidisk),您需要重新创建efidisk。为此,请删除旧的efidisk(qm set <vmid> -delete efidisk0)并按上述描述添加一个新的。这将重置您在OVMF菜单中所做的任何自定义配置!

当使用OVMF与虚拟显示器(没有VGA直通)时,你需要在OVMF菜单中设置客户端分辨率(你可以在启动期间按ESC按钮到达这个菜单),或者你必须选择SPICE作为显示类型。

可信平台模块(TPM)

受信任平台模块是一个设备,用于安全地存储秘密数据(如加密密钥),并提供防篡改功能以验证系统启动。

某些操作系统(例如Windows 11)要求将此类设备连接到机器(无论是实体还是虚拟的)。

通过指定一个*tpmstate*卷来添加TPM。这与efidisk类似,一旦创建,就不能更改(只能移除)。您可以通过以下命令添加一个:

# qm set <vmid> -tpmstate0 <storage>:1,version=<version>

''其中 <storage> 是您想要将状态存储在哪里,而 <version> 可以是 'v1.2v2.0。您也可以通过网络界面添加一个,方法是在虚拟机的硬件部分选择 AddTPM State'

TPM规范的’v2.0’版是更新且支持更好的,所以除非你有特定的实现需要’v1.2’版的TPM,否则应该优先考虑’v2.0’版。

Note
与物理TPM相比,模拟的TPM并不提供任何真正的安全好处。TPM的要点是,其中的数据不易被修改,除非通过TPM规范中指定的命令。由于模拟设备的数据存储发生在常规卷上,任何有权限访问它的人都可能编辑这些数据。

虚拟机间共享内存

您可以添加一个虚拟机间共享内存设备(ivshmem),这允许您在宿主机与一个客户机之间,或者多个客户机之间共享内存。

要添加这种设备,你可以使用 qm

# qm set <vmid> -ivshmem size=32,name=foo

其中大小以MiB为单位。文件将位于`/dev/shm/pve-shm-$name`下(默认名称为vmid)。

Note
目前,只要任何使用该设备的虚拟机被关闭或停止,该设备就会立即被删除。已打开的连接仍将持续,但无法再建立到同一设备的新连接。

此设备的一个使用案例是Looking Glass项目(脚注:Looking Glass: https://looking-glass.io/),它允许在主机和客户机之间进行高性能、低延迟的显示镜像。

音频设备

要添加一个音频设备,请运行以下命令:

qm set <vmid> -audio0 device=<device>

受支持的音频设备有:

  • ich9-intel-hda`:Intel HD Audio Controller,模拟ICH9

  • intel-hda`:Intel HD Audio控制器,模拟ICH6

  • AC97`:音频编解码器'97,适用于像Windows XP这样的较早的操作系统

有两个后端可用:

  • 香料

''The 'spice backend can be used in combination with SPICE while the none backend can be useful if an audio device is needed in the VM for some software to work. To use the physical audio device of the host use device passthrough (see PCI Passthrough and USB Passthrough). Remote protocols like Microsoft’s RDP have options to play sound.' 可以结合SPICE使用’spice’后端,而如果某些软件需要在虚拟机(VM)中使用音频设备,则’none’后端可能会很有用。要使用宿主机的物理音频设备,请使用设备直通技术(参见PCI直通USB直通)。像Microsoft的RDP这样的远程协议有播放声音的选项。

VirtIO RNG

RNG(随机数生成器)是一个为系统提供熵("随机性")的设备。虚拟硬件RNG可以用来从宿主系统向客户机虚拟机提供此类熵。这有助于避免客户机中的熵饥饿问题(一种情况是可用熵不足,系统可能会变慢或遇到问题),特别是在客户机的启动过程中。

要添加基于VirtIO的仿真RNG,请运行以下命令:

qm set <vmid> -rng0 source=<source>[,max_bytes=X,period=Y]

source`指定了在主机上从哪里读取熵值,必须是以下之一:

  • /dev/urandom`:非阻塞内核熵池(首选)

  • /dev/random`:阻塞内核池(不推荐,可能导致宿主系统的熵耗尽)

  • /dev/hwrng`: 用于通过连接到主机的硬件随机数生成器(如果有多个可用的,将使用 /sys/devices/virtual/misc/hw_random/rng_current 中选择的那个)

限制可以通过`max_bytes`和`period`参数来指定,它们被读作每`period`毫秒`max_bytes`字节。然而,这并不代表一个线性关系:1024B/1000ms意味着每1秒钟最多有1 KiB的数据变得可用,而不是说1 KiB的数据会在一秒钟内流向客户端。因此,减少`period`可以用来以更快的速度向客户端注入熵。

默认情况下,限制被设置为每1000毫秒(1 KiB/s)1024字节。建议总是使用限制器以避免客人使用过多的主机资源。如果需要,可以使用‘0’作为`max_bytes`的值来禁用所有限制。

设备启动顺序

QEMU可以告诉客户机它应该从哪些设备启动,以及启动的顺序。这可以通过配置中的`boot`属性来指定,例如:

boot: order=scsi0;net0;hostpci0

这样,客人会首先尝试从磁盘`scsi0`启动,如果失败了,它会继续尝试从`net0`进行网络启动,如果那也失败了,最后尝试从传递的PCIe设备启动(如果是NVMe的话,视为磁盘,否则尝试进入选项ROM)。

在GUI上,您可以使用拖放编辑器来指定启动顺序,并使用复选框来启用或禁用某些设备的整体启动。

Note
如果您的访客使用多个磁盘引导操作系统或加载引导程序,所有这些磁盘都必须标记为“可引导”的(也就是说,它们必须启用复选框或在配置列表中显示),以便访客能够启动。这是因为最近的SeaBIOS和OVMF版本只有在磁盘被标记为“可引导”的情况下才会初始化磁盘。

在任何情况下,即使设备没有出现在列表中或没有启用复选标记,一旦其操作系统启动并初始化它们,这些设备仍然会对客户机可用。'bootable’标志只影响客户机的BIOS和引导加载程序。

虚拟机的自动启动和关闭

在创建虚拟机(VMs)之后,您可能希望它们在主机系统启动时自动启动。为此,您需要在网络界面中的虚拟机“选项”选项卡中选择“启动时自动启动”选项,或者使用以下命令进行设置:

# qm set <vmid> -onboot 1
启动和关闭顺序

在某些情况下,您可能希望能够微调虚拟机的引导顺序,例如,如果您的某个虚拟机为其他客户机系统提供防火墙或DHCP服务。为此,您可以使用以下参数:

  • 启动/关闭顺序:定义启动顺序的优先级。例如,如果您希望虚拟机(VM)首先启动,请将其设置为1。(我们使用反向启动顺序进行关闭,因此启动顺序为1的机器将是最后一个被关闭的)。如果同一宿主机上有多个虚拟机(VM)定义了相同的顺序,它们还将按照“VMID”以升序进行排序。

  • 启动延迟:定义了该虚拟机启动与后续虚拟机启动之间的间隔时间。例如,如果你希望在启动其他虚拟机前等待240秒,就将其设置为240。

  • 关闭超时:定义在发出关闭指令后,{pve}应等待虚拟机离线的时间(以秒为单位)。默认值设置为180,这意味着{pve}将发出关闭请求,并等待180秒以确保机器离线。如果超时后机器仍然在线,它将被强制停止。

Note
由HA栈管理的VM当前不遵循’启动时启动’和’启动顺序’选项。这些VM将被启动和关闭算法跳过,因为HA管理器本身确保VM得到启动和停止。

请注意,没有设置启动/关闭顺序参数的机器将始终在设置了该参数的机器之后启动。此外,这个参数只能在运行在同一主机上的虚拟机之间强制实施,而不能在整个集群范围内实施。

如果您需要在主机启动和第一个虚拟机启动之间设置延迟,请参考Proxmox VE节点管理一节。

QEMU 客户端代理

QEMU Guest Agent是一种在虚拟机内运行的服务,它提供了宿主机与客户机之间的通信渠道。它用于交换信息,并允许宿主机向客户机发送命令。

例如,VM摘要面板中的IP地址是通过访客代理获取的。

当开始备份时,通过客户端代理告知客户端使用’fs-freeze’和’fs-thaw’命令同步未完成的写入操作。

为了让宾客代理正常工作,必须采取以下步骤:

  • 在客户机中安装代理并确保它正在运行

  • 通过代理在 {pve} 中启用通信

安装访客代理

对于大多数Linux发行版,客户端代理是可用的。该软件包通常被命名为`qemu-guest-agent`。

对于Windows,可以从Fedora VirtIO驱动程序ISO(https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso)中安装。

启用来宾代理通信

从{pve}到客户端代理的通讯可以在虚拟机的*选项*面板中启用。需要重新启动虚拟机以使更改生效。

使用QGA的自动修剪

可以启用 Run guest-trim 选项。启用此选项后,{pve} 将在以下可能将零写入存储的操作后向客户端发出 trim 命令:

  • 将磁盘移动到另一个存储器

  • 将带有本地存储的虚拟机实时迁移到另一个节点

在一个精简配置的存储上,这可以帮助释放未使用的空间。

Note
在Linux上使用ext4文件系统时存在一个注意事项,因为它使用了一种内存中的优化机制来避免发出重复的TRIM请求。由于客户端不知道底层存储的变化,因此只有第一次的客户端trim操作会按预期执行。直到下一次重启之前,后续的操作只会考虑自那以后发生改变的文件系统部分。

文件系统在备份时的冻结与解冻

默认情况下,当执行备份时,通过’fs-freeze' QEMU Guest Agent命令同步来宾文件系统,以确保一致性。

在Windows客户机上,一些应用程序可能通过挂接到Windows VSS(卷影复制服务)层自行处理一致性备份,这时候进行“文件系统冻结”可能会干扰这一过程。例如,已经观察到,在某些SQL服务器上调用“文件系统冻结”会触发VSS调用SQL编写器VSS模块以一种破坏SQL服务器差异备份链的模式。

对于这种设置,你可以通过设置 freeze-fs-on-backup QGA选项为 0 来配置 {pve},以便在备份时不进行冻结和解冻循环。这也可以通过GUI完成,使用’备份时冻结/解冻客户操作系统文件系统以保持一致性’选项。

Important
禁用此选项可能导致备份中的文件系统不一致,因此只有在你确切知道自己在做什么的情况下才应该禁用。

故障排除

虚拟机无法关闭

请确保客户端代理已安装并正在运行。

一旦启用了客户机代理,{pve} 将通过客户机代理发送像 shutdown 这样的电源命令。如果客户机代理未运行,命令将无法正确执行,shutdown 命令将会遇到超时。

SPICE增强功能

SPICE增强功能是可选特性,可以改善远程查看者的体验。

要通过图形用户界面启用它们,请转到虚拟机的*选项*面板。通过命令行界面启用它们,请运行以下命令:

qm set <vmid> -spice_enhancements foldersharing=1,videostreaming=all
Note
要使用这些功能,虚拟机的显示必须设置为SPICE (qxl)。

文件夹共享

与客户端共享一个本地文件夹。需要在客户端安装`spice-webdavd`守护进程。这使得通过位于http://localhost:9843的本地WebDAV服务器可以访问共享文件夹。

对于Windows客户端,'Spice WebDAV守护程序’的安装程序可以从[官方SPICE网站](https://www.spice-space.org/download.html#windows-binaries)下载。

大多数Linux发行版都有一个名为`spice-webdavd`的包可以安装。

在Virt-Viewer(远程查看器)中共享文件夹,请转到“文件 → 偏好设置”。选择要共享的文件夹,然后启用复选框。

Note
文件夹共享目前仅在Virt-Viewer的Linux版本中有效。
Caution
实验性的!目前这项功能无法可靠工作。

视频流

快速刷新区域被编码到视频流中。存在两个选项:

  • 任何快速刷新的区域将被编码成视频流。

  • filter:附加过滤器用于决定是否应该使用视频流(当前仅跳过小窗口表面)。

无法给出是否应该启用视频流和选择哪个选项的一般建议。根据具体情况的不同,效果可能会有所不同。

故障排除

共享文件夹未显示

请确保在客户机中启用并运行WebDAV服务。在Windows中,它被称为’Spice webdav proxy'。在Linux中,名称是’spice-webdavd',但取决于不同的发行版,名称可能有所不同。

如果服务正在运行,请通过在客户端的浏览器中打开 http://localhost:9843 来检查 WebDAV 服务器。

重启SPICE会话可以帮助解决问题。

移民

如果你有一个集群,你可以将你的虚拟机迁移到另一个主机上

# qm migrate <vmid> <target>

这通常有两种机制。

  • 在线迁移(又称实时迁移)

  • 离线迁移

在线迁移

如果您的虚拟机正在运行,并且没有配置本地绑定的资源(例如通过的设备),您可以在执行 qm migration 命令时使用 --online 标志来启动实时迁移。当VM运行时,Web界面默认为实时迁移。

它是如何工作的

在线迁移首先在目标主机上启动一个带有’incoming’标志的新QEMU进程,该进程仅执行带有暂停状态的客户虚拟CPU的基本初始化,然后等待来自源虚拟机的客户内存和设备状态数据流。其它所有资源,如磁盘,要么是共享的,要么在虚拟机运行时状态迁移开始之前就已经发送;因此,只剩下内存内容和设备状态需要被传输。

一旦这种连接建立,源开始异步发送内存内容到目标。如果源上的客户机内存发生变化,那些部分就会被标记为脏数据,然后再进行一次传送客户机内存数据的过程。这个循环重复进行,直到运行中的源虚拟机(VM)与即将到来的目标虚拟机(VM)之间的数据差异足够小,可以在几毫秒内发送,因为那时源虚拟机可以被完全暂停,而不会让用户或程序察觉到这次暂停,以便将剩余数据发送到目标,然后取消目标虚拟机CPU的暂停,使其在不到一秒的时间内成为新的运行中虚拟机。

要求

要使实时迁移工作,需要满足一些条件:

  • 虚拟机没有不能迁移的本地资源。例如,目前通过的PCI或USB设备会阻止实时迁移。另一方面,本地磁盘可以通过将它们发送到目标来进行迁移。

  • 主机位于同一个 {pve} 集群中。

  • 主机之间有一个工作中(并且可靠的)网络连接。

  • 目标主机必须拥有相同或更高版本的 {pve} 包。虽然有时候反向操作也可能有效,但这并不能得到保证。

  • 主机拥有来自同一供应商的具有相似功能的CPU。不同供应商的产品*可能*会根据实际型号和配置的虚拟机CPU类型而工作,但不能保证,所以在生产环境部署此类设置之前请进行测试。

离线迁移

如果您拥有本地资源,只要所有磁盘都存储在两个主机上定义的存储上,您仍然可以离线迁移您的虚拟机。迁移过程会通过网络将磁盘复制到目标主机,就像在线迁移一样。请注意,任何硬件直通配置可能需要根据目标主机上的设备位置进行调整。

副本和克隆

虚拟机的安装通常使用操作系统供应商提供的安装介质(CD-ROM)完成。根据操作系统的不同,这可能是一个耗时的任务,人们可能想要避免。

一种部署许多相同类型虚拟机(VM)的简单方式是复制一个现有的VM。我们使用“克隆”一词来描述这样的副本,并区分“链接克隆”和“完整克隆”。

完全克隆

这种复制的结果是一个独立的虚拟机。新的虚拟机不会与原始虚拟机共享任何存储资源。

可以选择一个*目标存储*,因此可以使用它将虚拟机迁移到完全不同的存储上。如果存储驱动支持多种格式,您还可以更改磁盘镜像的*格式*。

Note
完整克隆需要读取并复制所有虚拟机镜像数据。这通常比创建一个链接克隆要慢得多。

某些存储类型允许复制一个特定的*快照*,默认为“当前”的虚拟机数据。这也意味着,最终复制的数据从不包含原始虚拟机的任何额外快照。

链接克隆

现代存储驱动器支持一种生成快速链接克隆的方法。这样的克隆是一个可写的副本,其初始内容与原始数据相同。创建一个链接克隆几乎是瞬间的,并且最初不消耗额外空间。

它们被称为“链接”,因为新图像仍然引用原始图像。未修改的数据块从原始图像中读取,但修改内容被写入(并且之后从)新的位置读取。这项技术被称为“写时复制”。

这要求原始卷是只读的。使用 {pve},可以将任何虚拟机转换为只读的模板。这样的模板后续可以高效地用来创建链接克隆。

Note
如果存在链接克隆,您不能删除原始模板。

无法更改链接克隆的*目标存储*,因为这是存储内部特性。

"The Target node 选项允许您在不同的节点上创建新的虚拟机。唯一的限制是虚拟机位于共享存储上,且该存储也在目标节点上可用。"

为了避免资源冲突,所有网络接口MAC地址都会被随机化,并且我们为VM BIOS (smbios1) 设置生成一个新的’UUID'。

虚拟机模板

可以将虚拟机转换成模板。这些模板是只读的,你可以使用它们来创建链接克隆。

Note
无法启动模板,因为这会修改磁盘映像。如果您想更改模板,请创建一个链接克隆并修改它。

虚拟机生成ID

'{pve} 支持虚拟机生成 ID (vmgenid) 脚注:[官方 vmgenid 规范 https://docs.microsoft.com/en-us/windows/desktop/hyperv_v2/virtual-machine-generation-identifier] 对于虚拟机。这可以被客户操作系统用来检测任何导致时间偏移事件的事件,例如,恢复备份或者快照回滚。'

当创建新的虚拟机时,一个’vmgenid’将会自动生成并保存在其配置文件中。

要为已经存在的虚拟机创建并添加一个’vmgenid',可以传递特殊值`1`让{pve}自动生成一个,或者使用在线GUID生成器http://guid.one/ 手动设置’UUID’作为值,例如:

# qm set VMID -vmgenid 1
# qm set VMID -vmgenid 00000000-0000-0000-0000-000000000000
Note
向现有虚拟机初次添加’vmgenid’设备,可能会产生与快照回滚、备份恢复等操作相同的效果,因为虚拟机可以将此解释为代际更改。

在极少数情况下,如果不需要’vmgenid’机制,可以在创建VM时为其值传递`0`,或者通过以下方式在配置中事后删除该属性:

# qm set VMID -delete vmgenid

“vmgenid”的最显著用途是在较新版本的Microsoft Windows操作系统中使用,它利用这一功能来避免在时间敏感或需要复制的服务(如数据库或域控制器[2])在快照回滚、备份还原或整个虚拟机克隆操作中出现问题。

导入虚拟机

从外部虚拟机管理程序或其他{pve}集群导入现有虚拟机可以通过各种方法实现,最常见的方法有:

  • 使用原生导入向导,它利用“import”内容类型,如ESXi特殊存储所提供的。

  • 在源端执行备份,然后在目标端进行恢复。当从另一个{pve}实例迁移时,这种方法效果最好。

  • 使用`qm`命令行工具的OVF特定导入命令。

如果你从其他虚拟机监控器(hypervisors)导入虚拟机到{pve},推荐你熟悉{pve}的[概念](https://pve.proxmox.com/wiki/Migrate_to_Proxmox_VE#Concepts)。

导入向导

{pve}通过使用存储插件系统提供了一个集成的VM导入器,以原生方式集成到API和基于web的用户界面中。您可以使用这个功能将VM作为一个整体导入,其大部分配置都映射到{pve}的配置模型中,并且减少了停机时间。

Note
导入向导是在{pve} 8.2开发周期期间添加的,并处于技术预览状态。虽然它已经很有前景并且稳定工作,但它仍在积极开发之中,重点是在将来添加其他导入来源,例如OVF/OVA文件。

要使用导入向导,你首先必须为导入源设置一个新的存储空间,你可以在网页界面下的 Datacenter → Storage → Add 中进行设置。

然后您可以在资源树中选择新的存储,并使用“虚拟客户机”内容标签查看所有可导入的客户机。

选择一个,并使用’导入’按钮(或双击)打开导入向导。您可以在这里修改部分可用选项,然后开始导入。请注意,在导入完成后,您可以进行更高级的修改。

Tip
导入向导目前(2024-03)适用于ESXi,并且已经过ESXi版本6.5至8.0的测试。请注意,使用vSAN存储的客户机不能直接导入;必须先将它们的磁盘移至其他存储。虽然可以使用vCenter作为导入源,但性能会大幅下降(慢5到10倍)。

为了获得逐步指导以及关于如何将虚拟客户端适配到新的超级管理程序的技巧,请参考我们的https://pve.proxmox.com/wiki/Migrate_to_Proxmox_VE#Migration[迁移到{pve}维基文章]。

通过命令行界面导入OVF/OVA

从外部虚拟机管理程序导出的虚拟机(VM)通常采用一个或多个磁盘映像的形式,伴随一个配置文件描述虚拟机的设置(RAM、核心数)。 磁盘映像可以是vmdk格式,如果磁盘来自VMware或VirtualBox,或者是qcow2格式,如果磁盘来自KVM虚拟机管理程序。 对于虚拟机导出,最流行的配置格式是OVF标准,但实际上互操作性有限,因为许多设置并未在标准本身中实现,而且各虚拟机管理程序会在非标准扩展中导出额外的信息。

除了格式问题之外,如果模拟的硬件从一个虚拟机监控程序更改到另一个时变化太大,那么从其他虚拟机监控程序导入磁盘映像可能会失败。Windows虚拟机特别关注这一点,因为操作系统对任何硬件变化都非常挑剔。通过在导出前从互联网上安装可用的MergeIDE.zip工具并选择*IDE*类型的硬盘在引导导入的Windows虚拟机前,可以解决这个问题。

最后还有关于半虚拟化驱动的问题,这些驱动可以提高模拟系统的速度,并且特定于超级管理程序。GNU/Linux和其他免费的Unix操作系统默认安装了所有必要的驱动程序,您可以在导入虚拟机后立即切换到半虚拟化驱动。对于Windows虚拟机,您需要自行安装Windows半虚拟化驱动。

GNU/Linux 和其他免费的 Unix 系统通常可以轻松导入。请注意,由于上述问题,我们无法保证在所有情况下都能成功导入/导出 Windows 虚拟机。

Windows OVF导入的分步示例

微软提供了 虚拟机下载 以开始Windows开发。我们将使用其中一个 来展示OVF导入功能。

下载虚拟机压缩包

在了解用户协议后,选择适用于VMware平台的_Windows 10 Enterprise (Evaluation - Build)_,并下载zip文件。

从压缩文件中提取磁盘映像

使用 unzip 工具或您选择的任何压缩文件解压缩程序,解压zip文件,并通过ssh/scp将ovf和vmdk文件复制到您的{pve}主机。

导入虚拟机

这将创建一个新的虚拟机,使用从OVF清单中读取的核心、内存和VM名称,并将磁盘导入到+local-lvm+存储中。你必须手动配置网络。

# qm importovf 999 WinDev1709Eval.ovf local-lvm

虚拟机已经准备好启动了。

将外部磁盘映像添加到虚拟机

你也可以将现有的磁盘映像添加到虚拟机中,无论是来自其他虚拟机管理程序的,还是你自己创建的。

假设你用’vmdebootstrap’工具创建了一个Debian/Ubuntu磁盘映像:

vmdebootstrap --verbose \ --size 10GiB --serial-console \ --grub --no-extlinux \ --package openssh-server \ --package avahi-daemon \ --package qemu-guest-agent \ --hostname vm600 --enable-dhcp \ --customize=./copy_pub_ssh.sh \ --sparse --image vm600.raw

您现在可以创建一个新的目标虚拟机,将镜像导入到存储 pvedir 并将其连接到虚拟机的SCSI控制器:

# qm create 600 --net0 virtio,bridge=vmbr0 --name vm600 --serial0 socket \
   --boot order=scsi0 --scsihw virtio-scsi-pci --ostype l26 \
   --scsi0 pvedir:0,import-from=/path/to/dir/vm600.raw

虚拟机已经准备好启动了。

Cloud-Init 支持

''Cloud-Init 是一个事实上的多发行版软件包,它负责虚拟机实例的早期初始化。使用 Cloud-Init,可以在虚拟机管理程序一侧配置网络设备和 ssh 密钥。当 VM 首次启动时,VM 内部的 Cloud-Init 软件将会应用这些设置。''

许多Linux发行版提供了现成可用的Cloud-Init镜像,这些镜像主要设计用于’OpenStack'。这些镜像也能与{pve}一起使用。虽然获取这类现成镜像看起来很方便,但我们通常建议自己准备镜像。其优势在于您将确切知道自己安装了什么,这有助于您之后根据需求轻松定制镜像。

一旦你创建了这样一个Cloud-Init镜像,我们建议将其转换为虚拟机模板。从虚拟机模板,你可以快速创建链接克隆,因此这是快速部署新虚拟机实例的方法。你只需要在启动新的虚拟机之前配置网络(可能还有ssh密钥)。

我们推荐使用基于SSH密钥的身份验证方式来登录由Cloud-Init配置的虚拟机。也可以设置密码,但这种方式不如使用基于SSH密钥的身份验证安全,因为{pve}需要在Cloud-Init数据中存储该密码的加密版本。

{pve} 会生成一个 ISO 镜像以将 Cloud-Init 数据传递给虚拟机。为此,所有的 Cloud-Init 虚拟机都需要分配一个 CD-ROM 驱动器。通常,应当添加并使用串行控制台作为显示器。许多 Cloud-Init 镜像依赖于此,这是 OpenStack 的一个要求。然而,其他镜像可能无法适用此配置。如果使用串行控制台不起作用,请切回默认的显示配置。

准备 Cloud-Init 模板

第一步是准备你的虚拟机。基本上你可以使用任何虚拟机。只需在你想要准备的虚拟机*内部*安装Cloud-Init包。在基于Debian/Ubuntu的系统上,这个操作简单到如下所示:

apt-get install cloud-init
Warning
这个命令*不*是为了在 {pve} 主机上执行,而是仅在虚拟机内部执行。

已有许多发行版提供了现成的Cloud-Init镜像(以`.qcow2`文件形式提供),因此,您也可以简单地下载并导入此类镜像。在接下来的例子中,我们将使用由Ubuntu在https://cloud-images.ubuntu.com提供的云镜像。

# download the image
wget https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img

# create a new VM with VirtIO SCSI controller
qm create 9000 --memory 2048 --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci

# import the downloaded disk to the local-lvm storage, attaching it as a SCSI drive
qm set 9000 --scsi0 local-lvm:0,import-from=/path/to/bionic-server-cloudimg-amd64.img
Note
Ubuntu Cloud-Init镜像要求SCSI驱动器使用`virtio-scsi-pci`控制器类型。
添加 Cloud-Init CD-ROM 驱动器

下一步是配置一个CD-ROM驱动器,它将用于将Cloud-Init数据传递给虚拟机。

qm set 9000 --ide2 local-lvm:cloudinit

为了能够直接从Cloud-Init镜像启动,设置`boot`参数为`order=scsi0`以限制BIOS仅从此硬盘启动。这将加快启动速度,因为VM BIOS会跳过测试可启动CD-ROM的步骤。

qm set 9000 --boot order=scsi0

对于许多Cloud-Init镜像,需要配置串行控制台并使用它作为显示器。如果配置对给定的镜像不起作用,那么切换回默认显示器。

qm set 9000 --serial0 socket --vga serial0

在最后一步中,将虚拟机转换成模板是很有帮助的。从这个模板你可以快速创建链接克隆。从虚拟机模板部署比创建一个完整的克隆(拷贝)要快得多。

qm模版 9000

部署云初始化模板

你可以通过克隆来轻松部署这样一个模板:

qm clone 9000 123 --name ubuntu2

然后配置用于认证的SSH公钥,并配置IP设置:

qm set 123 --sshkey ~/.ssh/id_rsa.pub
qm set 123 --ipconfig0 ip=10.0.10.123/24,gw=10.0.10.1

您也可以仅使用一个命令配置所有Cloud-Init选项。我们只是将上述示例分开,以分离命令来减少行长度。另外,请确保根据您的特定环境调整IP设置。

自定义 Cloud-Init 配置

Cloud-Init集成还允许使用自定义配置文件代替自动生成的配置。这是通过命令行上的`cicustom`选项来完成的:

qm set 9000 --cicustom "user=<volume>,network=<volume>,meta=<volume>"

自定义配置文件必须存储在支持片段的存储上,并且必须在虚拟机将要迁移到的所有节点上可用。否则,虚拟机将无法启动。例如:

qm set 9000 --cicustom "user=local:snippets/userconfig.yaml"

Cloud-Init 有三种配置类型。第一种是上面示例中看到的 user 配置。第二种是 network 配置,第三种是 meta 配置。它们可以一起指定,或者根据需要混合和匹配。对于没有指定自定义配置文件的配置,将使用自动生成的配置。

生成的配置可以被转储,用作自定义配置的基础:

qm cloudinit dump 9000 user

相同的命令也适用于`network`和`meta`。

Cloud-Init特定选项

cicustom`: `[meta=<volume>] [,network=<volume>] [,user=<volume>] [,vendor=<volume>]

指定自定义文件以在启动时替换自动生成的文件。

meta`=`<volume>

指定一个自定义文件,包含通过cloud-init传递给虚拟机的所有元数据。这是特定于提供商的,意味着configdrive2和nocloud是有区别的。

network`=`<volume>

通过 cloud-init 将包含所有网络数据的自定义文件传递给虚拟机。

user`=`<volume>

通过 cloud-init 将包含所有用户数据的自定义文件传递给虚拟机。

vendor`=`<volume>

通过cloud-init将包含所有供应商数据的自定义文件传递给VM。

cipassword`: `<string>

要分配给用户的密码。通常不建议使用这种方法,请改用ssh密钥。还要注意,较旧版本的cloud-init不支持哈希密码。

citype`: `<configdrive2 | nocloud | opennebula>

指定云初始化配置格式。默认值取决于配置的操作系统类型(ostype)。我们对于Linux使用`nocloud`格式,对于Windows使用`configdrive2`格式。

ciupgrade`: <boolean> (default = 1)

在第一次启动后执行自动包升级。

ciuser`: `<string>

用于更改SSH密钥和密码的用户名,而不是镜像配置的默认用户。

ipconfig[n]`: `[gw=<GatewayIPv4>] [,gw6=<GatewayIPv6>] [,ip=<IPv4Format/CIDR>] [,ip6=<IPv6Format/CIDR>]

为相应接口指定IP地址和网关。

IP地址使用CIDR表示法,网关是可选的,但需要指定相同类型的IP地址。

特殊字符串’dhcp’可用于IP地址以使用DHCP,在这种情况下不应提供明确的网关。对于IPv6,特殊字符串’auto’可用于使用无状态自动配置。这需要cloud-init 19.4或更新版本。

如果启用了cloud-init,并且既没有指定IPv4地址也没有指定IPv6地址,它将默认使用IPv4上的dhcp。

gw`=`<GatewayIPv4>

IPv4流量的默认网关。

Note
需要选项: `ip
gw6`=`<GatewayIPv6>

IPv6流量的默认网关。

Note
需要选项: `ip6
ip`=<IPv4格式/CIDR> (默认值= dhcp)

CIDR格式的IPv4地址。

ip6`=<IPv6Format/CIDR> (default = dhcp)

IPv6地址的CIDR格式。

nameserver`: `<string>

为容器设置DNS服务器IP地址。如果没有设置searchdomain和nameserver,创建操作会自动使用主机的设置。

searchdomain`:`<字符串>

为容器设置DNS搜索域。如果没有设置searchdomain或nameserver,创建操作将自动使用主机的设置。

sshkeys`: `<string>

设置公共SSH密钥(每行一个密钥,OpenSSH格式)。

PCI(e) 透传

PCI(e) 透传是一种机制,它允许虚拟机从宿主机控制一个PCI设备。相比使用虚拟化硬件,这可以带来一些优势,例如更低的延迟、更高的性能或更多的功能(例如,卸载处理)。

但是,如果你将一个设备通过到虚拟机中,你就不能再在主机上或任何其他虚拟机中使用那个设备了。

请注意,虽然PCI直通对i440fx和q35机器都可用,但PCIe直通仅在q35机器上可用。这并不意味着作为PCI设备传递的PCIe能力设备将仅以PCI速度运行。将设备作为PCIe传递只是为了设置一个标志,告知客户端该设备是PCIe设备,而不是一个“非常快的旧版PCI设备”。某些客户端应用程序从这一点中受益。

一般要求

由于直通操作是在真实硬件上执行的,因此需要满足一些要求。下面简要概述这些要求,有关特定设备的更多信息,请参见 PCI Passthrough 示例

硬件

您的硬件需要支持`IOMMU`(输入/输出 内存 管理 单元)中断重映射,这包括CPU和主板。

通常,带有VT-d的Intel系统和带有AMD-Vi的AMD系统支持这项功能。但是并不保证所有东西都能开箱即用,这可能是由于硬件实现不佳以及驱动程序缺失或质量低下。

进一步来说,服务器级别的硬件通常比消费级别的硬件有更好的支持,但即便如此,许多现代系统也能支持这一点。

请咨询您的硬件供应商,以确定他们是否支持您特定设置下的Linux系统中的此功能。

确定PCI卡地址

最简单的方式是在VM的硬件标签中使用GUI添加一种类型为"Host PCI"的设备。或者,你也可以使用命令行。

你可以使用以下方式找到你的卡片

 lspci

配置

一旦你确保了你的硬件支持直通,你将需要进行一些配置来启用PCI(e)直通。

输入输出内存管理单元

首先,您需要在BIOS/UEFI中启用IOMMU支持。通常对应的设置称为`IOMMU`或`VT-d`,但您应该在主板的手册中找到确切的选项名称。

对于Intel CPU,您还需要在kernel command line内核上启用IOMMU,通过添加:

intel_iommu=on

对于AMD的CPU来说,它应该会自动被启用。

IOMMU 透传模式

如果您的硬件支持IOMMU直通模式,启用这种模式可能会提高性能。这是因为虚拟机会绕过超级管理程序通常执行的(默认的)DMA转换,而是将DMA请求直接传递给硬件IOMMU。要启用这些选项,请添加:

iommu=pt
内核模块

您必须确保已加载以下模块。这可以通过将它们添加到`/etc/modules`来实现。在6.2版本之后的内核中({pve} 8及以后版本),'vfio_virqfd’模块是’vfio’模块的一部分,因此,在{pve} 8及更高版本中加载’vfio_virqfd’是不必要的。

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd #如果是6.2或更高版本的内核,就不需要了

在更改任何与模块相关的内容后,你需要刷新你的`initramfs`。在{pve}上,这可以通过执行下列操作完成:

# update-initramfs -u -k all

要检查模块是否正在被加载,输出为

# lsmod | grep vfio

应当包括上述的四个模块。

完成配置

最后重新启动以使更改生效,并检查它确实已启用。

# dmesg | grep -e DMAR -e IOMMU -e AMD-Vi

应该显示根据硬件和内核具体的消息可能会有所不同,IOMMUDirected I/OInterrupt Remapping 是启用的。

有关如何排除故障或验证IOMMU是否按预期工作的说明,请参见我们wiki中的[验证IOMMU参数](https://pve.proxmox.com/wiki/PCI_Passthrough#Verifying_IOMMU_parameters)部分。

同样重要的是,你想要穿透的设备位于一个*单独的* IOMMU 组中。这可以通过调用 {pve} API 来检查:

# pvesh get /nodes/{nodename}/hardware/pci --pci-class-blacklist ""

如果设备与其功能(例如,带有HDMI音频设备的GPU)或与其根端口或PCI(e)桥一起处于一个`IOMMU`组中,这是可以的。

Note
PCI(e) 插槽

一些平台对其物理PCI(e)插槽的处理方式不同。因此,如果你没有得到期望的`IOMMU`组分离,有时将卡插入另一个PCI(e)插槽可能会有所帮助。

Note
不安全的中断

对于某些平台,可能需要允许不安全的中断。为此,在*/etc/modprobe.d/*目录下以`.conf`结尾的文件中添加以下行:

options vfio_iommu_type1 allow_unsafe_interrupts=1

请注意,这个选项可能会让您的系统不稳定。

GPU直通笔记

无法通过{pve}网络界面上的NoVNC或SPICE显示GPU的帧缓冲区。

当通过整个GPU或vGPU传递,并且需要图形输出时,必须要么将显示器物理连接到显卡上,要么在客户端内配置远程桌面软件(例如,VNC或RDP)。

如果你想将GPU作为硬件加速器使用,例如,用于使用OpenCL或CUDA的程序,这是不必要的。

主机设备直通

PCI(e) 透传最常用的一种变体是透传整个 PCI(e) 卡,例如 GPU 或网络卡。

主机配置

{pve}尝试自动使PCI(e)设备对主机不可用。但是,如果这不起作用,有两件事可以做:

  • 通过添加将设备ID传递给’vfio-pci’模块的选项

    options vfio-pci ids=1234:5678,4321:8765

    将以下内容添加到 /etc/modprobe.d/ 目录下的一个 .conf 文件中,其中 1234:56784321:8765 是通过以下方法获得的厂商和设备ID:

    # lspci -nn
  • 完全黑名单中的驱动程序在主机上,确保它自由绑定用于直通。

    将 DRIVERNAME 添加到黑名单

    /etc/modprobe.d/ 的 .conf 文件中。

    要找到驱动名,请执行

    # lspci -k

    例如:

    # lspci -k | grep -A 3 "VGA"

    将输出类似于

    01:00.0 VGA兼容控制器:NVIDIA Corporation GP108 [GeForce GT 1030] (rev a1)
    	子系统:Micro-Star International Co., Ltd. [MSI] GP108 [GeForce GT 1030]
    	正在使用的内核驱动:<some-module>
    	内核模块:<some-module>

    现在我们可以通过将它们写入.conf文件来将驱动程序列入黑名单:

    echo "blacklist <some-module>" >> /etc/modprobe.d/blacklist.conf

对于这两种方法,您需要再次更新`initramfs`,并在此之后重启。

如果这样做不起作用,你可能需要设置一个软依赖来在加载’vfio-pci’之前加载gpu模块。这可以通过’softdep’标志来完成,更多信息请参阅’modprobe.d’的手册页。

例如,如果你正在使用名为<some-module>的驱动程序:

# echo "softdep <some-module> pre: vfio-pci" >> /etc/modprobe.d/<some-module>.conf
验证配置

要检查你的更改是否成功,你可以使用

# lspci -nnk

并检查您的设备条目。如果它显示

正在使用的内核驱动程序:vfio-pci

或者完全缺少’正在使用’这一行,设备已经可以用于直通。

虚拟机配置

当通过GPU时,使用’q35’作为机器类型、OVMF(对于虚拟机来说是’UEFI')而不是SeaBIOS,以及使用PCIe而不是PCI时,可以达到最佳兼容性。注意,如果你想要对GPU进行直通,而且GPU需要有一个能够支持UEFI的ROM,否则请使用SeaBIOS。要检查ROM是否支持UEFI,可以查看https://pve.proxmox.com/wiki/PCI_Passthrough#How_to_know_if_a_graphics_card_is_UEFI_.28OVMF.29_compatible[PCI Passthrough Examples] wiki。

此外,通过使用OVMF,可能可以禁用VGA仲裁,从而减少启动过程中需要运行的遗留代码量。要禁用VGA仲裁:

echo "options vfio-pci ids=<vendor-id>,<device-id> disable_vga=1" > /etc/modprobe.d/vfio.conf

<vendor-id><device-id> 替换为从以下位置获得的相应值:

# lspci -nn

PCI设备可以在虚拟机的硬件部分的网络界面中添加。或者,您可以使用命令行; 在VM配置中设置*hostpciX*选项,例如通过执行:

# qm set VMID -hostpci0 00:02.0

或者通过向虚拟机配置文件添加一行:

hostpci0: 00:02.0

如果您的设备具有多个功能(例如,“00:02.0”和“00:02.1”),您可以通过简写语法“00:02”将它们一起传递。这等同于在网页界面中勾选“所有功能”复选框。

根据设备和客户端操作系统的不同,可能需要一些选项:

  • x-vga=on|off 将 PCI(e) 设备标记为 VM 的主显卡。启用此选项后,vga 配置选项将被忽略。

  • 'pcie=on|off 告诉 {pve} 使用 PCIe 或 PCI 端口。一些客户/设备组合需要 PCIe 而不是 PCI。PCIe 仅适用于 q35 机器类型。'

  • 'rombar=on|off 使固件ROM对客户可见。默认为开启。一些PCI(e)设备需要禁用此功能。'

  • 'romfile=<path>, 是一个可选的路径,用于指定设备使用的ROM文件。这是相对于*/usr/share/kvm/*的相对路径。'

示例

一个将GPU设置为主要设备的PCIe直通示例:

# qm set VMID -hostpci0 02:00,pcie=on,x-vga=on
PCI ID覆盖

您可以覆盖宾客操作系统将看到的PCI供应商ID、设备ID和子系统ID。如果您的设备是一个变体,带有宾客驱动程序无法识别的ID,但您仍希望强制加载这些驱动程序(例如,如果您知道您的设备与已支持的变体共享相同的芯片组),那么这样做是有用的。

可用的选项包括`vendor-id`、device-idsub-vendor-id`和`sub-device-id。你可以设置这些中的任何一个或全部,以覆盖你设备的默认ID。

例如:

# qm set VMID -hostpci0 02:00,device-id=0x10f6,sub-vendor-id=0x0000

单根I/O虚拟化

穿透PCI(e)设备的另一种方式是使用设备的硬件虚拟化功能,如果可用的话。

Note
启用 SR-IOV

要使用SR-IOV,平台支持尤其重要。首先可能需要在BIOS/UEFI中启用此功能,或者使用特定的PCI(e)端口才能使其工作。如有疑问,请咨询平台的手册或联系其供应商。

''SR-IOV单根输入/输出虚拟化)使单个设备能够为系统提供多个’VF'(虚拟功能)。每个’VF’都可以在不同的虚拟机中使用,拥有完整的硬件特性,并且相比软件虚拟化设备,具有更好的性能和更低的延迟。'

目前,最常见的使用场景是具有SR-IOV支持的NICs(网络接口卡),它可以为每个物理端口提供多个VF。这允许在VM内部使用诸如校验和卸载等功能,从而减少(主机)CPU开销。

主机配置

通常,有两种方法可以在设备上启用虚拟函数。

  • 有时驱动模块有一个选项,例如对于某些英特尔驱动程序

    max_vfs=4

    可以将文件名以 .conf 结尾的文件放置在 /etc/modprobe.d/ 目录下。 (完成后不要忘记更新你的initramfs)

    请参阅您的驱动模块文档,以获取确切的参数和选项。

  • 第二种,更通用的方法是使用`sysfs`。如果设备和驱动支持这一点,你可以动态地改变虚拟函数(VFs)的数量。例如,要在设备0000:01:00.0上设置4个虚拟函数,执行:

    # echo 4 > /sys/bus/pci/devices/0000:01:00.0/sriov_numvfs

    为了使这个更改持久化,你可以使用`sysfsutils` Debian包。安装后通过 /etc/sysfs.conf 或在 /etc/sysfs.d/ 中的一个 FILE.conf 文件来配置它。

虚拟机配置

在创建VF之后,当你使用`lspci`命令输出它们时,你应该可以看到它们作为独立的PCI(e)设备。获取它们的ID,然后像处理正常的PCI(e)设备一样进行透传,参考qm_pci_passthrough_vm_config。

中介设备(vGPU,GVT-g)

中介设备是另一种方法,用于重用物理硬件的特性和性能到虚拟化硬件。这些在虚拟化GPU设置中最为常见,例如英特尔的GVT-g和NVIDIA在其GRID技术中使用的vGPU。

凭借此技术,物理卡能够创建虚拟卡,类似于SR-IOV。不同之处在于,中介设备在主机中不会作为PCI(e)设备出现,因而只适合在虚拟机中使用。

主机配置

一般而言,你的卡的驱动必须支持那个功能,否则它将无法工作。所以请咨询你的供应商,了解兼容的驱动程序以及如何配置它们。

Intel的GVT-g驱动程序已集成到内核中,应该适用于第5代、第6代和第7代Intel Core处理器,以及E3 v4、E3 v5和E3 v6 Xeon处理器。

要为英特尔显卡启用它,你必须确保加载模块’kvmgt'(例如通过`/etc/modules`),并在内核命令行上启用它,并添加以下参数:

i915.enable_gvt=1

在此之后,记得更新`initramfs`,然后重启你的主机。

虚拟机配置

要使用一个中介设备,只需在`hostpciX`虚拟机配置选项上指定`mdev`属性。

您可以通过’sysfs’获取支持的设备。例如,要列出设备'0000:00:02.0’支持的类型,您只需执行:

# ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types

每个条目是一个包含以下重要文件的目录:

  • available_instances 包含了此类型的实例仍然可用的数量,每个VM中使用的’mdev’都会减少这个数量。

  • "description" 包含了关于该类型功能的简短描述

  • “create”是用来创建这种设备的端点,如果配置了带有`mdev`的`hostpciX`选项,{pve}会自动为您完成这一操作。

一个配备了`Intel GVT-g vGPU`(Intel Skylake 6700k)的示例配置:

# qm set VMID -hostpci0 00:02.0,mdev=i915-GVTg_V5_4

使用这个设置,{pve}会在虚拟机启动时自动创建这样一个设备,并在虚拟机停止时再次清理。

在集群中使用

它也可能在集群级别映射设备,以便它们可以与HA正确使用,并且可以检测到硬件变化,非根用户可以配置它们。有关该内容的详细信息,请参见资源映射

钩子脚本

你可以通过配置属性`hookscript`给虚拟机添加一个钩子脚本。

# qm set 100 --hookscript local:snippets/hookscript.pl

它将在客户端生命周期的不同阶段被调用。有关示例和文档,请参阅`/usr/share/pve-docs/examples/guest-example-hookscript.pl`下的示例脚本。

冬眠

你可以通过GUI选项`Hibernate`或使用命令将虚拟机挂起到磁盘上

# qm suspend ID --todisk

这意味着当前内存的内容将被保存到磁盘上,虚拟机将被停止。在下一次启动时,内存内容将被加载,虚拟机可以从之前离开的地方继续运行。

状态存储选择

如果没有为内存指定目标存储,它将会自动选择以下选项中的第一个:

  1. 虚拟机配置中的存储 vmstatestorage

  2. 来自任何虚拟机磁盘的第一块共享存储。

  3. 第一个非共享存储来自任何虚拟机磁盘。

  4. 将存储`local`作为后备选项。

资源映射

当使用或引用本地资源(例如,pci设备的地址)时,使用原始地址或ID有时会出现问题,例如:

  • 在使用HA时,目标节点上可能存在具有相同ID或路径的不同设备,如果在将此类客户端分配给HA组时不小心,可能会使用错误的设备,从而破坏配置。

  • 更换硬件可能会更改ID和路径,因此需要检查所有已分配的设备,以查看路径或ID是否仍然正确。

为了更好地处理这个问题,可以定义集群范围的资源映射,这样资源可以有一个集群唯一的,用户选择的标识符,这个标识符在不同的主机上可以对应不同的设备。有了这个,HA(高可用性)就不会用错误的设备启动一个客户端,而且可以检测到硬件变化。

创建这样的映射可以通过在`Datacenter`下的相关标签中的`Resource Mappings`类别下的{pve}网页GUI完成,或者在命令行界面(cli)上完成。

# pvesh create /cluster/mapping/<type> <options>

其中`<type>是硬件类型(目前为`pci`或`usb),而`<options>`是设备映射和其他配置参数。

请注意,选项必须包含一个具有该硬件的所有标识属性的map属性,以便可以验证硬件没有更改,并且正确的设备被传递。

例如,要在节点`node1`上添加一个PCI设备,命名为`device1`,路径为`0000:01:00.0`,设备ID为`0001`,供应商ID为`0002`,并且在`node2`上的路径为`0000:02:00.0`,你可以使用以下方式添加它:

# pvesh create /cluster/mapping/pci --id device1 \
 --map node=node1,path=0000:01:00.0,id=0002:0001 \
 --map node=node2,path=0000:02:00.0,id=0002:0001

你必须对每个需要映射该设备的节点重复 map 参数(请注意,当前每个映射每个节点只能映射一个USB设备)。

使用图形用户界面(GUI)会使这个过程变得更简单,因为正确的属性会被自动识别并发送到API。

PCI设备也有可能在每个节点上提供多个设备,并为这些节点设置多个映射属性。如果这样的设备分配给了一个客户机,当客户机启动时,将使用第一个空闲的设备。给出路径的顺序也是尝试这些路径的顺序,因此可以实施任意分配策略。

这对于具有SR-IOV的设备很有用,因为有时候具体传递哪个虚拟功能并不重要。

你可以通过图形用户界面或者使用命令行将这样一个设备分配给一个访客。

# qm set ID -hostpci0 <name>

对于PCI设备,或者

# qm set <vmid> -usb0 <name>

针对USB设备。

''其中`<vmid>是客户端的id,<name>是为创建的映射选择的名称。所有通常用于通过设备的选项都是允许的,例如`mdev''

要创建映射,需要在 /mapping/<type>/<name> 上使用 Mapping.Modify(其中 <type> 是设备类型,<name> 是映射的名称)。

要使用这些映射,必须在`/mapping/<type>/<name>上使用`Mapping.Use (除了编辑配置的正常访客权限之外)。

使用`qm`管理虚拟机

qm是用于在{pve}上管理QEMU/KVM虚拟机的工具。您可以创建和销毁虚拟机,并控制执行(启动/停止/挂起/恢复)。除此之外,您还可以使用qm来设置关联配置文件中的参数。还可以创建和删除虚拟磁盘。

命令行使用示例

使用上传到“local”存储的iso文件,在“local-lvm”存储上创建一个带有4GB IDE磁盘的虚拟机

# qm create 300 -ide0 local-lvm:4 -net0 e1000 -cdrom local:iso/proxmox-mailgateway_2.1.iso

启动新的虚拟机

# qm start 300

发送一个关机请求,然后等待直到虚拟机停止。

# qm shutdown 300 && qm wait 300

与上面相同,但仅等待40秒。

# qm shutdown 300 && qm wait 300 -timeout 40

销毁虚拟机 (VM) 总会将其从访问控制列表中移除,并且总会删除虚拟机的防火墙配置。如果您还希望将虚拟机从复制作业、备份作业以及高可用性 (HA) 资源配置中移除,请激活 --purge 选项。

# qm destroy 300 --purge

将磁盘映像移动到不同的存储中。

# qm move-disk 300 scsi0 other-storage

将磁盘映像重新分配给另一个虚拟机。这将从源虚拟机中移除磁盘`scsi1`并将其作为`scsi3`连接到目标虚拟机。在后台,磁盘映像正在被重命名,以便名称与新所有者匹配。

# qm move-disk 300 scsi1 --target-vmid 400 --target-disk scsi3

配置

虚拟机配置文件存储在Proxmox集群文件系统内部,可以在`/etc/pve/qemu-server/<VMID>.conf`处访问。像`/etc/pve/`内部的其他文件一样,它们会自动复制到所有其他集群节点。

Note
VMID小于100的是保留给内部用途的,而且VMID需要在整个集群中是唯一的。
示例虚拟机配置
boot: order=virtio0;net0
cores: 1
sockets: 1
memory: 512
name: webmail
ostype: l26
net0: e1000=EE:D2:28:5F:B6:3E,bridge=vmbr0
virtio0: local:vm-100-disk-1,size=32G

那些配置文件是简单的文本文件,你可以使用普通的文本编辑器(如`vi`、nano…​)来编辑它们。做一些小的更正有时候是有用的,但请记住,你需要重启虚拟机来应用这些更改。

出于那个原因,通常使用`qm`命令来生成和修改那些文件,或者使用GUI来完成整个操作会更好。我们的工具包足够智能,能够即时应用大多数更改到正在运行的虚拟机(VM)。这个功能被称为“热插拔”,在这种情况下,无需重启虚拟机。

文件格式

VM配置文件使用一种简单的冒号分隔的键/值格式。每一行都遵循以下格式:

# this is a comment
OPTION: value

这些文件中的空白行会被忽略,而以`#`字符开头的行被视为注释,也会被忽略。

快照

当你创建一个快照时,‘qm`会将快照时刻的配置存储到同一配置文件内的一个单独的快照区块中。例如,在创建了一个名为``testsnapshot’'的快照之后,你的配置文件将会是这样的:

虚拟机配置与快照
memory: 512
swap: 512
parent: testsnaphot
...

[testsnaphot]
memory: 512
swap: 512
snaptime: 1457170803
...

有一些与快照相关的属性,比如`parent`和`snaptime`。`parent`属性用于存储快照之间的父/子关系。`snaptime`是快照创建的时间戳(Unix纪元)。

您可以选择使用`vmstate`选项保存运行中虚拟机的内存。关于目标存储如何为虚拟机状态选择的详细信息,请查看章节休眠中的状态存储选择

选项

acpi`: <boolean> (default = 1)

启用/禁用ACPI。

affinity`: `<string>

用于执行访客进程的主机核心列表,例如:0,5,8-11

agent`: `[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=<virtio|isa>]

启用/禁用与QEMU访客代理及其属性的通信。

enabled`=<boolean> (default = 0)

启用/禁用与在虚拟机中运行的QEMU客户端代理(QGA)的通信。

freeze-fs-on-backup`=<boolean> (default = 1)

在备份时冻结/解冻访客文件系统以保持一致性。

fstrim_cloned_disks`=<boolean> (default = 0)

在移动磁盘或迁移虚拟机后运行fstrim。

type`=<isa | virtio> (default = virtio)

选择代理类型

arch`: `<aarch64 | x86_64>

虚拟处理器架构。默认为主机。

args`: `<string>

传递给kvm的任意参数,例如:

args: -no-reboot -smbios type=0,vendor=FOO

Note
这个选项仅限专家使用。
audio0`: `device=<ich9-intel-hda|intel-hda|AC97> [,driver=<spice|none>]

配置一个音频设备,与QXL/Spice结合使用时很有用。

device`=`<AC97 | ich9-intel-hda | intel-hda>

配置音频设备。

driver`=<none | spice> (default = spice)

音频设备的驱动后端。

autostart`: <boolean> (default = 0)

在崩溃后自动重启(当前被忽略)。

balloon`:`<整数> (0 - N)

VM的目标RAM量(以MiB为单位)。使用零将禁用气球驱动程序。

bios`:<ovmf | seabios>(默认值为 seabios

选择BIOS实现。

boot`: `[[legacy=]<[acdn]{1,4}>] [,order=<device[;device…​]>]

指定客户机启动顺序。请使用’order='子属性,不使用键或使用’legacy='已被弃用。

legacy`=<[acdn]{1,4}> (default = cdn)

从软盘(a)、硬盘(c)、CD-ROM(d)或网络(n)启动。已弃用,请改用’order='。

order=<device[;device…​]>

客人将尝试按照这里出现的顺序从设备启动。

磁盘、光驱和通过的存储USB设备将会直接从中启动,网络接口卡将加载PXE,而PCIe设备将表现得像磁盘(例如NVMe)或加载一个选项ROM(例如RAID控制器,硬件网络接口卡)。

请注意,只有此列表中的设备才会被标记为可引导的,因此会被客户端固件(BIOS/UEFI)加载。如果您需要多个磁盘来引导(例如,软件RAID),您需要在这里指定它们所有。

当给定时,覆盖已弃用的 legacy=[acdn]* 值。

bootdisk`: `(ide|sata|scsi|virtio)\d+

启用从指定磁盘启动。已弃用:请改用 boot: order=foo;bar

cdrom`: `<volume>

这是选项-ide2的别名

cicustom`: `[meta=<volume>] [,network=<volume>] [,user=<volume>] [,vendor=<volume>]

cloud-init: 指定自定义文件来替换启动时自动生成的文件。

meta`=`<volume>

指定一个自定义文件,包含通过 cloud-init 传递给 VM 的所有元数据。这是特定于提供商的,意味着 configdrive2 和 nocloud 是不同的。

network`=`<volume>

通过cloud-init将包含所有网络数据的自定义文件传递给虚拟机。

user`=`<volume>

通过cloud-init将包含所有用户数据的自定义文件传递给虚拟机。

vendor`=`<volume>

通过cloud-init向虚拟机传递一个包含所有供应商数据的自定义文件。

cipassword`: `<string>

cloud-init: 分配给用户的密码。通常不推荐使用此方法。请改用ssh密钥。还要注意,旧版本的cloud-init不支持散列密码。

citype`: `<configdrive2 | nocloud | opennebula>

指定cloud-init配置格式。默认值取决于配置的操作系统类型(ostype)。对于Linux,我们使用`nocloud`格式,对于Windows,我们使用`configdrive2`。

ciupgrade`: <boolean> (default = 1)

cloud-init:在首次启动后自动进行软件包升级。

ciuser`: `<string>

cloud-init:用于更改ssh密钥和密码的用户名称,而不是镜像配置的默认用户。

cores`: <integer> (1 - N) (default = 1)

每个插槽的核心数。

cpu`: `[[cputype=]<string>] [,flags=<+FLAG[;-FLAG…​]>] [,hidden=<1|0>] [,hv-vendor-id=<vendor-id>] [,phys-bits=<8-64|host>] [,reported-model=<enum>]

模拟的CPU类型。

cputype`=<string> (default = kvm64)

模拟的CPU类型。可以是默认值或自定义名称(自定义模型名称必须以’custom-'为前缀)。

flags`=`<+FLAG[;-FLAG…​]>

附加的CPU标志列表,通过';'分隔。使用'+FLAG’来启用标志,使用'-FLAG’来禁用标志。自定义CPU模型可以指定QEMU/KVM支持的任何标志,出于安全原因,特定于虚拟机的标志必须来自以下集合:pcid、spec-ctrl、ibpb、ssbd、virt-ssbd、amd-ssbd、amd-no-ssb、pdpe1gb、md-clear、hv-tlbflush、hv-evmcs、aes。

hidden`=<boolean> (default = 0)

不要标识为KVM虚拟机。

hv-vendor-id`=`<vendor-id>

Hyper-V 供应商 ID。Windows 客户端内的一些驱动程序或应用程序需要一个特定的 ID。

phys-bits`=`<8-64|host>

报告给客户操作系统的物理内存地址位。应该小于或等于主机的地址位。设置为“host”以使用来自主机CPU的值,但注意这样做将破坏到其他值CPU的实时迁移。

reported-model`=<486 | Broadwell | Broadwell-IBRS | Broadwell-noTSX | Broadwell-noTSX-IBRS | Cascadelake-Server | Cascadelake-Server-noTSX | Cascadelake-Server-v2 | Cascadelake-Server-v4 | Cascadelake-Server-v5 | Conroe | Cooperlake | Cooperlake-v2 | EPYC | EPYC-Genoa | EPYC-IBPB | EPYC-Milan | EPYC-Milan-v2 | EPYC-Rome | EPYC-Rome-v2 | EPYC-Rome-v3 | EPYC-Rome-v4 | EPYC-v3 | EPYC-v4 | GraniteRapids | Haswell | Haswell-IBRS | Haswell-noTSX | Haswell-noTSX-IBRS | Icelake-Client | Icelake-Client-noTSX | Icelake-Server | Icelake-Server-noTSX | Icelake-Server-v3 | Icelake-Server-v4 | Icelake-Server-v5 | Icelake-Server-v6 | IvyBridge | IvyBridge-IBRS | KnightsMill | Nehalem | Nehalem-IBRS | Opteron_G1 | Opteron_G2 | Opteron_G3 | Opteron_G4 | Opteron_G5 | Penryn | SandyBridge | SandyBridge-IBRS | SapphireRapids | SapphireRapids-v2 | Skylake-Client | Skylake-Client-IBRS | Skylake-Client-noTSX-IBRS | Skylake-Client-v4 | Skylake-Server | Skylake-Server-IBRS | Skylake-Server-noTSX-IBRS | Skylake-Server-v4 | Skylake-Server-v5 | Westmere | Westmere-IBRS | athlon | core2duo | coreduo | host | kvm32 | kvm64 | max | pentium | pentium2 | pentium3 | phenom | qemu32 | qemu64> (default = kvm64)

CPU型号和供应商向客户报告。必须是QEMU/KVM支持的模型。仅对自定义CPU模型定义有效,默认模型将始终向客户操作系统报告自身。

cpulimit`: <number> (0 - 128) (default = 0)

CPU使用限制。

Note
如果计算机有2个CPU,它总共有'2’个CPU时间。值'0’表示没有CPU限制。
cpuunits`: <integer> (1 - 262144) (default = cgroup v1: 1024, cgroup v2: 100)

VM的CPU权重。该参数在内核公平调度器中使用。数字越大,此VM获得的CPU时间就越多。数字是相对于所有其他运行中的VM的权重而言的。

description`: `<string>

虚拟机的描述。在web界面的虚拟机摘要中显示。这将作为注释保存在配置文件内。

efidisk0`: `[file=]<volume> [,efitype=<2m|4m>] [,format=<enum>] [,pre-enrolled-keys=<1|0>] [,size=<DiskSize>]

为存储EFI变量配置一个磁盘。

efitype`=<2m | 4m> (default = 2m)

OVMF EFI 变量的大小和类型。4m’较新且推荐使用,并且对于安全启动是必需的。为了向后兼容,如果未另行指定,则使用'2m。对于arch=aarch64(ARM)的VMs,此项被忽略。

file`=`<volume>

驱动器的后备卷。

format=<cloop | cow | qcow | qcow2 | qed | raw | vmdk>

驱动器备份文件的数据格式。

pre-enrolled-keys`=<boolean> (default = 0)

如果与’efitype=4m’一起使用,请使用带有特定于发行版和Microsoft标准密钥的EFI变量模板。请注意,这将默认启用安全启动,尽管仍然可以从虚拟机内部关闭它。

size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

freeze`: `<boolean>

在启动时冻结CPU(使用 c 监视器命令开始执行)。

hookscript`: `<string>

在虚拟机生命周期的不同阶段将要执行的脚本。

hostpci[n]`: `[[host=]<HOSTPCIID[;HOSTPCIID2…​]>] [,device-id=<hex id>] [,legacy-igd=<1|0>] [,mapping=<mapping-id>] [,mdev=<string>] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=<string>] [,sub-device-id=<hex id>] [,sub-vendor-id=<hex id>] [,vendor-id=<hex id>] [,x-vga=<1|0>]

将主机PCI设备映射到客户机中。

Note
这个选项允许直接访问主机硬件。因此,不再可能迁移这样的机器 - 请谨慎使用。
Caution
实验性功能!用户报告此选项有问题。
device-id`=`<hex id>

覆盖对客户端可见的PCI设备ID

host`=`<HOSTPCIID[;HOSTPCIID2…​]>

主机PCI设备透传。主机PCI设备的PCI ID或主机的一组PCI虚拟函数。HOSTPCIID的语法为:

''总线:设备.功能 (十六进制数字)'

你可以使用 lspci 命令来列出现有的PCI设备。

必须设置“这个”或“mapping”键。

legacy-igd`=<boolean> (default = 0)

将此设备以传统IGD模式传递,使其成为虚拟机中的主要且独占的图形设备。需要使用’pc-i440fx’机器类型并将VGA设置为’none'。

mapping`=`<mapping-id>

集群范围映射的ID。必须设置此项或默认键’host'。

mdev`=`<string>

要使用的介质设备的类型。VM启动时将创建此类型的实例,并在VM停止时清理。

pcie`=<boolean> (default = 0)

选择PCI-express总线(需要’q35’机器模型)。

rombar`=<boolean> (default = 1)

指定设备的 ROM 是否会在客户机的内存映射中可见。

romfile`=`<string>

定制的PCI设备ROM文件名(必须位于/usr/share/kvm/)。

sub-device-id`=`<hex id>

覆盖对客户端可见的PCI子系统设备ID

sub-vendor-id`=`<hex id>

覆写对客户端可见的PCI子系统供应商ID

vendor-id`=`<hex id>

覆盖对客户端可见的PCI供应商ID

x-vga`=<boolean> (default = 0)

启用 vfio-vga 设备支持。

hotplug`: <string> (default = network,disk,usb)

选择性启用热插拔功能。这是一个由逗号分隔的热插拔功能列表:网络磁盘CPU内存USB’和’cloudinit。使用'0’完全禁用热插拔。使用'1’作为值是默认`网络,磁盘,USB`的别名。对于机器版本 >= 7.1且操作系统类型为l26或windows > 7的客户来说,USB热插拔是可能的。

hugepages`: `<1024 | 2 | any>

启用/禁用大页内存。

ide[n]`: `[file=]<volume> [,aio=<native|threads|io_uring>] [,backup=<1|0>] [,bps=<bps>] [,bps_max_length=<seconds>] [,bps_rd=<bps>] [,bps_rd_max_length=<seconds>] [,bps_wr=<bps>] [,bps_wr_max_length=<seconds>] [,cache=<enum>] [,cyls=<integer>] [,detect_zeroes=<1|0>] [,discard=<ignore|on>] [,format=<enum>] [,heads=<integer>] [,iops=<iops>] [,iops_max=<iops>] [,iops_max_length=<seconds>] [,iops_rd=<iops>] [,iops_rd_max=<iops>] [,iops_rd_max_length=<seconds>] [,iops_wr=<iops>] [,iops_wr_max=<iops>] [,iops_wr_max_length=<seconds>] [,mbps=<mbps>] [,mbps_max=<mbps>] [,mbps_rd=<mbps>] [,mbps_rd_max=<mbps>] [,mbps_wr=<mbps>] [,mbps_wr_max=<mbps>] [,media=<cdrom|disk>] [,model=<model>] [,replicate=<1|0>] [,rerror=<ignore|report|stop>] [,secs=<integer>] [,serial=<serial>] [,shared=<1|0>] [,size=<DiskSize>] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=<none|lba|auto>] [,werror=<enum>] [,wwn=<wwn>]

将卷作为IDE硬盘或CD-ROM使用(n为0到3)。

aio`=`<io_uring | native | threads>

要使用的AIO类型。

backup`=`<boolean>

在进行备份时是否应该包括驱动器。

bps`=`<bps>

每秒最大读写速度(以字节计)。

bps_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

bps_rd`=`<bps>

每秒最大读取速度(以字节为单位)。

bps_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

bps_wr`=`<bps>

每秒最大写入速度(以字节计)。

bps_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

cache`=`<directsync | none | unsafe | writeback | writethrough>

驱动器的缓存模式

cyls`=`<integer>

强制驱动器的物理几何结构具有特定的柱面数。

detect_zeroes`=`<boolean>

控制是否检测并尝试优化写入零的操作。

discard`=`<ignore | on>

控制是否将丢弃/修剪请求传递给底层存储。

file`=`<volume>

驱动器的后备卷。

format=<cloop | cow | qcow | qcow2 | qed | raw | vmdk>

驱动器备份文件的数据格式。

heads`=`<integer>

强制驱动器的物理几何形状具有特定的磁头数量。

iops`=`<iops>

最大读/写I/O操作每秒的次数。

iops_max`=`<iops>

每秒未限制的最大读/写I/O池操作数。

iops_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

iops_rd`=`<iops>

每秒最大读取I/O操作数。

iops_rd_max`=`<iops>

每秒最大无限制读取I/O池操作数。

iops_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

iops_wr`=`<iops>

最大写入I/O的操作次数每秒。

iops_wr_max`=`<iops>

每秒最大未限制的写入I/O池操作数。

iops_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

mbps`=`<mbps>

每秒的最大读写速度,以兆字节为单位。

mbps_max`=`<mbps>

最大未限制的读/写池,以每秒兆字节计。

mbps_rd`=`<mbps>

最大读取速度,以每秒兆字节计。

mbps_rd_max`=`<mbps>

每秒以兆字节计的最大未限制读取池。

mbps_wr`=`<mbps>

每秒最大写入速度,以兆字节计。

mbps_wr_max`=`<mbps>

每秒以兆字节计的最大未限速写入池。

media`=<cdrom | disk> (default = disk)

驱动器的媒体类型。

model`=`<model>

驱动器报告的型号名称,经过URL编码,最长40个字节。

replicate`=<boolean> (default = 1)

是否应将驱动器考虑用于复制任务。

rerror`=`<ignore | report | stop>

读取错误操作。

secs`=`<integer>

强制驱动器的物理几何结构具有特定的扇区计数。

serial`=`<serial>

驱动器报告的序列号,进行URL编码,最长20个字节。

shared`=<boolean> (default = 0)

将这个本地管理的卷标记为在所有节点上可用。

Warning
这个选项不会自动共享卷,它假设卷已经共享了!
size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

snapshot`=`<boolean>

控制qemu的快照模式特性。如果激活,对磁盘所做的更改是临时的,并且会在虚拟机关闭时被丢弃。

ssd`=`<boolean>

是否将此驱动器暴露为SSD,而不是旋转硬盘。

trans=<auto | lba | none>

强制磁盘几何结构BIOS转换模式。

werror`=`<enospc | ignore | report | stop>

写入错误操作。

wwn`=`<wwn>

驱动器的全球名称,以16字节的十六进制字符串形式编码,前缀为'0x'。

ipconfig[n]`: `[gw=<GatewayIPv4>] [,gw6=<GatewayIPv6>] [,ip=<IPv4Format/CIDR>] [,ip6=<IPv6Format/CIDR>]

cloud-init:为相应接口指定IP地址和网关。

IP地址使用CIDR表示法,网关是可选的,但需要指定同一类型的IP地址。

特殊字符串’dhcp’可以用于IP地址使用DHCP,在这种情况下不应该提供显式网关。对于IPv6,特殊字符串’auto’可以用来使用无状态自动配置。这需要cloud-init 19.4或更高版本。

如果启用了cloud-init且未指定IPv4或IPv6地址,它将默认使用IPv4上的dhcp。

gw`=`<GatewayIPv4>

IPv4流量的默认网关。

Note
需要选项:`ip
gw6`=`<GatewayIPv6>

IPv6流量的默认网关。

Note
需要选项:`ip6
ip`=<IPv4格式/CIDR> (默认值= dhcp)

IPv4地址以CIDR格式。

ip6`=<IPv6格式/CIDR> (默认值 = dhcp)

IPv6地址以CIDR格式。

ivshmem`: `size=<integer> [,name=<string>]

Inter-VM共享内存。用于VM之间的直接通讯,或者与宿主机的通讯。

name`=`<string>

文件的名称。将以 pve-shm- 为前缀。默认是 VMID。当虚拟机停止时,该文件将被删除。

size`=`<integer> (1 - N)

文件的大小,以 MB 计。

keephugepages`: <boolean> (default = 0)

与hugepages一起使用。如果启用,关闭虚拟机后不会删除hugepages,可用于后续启动。

keyboard`:`<da | de | de-ch | en-gb | en-us | es | fi | fr | fr-be | fr-ca | fr-ch | hu | is | it | ja | lt | mk | nl | no | pl | pt | pt-br | sl | sv | tr>

VNC服务器的键盘布局。这个选项通常不是必需的,并且通常最好从宾客操作系统内部进行处理。

kvm`: <boolean> (default = 1)

启用/禁用 KVM 硬件虚拟化。

localtime`: `<boolean>

将实时时钟(RTC)设定为本地时间。如果`ostype`表明是Microsoft Windows操作系统,默认情况下这个功能是启用的。

lock`: `<backup | clone | create | migrate | rollback | snapshot | snapshot-delete | suspended | suspending>

锁定/解锁虚拟机。

machine: (pc|pc(-i440fx)?-\d+(\.\d+)(\+pve\d)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)(\+pve\d)?(\.pxe)?|virt(?:-\d+(\.\d+))?(\+pve\d)?)

指定QEMU机器类型。

memory`: `[current=]<integer>

内存属性。

current`=<integer> (16 - N) (default = 512)

当前VM(虚拟机)在线内存的量,单位为MiB。当你使用气球设备时,这是可用内存的最大值。

migrate_downtime`: <number> (0 - N) (default = 0.1)

为迁移设置最大可容忍的停机时间(以秒为单位)。

migrate_speed`:<integer> (0 - N)默认值 = 0

为迁移设置最大速度(以MB/s为单位)。值0表示无限制。

name`: `<string>

为虚拟机设置一个名称。仅在配置Web界面中使用。

nameserver`: `<string>

cloud-init:为容器设置DNS服务器IP地址。如果没有设置searchdomain或nameserver,创建操作将自动使用宿主机的设置。

net[n]`: `[model=]<enum> [,bridge=<bridge>] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=<XX:XX:XX:XX:XX:XX>] [,mtu=<integer>] [,queues=<integer>] [,rate=<number>] [,tag=<integer>] [,trunks=<vlanid[;vlanid…​]>] [,<model>=<macaddr>]

指定网络设备。

bridge`=`<bridge>

要连接网络设备的桥接器。Proxmox VE标准桥接器称为’vmbr0'。

如果您不指定桥接,我们将创建一个kvm用户(NATed)网络设备,它提供DHCP和DNS服务。将使用以下地址:

10.0.2.2 网关 10.0.2.3 DNS服务器 10.0.2.4 SMB服务器

DHCP服务器从10.0.2.15开始分配地址给访客。

firewall`=`<boolean>

这个接口是否应该被防火墙保护。

link_down`=`<boolean>

这个接口是否应该被断开连接(就像拔掉插头一样)。

macaddr`=`<XX:XX:XX:XX:XX:XX>

一个常见的MAC地址,其中I/G(个体/组)位没有设置。

model`=`<e1000 | e1000-82540em | e1000-82544gc | e1000-82545em | e1000e | i82551 | i82557b | i82559er | ne2k_isa | ne2k_pci | pcnet | rtl8139 | virtio | vmxnet3>

网络卡型号。virtio’型号提供最佳的性能,且CPU开销非常低。如果你的客户端不支持这个驱动程序,通常最好使用’e1000

mtu`=`<integer> (1 - 65520)

强制MTU设置,仅限VirtIO使用。设置为'1’以使用桥接MTU。

queues`=`<integer> (0 - 64)

设备上要使用的数据包队列数量。

rate`=`<number> (0 - N)

以浮点数形式表示的速率限制,单位为mbps(每秒兆字节)。

标签`=`<整数> (1 - 4094)

应用于此接口上的数据包的VLAN标签。

trunks`=`<vlanid[;vlanid…​]>

允许VLAN干线通过此接口。

numa`: <boolean> (default = 0)

启用/禁用 NUMA。

numa[n]`: `cpus=<id[-id];…​> [,hostnodes=<id[-id];…​>] [,memory=<number>] [,policy=<preferred|bind|interleave>]

NUMA拓扑。

cpus`=`<id[-id];…​>

CPUs 访问此 NUMA 节点。

hostnodes`=`<id[-id];…​>

使用的主机NUMA节点。

memory`=`<number>

这个NUMA节点提供的内存量。

policy`=`<bind | interleave | preferred>

NUMA分配策略。

onboot`: <boolean> (default = 0)

指定虚拟机是否会在系统启动时启动。

ostype`: `<l24 | l26 | other | solaris | w2k | w2k3 | w2k8 | win10 | win11 | win7 | win8 | w2vista | wxp>

指定客户操作系统。这用于为特定操作系统启用特殊的优化/特性:

其他

未指定操作系统

wxp

微软Windows XP

w2k

微软Windows 2000

w2k3

微软 Windows 2003

W2k8 是Windows Server 2008的简称,没有直译的中文意思,通常指的是"Windows Server 2008"这个微软发布的服务器操作系统版本。

微软 Windows 2008

wvista

微软Windows Vista

win7

微软 Windows 7

win8

微软Windows 8/2012/2012r2

win10

微软Windows 10/2016/2019

win11

微软Windows 11/2022

l24

Linux 2.4 内核

l26

Linux 2.6 - 6.X 内核

太阳神

Solaris/OpenSolaris/OpenIndiana 内核

parallel[n]`: `/dev/parport\d+|/dev/usb/lp\d+

将主机并行设备映射(n为0到2)。

Note
这个选项允许直接访问主机硬件。因此,不再可能迁移这样的机器 - 请谨慎使用。
Caution
实验性功能!用户报告此选项有问题。
protection`: <boolean> (default = 0)

设置虚拟机的保护标志。这将禁用删除虚拟机和删除磁盘操作。

reboot`: <boolean> (default = 1)

允许重启。如果设置为'0',虚拟机将在重启时退出。

rng0`: `[source=]</dev/urandom|/dev/random|/dev/hwrng> [,max_bytes=<integer>] [,period=<integer>]

配置基于VirtIO的随机数生成器。

max_bytes`=<integer> (default = 1024)

每“周期”毫秒允许注入到客户机中的最大熵字节数。当使用'/dev/random’作为源时,建议使用较低的值。使用`0`可以禁用限制(可能危险!)。

period`=<integer> (default = 1000)

每隔’period’毫秒,熵注入配额会被重置,允许客户端再次获取’max_bytes’大小的熵。

source`=`</dev/hwrng | /dev/random | /dev/urandom>

要从主机上收集熵的文件。在大多数情况下,应该优先选择 /dev/urandom 而不是 /dev/random,以避免主机上的熵饥饿问题。使用 urandom 并不以任何有意义的方式降低安全性,因为它仍然从真实的熵中获取种子,而且提供的字节很可能会在客户端同真实的熵混合。/dev/hwrng 可用于从主机传递一个硬件 RNG。

sata[n]`: `[file=]<volume> [,aio=<native|threads|io_uring>] [,backup=<1|0>] [,bps=<bps>] [,bps_max_length=<seconds>] [,bps_rd=<bps>] [,bps_rd_max_length=<seconds>] [,bps_wr=<bps>] [,bps_wr_max_length=<seconds>] [,cache=<enum>] [,cyls=<integer>] [,detect_zeroes=<1|0>] [,discard=<ignore|on>] [,format=<enum>] [,heads=<integer>] [,iops=<iops>] [,iops_max=<iops>] [,iops_max_length=<seconds>] [,iops_rd=<iops>] [,iops_rd_max=<iops>] [,iops_rd_max_length=<seconds>] [,iops_wr=<iops>] [,iops_wr_max=<iops>] [,iops_wr_max_length=<seconds>] [,mbps=<mbps>] [,mbps_max=<mbps>] [,mbps_rd=<mbps>] [,mbps_rd_max=<mbps>] [,mbps_wr=<mbps>] [,mbps_wr_max=<mbps>] [,media=<cdrom|disk>] [,replicate=<1|0>] [,rerror=<ignore|report|stop>] [,secs=<integer>] [,serial=<serial>] [,shared=<1|0>] [,size=<DiskSize>] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=<none|lba|auto>] [,werror=<enum>] [,wwn=<wwn>]

将卷作为 SATA 硬盘或 CD-ROM 使用(n 为 0 到 5)。

aio`=`<io_uring | native | threads>

要使用的AIO类型。

backup`=`<boolean>

在进行备份时是否应该包括驱动器。

bps`=`<bps>

每秒最大读写速度(以字节计)。

bps_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

bps_rd`=`<bps>

每秒最大读取速度(以字节为单位)。

bps_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

bps_wr`=`<bps>

每秒最大写入速度(以字节计)。

bps_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

cache`=`<directsync | none | unsafe | writeback | writethrough>

驱动器的缓存模式

cyls`=`<integer>

强制驱动器的物理几何结构具有特定的柱面数。

detect_zeroes`=`<boolean>

控制是否检测并尝试优化写入零的操作。

discard`=`<ignore | on>

控制是否将丢弃/修剪请求传递给底层存储。

file`=`<volume>

驱动器的后备卷。

format=<cloop | cow | qcow | qcow2 | qed | raw | vmdk>

驱动器备份文件的数据格式。

heads`=`<integer>

强制驱动器的物理几何形状具有特定的磁头数量。

iops`=`<iops>

最大读/写I/O操作每秒的次数。

iops_max`=`<iops>

每秒未限制的最大读/写I/O池操作数。

iops_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

iops_rd`=`<iops>

每秒最大读取I/O操作数。

iops_rd_max`=`<iops>

每秒最大无限制读取I/O池操作数。

iops_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

iops_wr`=`<iops>

最大写入I/O的操作次数每秒。

iops_wr_max`=`<iops>

每秒最大未限制的写入I/O池操作数。

iops_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

mbps`=`<mbps>

每秒的最大读写速度,以兆字节为单位。

mbps_max`=`<mbps>

最大未限制的读/写池,以每秒兆字节计。

mbps_rd`=`<mbps>

最大读取速度,以每秒兆字节计。

mbps_rd_max`=`<mbps>

每秒以兆字节计的最大未限制读取池。

mbps_wr`=`<mbps>

每秒最大写入速度,以兆字节计。

mbps_wr_max`=`<mbps>

每秒以兆字节计的最大未限速写入池。

media`=<cdrom | disk> (default = disk)

驱动器的媒体类型。

replicate`=<boolean> (default = 1)

是否应将驱动器考虑用于复制任务。

rerror`=`<ignore | report | stop>

读取错误操作。

secs`=`<integer>

强制驱动器的物理几何结构具有特定的扇区计数。

serial`=`<serial>

驱动器报告的序列号,进行URL编码,最长20个字节。

shared`=<boolean> (default = 0)

将这个本地管理的卷标记为在所有节点上可用。

Warning
这个选项不会自动共享卷,它假设卷已经共享了!
size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

snapshot`=`<boolean>

控制qemu的快照模式特性。如果激活,对磁盘所做的更改是临时的,并且会在虚拟机关闭时被丢弃。

ssd`=`<boolean>

是否将此驱动器暴露为SSD,而不是旋转硬盘。

trans=<auto | lba | none>

强制磁盘几何结构BIOS转换模式。

werror`=`<enospc | ignore | report | stop>

写入错误操作。

wwn`=`<wwn>

驱动器的全球名称,以16字节的十六进制字符串形式编码,前缀为'0x'。

scsi[n]`: `[file=]<volume> [,aio=<native|threads|io_uring>] [,backup=<1|0>] [,bps=<bps>] [,bps_max_length=<seconds>] [,bps_rd=<bps>] [,bps_rd_max_length=<seconds>] [,bps_wr=<bps>] [,bps_wr_max_length=<seconds>] [,cache=<enum>] [,cyls=<integer>] [,detect_zeroes=<1|0>] [,discard=<ignore|on>] [,format=<enum>] [,heads=<integer>] [,iops=<iops>] [,iops_max=<iops>] [,iops_max_length=<seconds>] [,iops_rd=<iops>] [,iops_rd_max=<iops>] [,iops_rd_max_length=<seconds>] [,iops_wr=<iops>] [,iops_wr_max=<iops>] [,iops_wr_max_length=<seconds>] [,iothread=<1|0>] [,mbps=<mbps>] [,mbps_max=<mbps>] [,mbps_rd=<mbps>] [,mbps_rd_max=<mbps>] [,mbps_wr=<mbps>] [,mbps_wr_max=<mbps>] [,media=<cdrom|disk>] [,product=<product>] [,queues=<integer>] [,replicate=<1|0>] [,rerror=<ignore|report|stop>] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=<integer>] [,serial=<serial>] [,shared=<1|0>] [,size=<DiskSize>] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=<none|lba|auto>] [,vendor=<vendor>] [,werror=<enum>] [,wwn=<wwn>]

将卷作为SCSI硬盘或CD-ROM使用(n为0到30)。

aio`=`<io_uring | native | threads>

要使用的AIO类型。

backup`=`<boolean>

在进行备份时是否应该包括驱动器。

bps`=`<bps>

每秒最大读写速度(以字节计)。

bps_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

bps_rd`=`<bps>

每秒最大读取速度(以字节为单位)。

bps_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

bps_wr`=`<bps>

每秒最大写入速度(以字节计)。

bps_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

cache`=`<directsync | none | unsafe | writeback | writethrough>

驱动器的缓存模式

cyls`=`<integer>

强制驱动器的物理几何结构具有特定的柱面数。

detect_zeroes`=`<boolean>

控制是否检测并尝试优化写入零的操作。

discard`=`<ignore | on>

控制是否将丢弃/修剪请求传递给底层存储。

file`=`<volume>

驱动器的后备卷。

format=<cloop | cow | qcow | qcow2 | qed | raw | vmdk>

驱动器备份文件的数据格式。

heads`=`<integer>

强制驱动器的物理几何形状具有特定的磁头数量。

iops`=`<iops>

最大读/写I/O操作每秒的次数。

iops_max`=`<iops>

每秒未限制的最大读/写I/O池操作数。

iops_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

iops_rd`=`<iops>

每秒最大读取I/O操作数。

iops_rd_max`=`<iops>

每秒最大无限制读取I/O池操作数。

iops_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

iops_wr`=`<iops>

最大写入I/O的操作次数每秒。

iops_wr_max`=`<iops>

每秒最大未限制的写入I/O池操作数。

iops_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

iothread`=`<boolean>

是否为此驱动器使用iothreads

mbps`=`<mbps>

每秒的最大读写速度,以兆字节为单位。

mbps_max`=`<mbps>

最大未限制的读/写池,以每秒兆字节计。

mbps_rd`=`<mbps>

最大读取速度,以每秒兆字节计。

mbps_rd_max`=`<mbps>

每秒以兆字节计的最大未限制读取池。

mbps_wr`=`<mbps>

每秒最大写入速度,以兆字节计。

mbps_wr_max`=`<mbps>

每秒以兆字节计的最大未限速写入池。

media`=<cdrom | disk> (default = disk)

驱动器的媒体类型。

product`=`<product>

驱动器的产品名称,最长16个字节。

queues`=`<integer> (2 - N)

队列数量。

replicate`=<boolean> (default = 1)

是否应将驱动器考虑用于复制任务。

rerror`=`<ignore | report | stop>

读取错误操作。

ro`=`<boolean>

驱动器是否是只读的。

scsiblock`=<boolean> (default = 0)

是否使用scsi-block来完全透传宿主机的块设备

Warning
结合主机上的低内存或高内存碎片使用,可能会导致I/O错误。
secs`=`<integer>

强制驱动器的物理几何结构具有特定的扇区计数。

serial`=`<serial>

驱动器报告的序列号,进行URL编码,最长20个字节。

shared`=<boolean> (default = 0)

将这个本地管理的卷标记为在所有节点上可用。

Warning
这个选项不会自动共享卷,它假设卷已经共享了!
size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

snapshot`=`<boolean>

控制qemu的快照模式特性。如果激活,对磁盘所做的更改是临时的,并且会在虚拟机关闭时被丢弃。

ssd`=`<boolean>

是否将此驱动器暴露为SSD,而不是旋转硬盘。

trans=<auto | lba | none>

强制磁盘几何结构BIOS转换模式。

vendor`=`<vendor>

驱动器的厂商名称,最长不超过8字节。

werror`=`<enospc | ignore | report | stop>

写入错误操作。

wwn`=`<wwn>

驱动器的全球名称,以16字节的十六进制字符串形式编码,前缀为'0x'。

scsihw`: <lsi | lsi53c810 | megasas | pvscsi | virtio-scsi-pci | virtio-scsi-single> (default = lsi)

SCSI控制器型号

searchdomain`: `<string>

cloud-init:为容器设置DNS搜索域。如果没有设置searchdomain或nameserver,则创建操作会自动使用主机的设置。

serial[n]`: `(/dev/.+|socket)

在虚拟机内创建一个序列设备(n为0到3),并穿透一个主机序列设备(即/dev/ttyS0),或者在主机侧创建一个unix套接字(使用’qm terminal’打开一个终端连接)。

Note
如果你通过宿主的串行设备,就不再可能迁移这样的机器 - 使用时需特别小心。
Caution
实验性功能!用户报告此选项有问题。
shares`: <integer> (0 - 50000) (default = 1000)

自动气球式内存共享的数量。这个数字越大,虚拟机(VM)获得的内存就越多。这个数字是相对于所有其他运行中的虚拟机的权重而言的。使用零将禁用自动气球式内存分配。自动气球式内存分配是通过pvestatd完成的。

smbios1`: `[base64=<1|0>] [,family=<Base64 encoded string>] [,manufacturer=<Base64 encoded string>] [,product=<Base64 encoded string>] [,serial=<Base64 encoded string>] [,sku=<Base64 encoded string>] [,uuid=<UUID>] [,version=<Base64 encoded string>]

指定SMBIOS类型1字段。

base64`=`<boolean>

用于指示SMBIOS值是否为base64编码的标志

family`=`<Base64编码字符串>

设置 SMBIOS1 家族字符串。

manufacturer`=`<Base64 encoded string>

设置 SMBIOS1 的制造商。

product`=`<Base64 encoded string>

设置 SMBIOS1 产品 ID。

serial`=`<Base64编码字符串>

设置SMBIOS1序列号。

sku`=`<Base64 encoded string>

设置 SMBIOS1 SKU 字符串。

uuid`=`<UUID>

设置 SMBIOS1 UUID。

version`=`<Base64 encoded string>

设置SMBIOS1版本。

smp`:<整数> (1 - N)(默认值=1

CPU的数量。请使用选项-sockets代替。

sockets`: <integer> (1 - N) (default = 1)

CPU插槽的数量。

spice_enhancements`: `[foldersharing=<1|0>] [,videostreaming=<off|all|filter>]

为SPICE配置额外的增强功能。

foldersharing`=<boolean> (default = 0)

启用通过SPICE共享文件夹。需要在虚拟机中安装Spice-WebDAV守护程序。

videostreaming`=<all | filter | off> (default = off)

启用视频流。对检测到的视频流使用压缩。

sshkeys`: `<string>

cloud-init:设置公共SSH密钥(每行一个密钥,OpenSSH格式)。

startdate`: (now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS) (default = now)

设置实时时钟的初始日期。有效的日期格式包括:now2006-06-17T16:01:212006-06-17

startup`: `[[order=]\d+] [,up=\d+] [,down=\d+]

启动和关闭行为。顺序是一个非负数,用来定义一般的启动顺序。关闭操作则以相反的顺序执行。此外,您还可以设置“启动(up)”或“关闭(down)”的延迟时间(以秒为单位),这指定了在启动或停止下一个虚拟机之前等待的延迟时间。

tablet`: <boolean> (default = 1)

启用/禁用USB平板设备。通常需要此设备才能允许VNC的绝对鼠标定位。否则,鼠标会与普通VNC客户端失去同步。如果你在一个主机上运行了很多仅控制台的客户机,你可以考虑禁用它以节省一些上下文切换。如果你使用spice(qm set <vmid> --vga qxl),默认情况下这个功能是关闭的。

tags`: `<string>

虚拟机的标签。这只是元信息。

tdf`:<boolean>(默认值为`0`)

启用/禁用时间漂移修复。

template`: <boolean> (default = 0)

启用/禁用模板。

tpmstate0`: `[file=]<volume> [,size=<DiskSize>] [,version=<v1.2|v2.0>]

配置一个磁盘用于存储TPM状态。格式固定为’raw'。

file`=`<volume>

驱动器的后备卷。

size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

version`=<v1.2 | v2.0> (default = v2.0)

TPM接口版本。v2.0是较新的版本,应该优先考虑。请注意,此项稍后不能更改。

unused[n]: `[file=]<volume>

对未使用卷的引用。这是内部使用的,不应手动修改。

file`=`<volume>

驱动器的后备卷。

usb[n]`: `[[host=]<HOSTUSBDEVICE|spice>] [,mapping=<mapping-id>] [,usb3=<1|0>]

配置一个USB设备(n的范围是0到4,对于机器版本>= 7.1且操作系统类型为l26或windows > 7,n可以达到14)。

host`=`<HOSTUSBDEVICE|spice>

主机USB设备或端口或值’spice'。HOSTUSBDEVICE语法为:

' bus-port(.port)* (十进制数字)或 vendor_id:product_id (十六进制数字)或 spice '

你可以使用 lsusb -t 命令来列出现有的usb设备。

Note
这个选项允许直接访问主机硬件。因此,不再可能迁移这样的机器 - 请谨慎使用。

spice 可用于为 spice 添加 usb 重定向设备。

必须设置“这个”或“mapping”键。

mapping`=`<mapping-id>

集群范围映射的ID。必须设置此项或默认键’host'。

usb3`=<boolean> (default = 0)

指定给定的主机选项是否为USB3设备或端口。对于现代客户机(机器版本 >= 7.1 且 ostype l26 以及 windows > 7),此标志无关紧要(所有设备都插入xhci控制器)。

vcpus`: <integer> (1 - N) (default = 0)

热插拔虚拟CPU的数量。

vga`: `[[type=]<enum>] [,clipboard=<vnc>] [,memory=<integer>]

配置VGA硬件。如果你想使用高分辨率模式(>= 1280x1024x16),你可能需要增加vga内存选项。自QEMU 2.9版起,默认的VGA显示类型为所有操作系统类型的’std',除了一些Windows版本(XP及更旧的版本)使用’cirrus'。'qxl’选项启用了SPICE显示服务器。对于win*操作系统,你可以选择想要多少独立显示器,Linux客户端可以自己添加显示器。你也可以不使用任何图形卡,使用串行设备作为终端。

clipboard=<vnc>

启用特定的剪贴板。如果未设置,根据显示类型,将添加SPICE剪贴板。目前还不支持与VNC剪贴板的迁移!

memory`=`<integer> (4 - 512)

设置VGA内存(以MiB为单位)。在串行显示中无效。

type=<cirrus | none | qxl | qxl2 | qxl3 | qxl4 | serial0 | serial1 | serial2 | serial3 | std | virtio | virtio-gl | vmware> (default = std)

选择VGA类型。

virtio[n]`: `[file=]<volume> [,aio=<native|threads|io_uring>] [,backup=<1|0>] [,bps=<bps>] [,bps_max_length=<seconds>] [,bps_rd=<bps>] [,bps_rd_max_length=<seconds>] [,bps_wr=<bps>] [,bps_wr_max_length=<seconds>] [,cache=<enum>] [,cyls=<integer>] [,detect_zeroes=<1|0>] [,discard=<ignore|on>] [,format=<enum>] [,heads=<integer>] [,iops=<iops>] [,iops_max=<iops>] [,iops_max_length=<seconds>] [,iops_rd=<iops>] [,iops_rd_max=<iops>] [,iops_rd_max_length=<seconds>] [,iops_wr=<iops>] [,iops_wr_max=<iops>] [,iops_wr_max_length=<seconds>] [,iothread=<1|0>] [,mbps=<mbps>] [,mbps_max=<mbps>] [,mbps_rd=<mbps>] [,mbps_rd_max=<mbps>] [,mbps_wr=<mbps>] [,mbps_wr_max=<mbps>] [,media=<cdrom|disk>] [,replicate=<1|0>] [,rerror=<ignore|report|stop>] [,ro=<1|0>] [,secs=<integer>] [,serial=<serial>] [,shared=<1|0>] [,size=<DiskSize>] [,snapshot=<1|0>] [,trans=<none|lba|auto>] [,werror=<enum>]

将卷作为 VIRTIO 硬盘使用(n 为 0 到 15)。

aio`=`<io_uring | native | threads>

要使用的AIO类型。

backup`=`<boolean>

在进行备份时是否应该包括驱动器。

bps`=`<bps>

每秒最大读写速度(以字节计)。

bps_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

bps_rd`=`<bps>

每秒最大读取速度(以字节为单位)。

bps_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

bps_wr`=`<bps>

每秒最大写入速度(以字节计)。

bps_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

cache`=`<directsync | none | unsafe | writeback | writethrough>

驱动器的缓存模式

cyls`=`<integer>

强制驱动器的物理几何结构具有特定的柱面数。

detect_zeroes`=`<boolean>

控制是否检测并尝试优化写入零的操作。

discard`=`<ignore | on>

控制是否将丢弃/修剪请求传递给底层存储。

file`=`<volume>

驱动器的后备卷。

format=<cloop | cow | qcow | qcow2 | qed | raw | vmdk>

驱动器备份文件的数据格式。

heads`=`<integer>

强制驱动器的物理几何形状具有特定的磁头数量。

iops`=`<iops>

最大读/写I/O操作每秒的次数。

iops_max`=`<iops>

每秒未限制的最大读/写I/O池操作数。

iops_max_length`=`<seconds>

I/O突发的最大长度,以秒为单位。

iops_rd`=`<iops>

每秒最大读取I/O操作数。

iops_rd_max`=`<iops>

每秒最大无限制读取I/O池操作数。

iops_rd_max_length`=`<seconds>

读取I/O突发的最大长度,以秒为单位。

iops_wr`=`<iops>

最大写入I/O的操作次数每秒。

iops_wr_max`=`<iops>

每秒最大未限制的写入I/O池操作数。

iops_wr_max_length`=`<seconds>

写入I/O爆发的最大长度,以秒为单位。

iothread`=`<boolean>

是否为此驱动器使用iothreads

mbps`=`<mbps>

每秒的最大读写速度,以兆字节为单位。

mbps_max`=`<mbps>

最大未限制的读/写池,以每秒兆字节计。

mbps_rd`=`<mbps>

最大读取速度,以每秒兆字节计。

mbps_rd_max`=`<mbps>

每秒以兆字节计的最大未限制读取池。

mbps_wr`=`<mbps>

每秒最大写入速度,以兆字节计。

mbps_wr_max`=`<mbps>

每秒以兆字节计的最大未限速写入池。

media`=<cdrom | disk> (default = disk)

驱动器的媒体类型。

replicate`=<boolean> (default = 1)

是否应将驱动器考虑用于复制任务。

rerror`=`<ignore | report | stop>

读取错误操作。

ro`=`<boolean>

驱动器是否是只读的。

secs`=`<integer>

强制驱动器的物理几何结构具有特定的扇区计数。

serial`=`<serial>

驱动器报告的序列号,进行URL编码,最长20个字节。

shared`=<boolean> (default = 0)

将这个本地管理的卷标记为在所有节点上可用。

Warning
这个选项不会自动共享卷,它假设卷已经共享了!
size`=`<DiskSize>

磁盘大小。这纯粹是信息性的,并没有任何影响。

snapshot`=`<boolean>

控制qemu的快照模式特性。如果激活,对磁盘所做的更改是临时的,并且会在虚拟机关闭时被丢弃。

trans=<auto | lba | none>

强制磁盘几何结构BIOS转换模式。

werror`=`<enospc | ignore | report | stop>

写入错误操作。

vmgenid`: <UUID> (默认值= 1 (自动生成))

VM生成ID(vmgenid)设备向宾操作系统公开了一个128位整数值标识符。这允许在虚拟机以不同配置执行时(例如,执行快照或从模板创建)通知宾操作系统。宾操作系统注意到变化,并能够适当反应,通过将其分布式数据库的副本标记为脏数据,重新初始化其随机数生成器等。请注意,自动创建仅在通过API/CLI创建或更新方法时有效,手动编辑配置文件时不适用。

vmstatestorage`: `<string>

默认存储用于虚拟机状态卷/文件。

watchdog`: `[[model=]<i6300esb|ib700>] [,action=<enum>]

创建一个虚拟硬件看门狗设备。一旦被启用(通过客体动作),这个看门狗就必须被客体内的一个代理定期轮询,否则看门狗将会重置客体(或执行指定的相应操作)。

action`=`<debug | none | pause | poweroff | reset | shutdown>

如果激活后,来宾无法及时轮询看门狗,则执行的操作。

model`=<i6300esb | ib700> (default = i6300esb)

要模拟的看门狗类型。

在线迁移、快照和备份(vzdump)会设置一个锁,以防止对受影响的虚拟机执行不兼容的并发操作。有时候,您需要手动移除这样的锁(例如,在电源故障之后)。

# qm unlock <vmid>
Caution
仅在你确定设置锁定的操作不再运行时才执行该操作。

1. PCID现在是x86上一个关键的性能/安全特性 https://groups.google.com/forum/m/#!topic/mechanical-sympathy/L9mHTbeQLNU
2. https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/virtualized-domain-controller-architecture