以下章节将重点介绍常见虚拟化任务,并说明 Proxmox VE 在主机管理和运维方面的特定内容。
Pxvirt 基于 OpenEuler GNU/Linux,并通过额外仓库提供 Proxmox VE 相关软件包。这意味着可以使用完整的 OpenEuler 软件包体系,包括安全更新和错误修复。
Pxvirt提供基于 OpenEuler kernel 的自有 Linux kernel,并启用了所有必要的虚拟化和容器功能, 同时包含 ZFS 以及若干额外硬件驱动。
对于以下章节未涵盖的其他主题,请参考 OpenEuler 文档。在线版
软件包仓库
Proxmox VE 基于 openEuler,使用 RPM 软件包格式,并通过 dnf 管理软件包和仓库。
Proxmox VE 每天自动检查软件包更新。root@pam 用户会通过电子邮件收到可用更新通知。 在 GUI 中,可以使用 Changelog 按钮查看所选更新的更多详细信息。
Proxmox VE 中的软件仓库
仓库是一组软件包集合,可用于安装新软件,也是获取安全更新、错误修复和新功能的重要来源。
|
|
需要配置有效的 openEuler 基础仓库和 PXVIRT 仓库,才能获得完整的软件包依赖和更新。 |
DNF 仓库定义在 /etc/yum.repos.d/ 目录下的 .repo 文件中。每个仓库通常包含 baseurl、enabled、gpgcheck、gpgkey 等字段。
PXVIRT 仓库
PXVIRT 软件包通过梨儿方 PXVIRT 仓库发布。请在每个 Proxmox VE 节点上创建 /etc/yum.repos.d/pxvirt.repo:
[pxvirt] name=Lierfang PxVirt Repo baseurl=https://mirrors.lierfang.com/pxcloud/pxvirt/repo/openeuler/24.03/$basearch enabled=1 gpgcheck=1 gpgkey=https://mirrors.lierfang.com/pxcloud/lierfang.gpg
也可以使用编辑器创建该文件:
# editor /etc/yum.repos.d/pxvirt.repo [pxvirt] name=Lierfang PxVirt Repo baseurl=https://mirrors.lierfang.com/pxcloud/pxvirt/repo/openeuler/24.03/$basearch enabled=1 gpgcheck=1 gpgkey=https://mirrors.lierfang.com/pxcloud/lierfang.gpg
配置完成后,刷新软件包元数据:
# chmod 0600 /etc/yum.repos.d/pxvirt.repo # dnf makecache
如果需要确认仓库是否已经启用,可以运行:
# dnf repolist
Ceph 软件包仓库
PXVIRT 的 openEuler 版本不使用 Proxmox 的独立 Ceph 仓库。 不要沿用 Proxmox 文档中的 enterprise、no-subscription 或 test Ceph 仓库地址。
如需安装或更新 Ceph 相关软件包,请使用已配置的 openEuler 基础仓库和 PXVIRT 仓库。 如果使用外部 Ceph 集群,只需要按存储章节配置客户端连接信息。
软件包签名验证
PXVIRT 仓库启用了 gpgcheck=1,DNF 会使用 gpgkey 指定的 GPG 公钥验证软件包签名。 如果密钥尚未导入,首次安装或更新软件包时,DNF 会提示导入该密钥。
也可以手动导入仓库密钥:
# rpm --import https://mirrors.lierfang.com/pxcloud/lierfang.gpg
ßß ==== 常用命令示例 ß 以下命令可用于刷新软件包索引、查看可升级软件包,并检查 Proxmox VE 软件包版本:
# dnf makecache # dnf check-update # pveversion -v
安装所有可用更新:
# dnf update
系统软件更新
Proxmox 会定期为所有软件仓库提供更新。要安装更新,可以使用基于 Web 的 GUI,或使用以下 CLI 命令:
# dnf makecache # dnf update
|
|
DNF 包管理系统非常灵活,并提供许多功能;更多信息请参见 man dnf。 |
|
|
定期更新对于获取最新补丁和安全相关修复至关重要。重大系统升级会在 Pxvirt Community Forum 中公告。 |
固件更新
在裸金属服务器上运行 Proxmox VE 时,应应用本章所述的固件更新。是否适合在客户机内部配置固件更新 (例如使用设备直通时)高度依赖具体部署,因此不在本章讨论范围内。
除了常规软件更新,固件更新对于可靠、安全的运行同样重要。
在获取并应用固件更新时,建议结合使用可用的多种方法,以便尽早获得更新,或确保能够获得更新。
从术语上看,firmware 通常分为微码(用于 CPU)和固件(用于其他设备)。
持久化固件
本节适用于所有设备。更新后的微码通常包含在 BIOS/UEFI 更新中,并存储在主板上; 其他固件则存储在相应设备上。这种持久化方式对 CPU 尤其重要,因为它允许在启动时尽早按常规流程加载更新后的微码。
|
|
某些更新(例如 BIOS/UEFI 或存储控制器更新)可能会重置设备配置。请仔细遵循厂商说明,并备份当前配置。 |
请向厂商确认可用的更新方法。
-
服务器的便捷更新方法可能包括 Dell 的 Lifecycle Manager 或 HPE 的 Service Packs。
-
有时也可以使用 Linux 实用工具。例如,NVIDIA ConnectX 可使用 mlxup,Broadcom 网卡可使用 bnxtnvm/niccli。
-
如果正在使用的 硬件厂商与 LVFS 合作,并且硬件属于 受支持硬件,那么 LVFS 也是一种选择。 其技术要求是系统制造于 2014 年之后,并通过 UEFI 启动。
在 openEuler 中,可以通过 fwupd 软件包使用 LVFS 提供的固件更新。 如果系统未能自动识别 EFI 分区位置,可以在 /etc/fwupd/daemon.conf 中显式配置正确的挂载点,例如:
# Override the location used for the EFI system partition (ESP) path. EspLocation=/boot/efi
|
|
如果更新说明要求重启主机,请确保可以安全执行。另请参见 节点维护。 |
运行时固件文件
此方法将固件存储在 Proxmox VE 操作系统中;如果设备的 持久化固件版本较旧,则会将该固件传递给设备。 该方法受网络卡、显卡等设备支持,但不适用于依赖持久化固件的设备,例如主板和硬盘。
在 Proxmox VE 中,常见硬件所需的运行时固件由 openEuler 的 linux-firmware 软件包提供。因此,通过常规的 系统更新, 常见硬件所包含的固件会自动保持最新。
如需额外固件,请确认已经启用相应的 openEuler 软件源。
如果尝试安装额外固件软件包但发生冲突,DNF 将中止安装。特定固件也许可以通过其他方式获取。
CPU 微码更新
微码更新用于修复已发现的安全漏洞和其他严重 CPU 缺陷。虽然 CPU 性能可能受到影响, 但已打补丁的微码通常仍然比由内核自行执行缓解措施的未打补丁微码具有更好的性能。 根据 CPU 类型不同,如果不有意让 CPU 运行在不安全状态,可能无法再达到存在缺陷的出厂状态下的性能结果。
要查看当前 CPU 漏洞及其缓解措施概览,请运行 lscpu。只有当 Proxmox VE 主机 保持最新、版本尚未 结束生命周期,并且自上次内核更新以来至少重启过一次时, 当前真实世界中已知的漏洞才会显示出来。
除了推荐通过 持久化 BIOS/UEFI 更新来更新微码之外, 还可以使用一种独立方式:早期 OS 微码更新。这种方式使用方便, 在主板厂商不再提供 BIOS/UEFI 更新时也很有帮助。无论使用哪种方法,应用微码更新都始终需要重启。
设置早期 OS 微码更新
要设置由 Linux 内核在启动早期应用的微码更新,需要:
-
确认已经启用相应的 openEuler 软件源
-
获取最新可用软件包:dnf makecache(也可以使用 Web 界面中的 Node → Updates)
-
安装 CPU 微码软件包:dnf install microcode_ctl
-
重启 Proxmox VE 主机
之后的任何微码更新也都需要重启后才能加载。
微码版本
要获取当前正在运行的微码修订版以便比较或调试:
# grep microcode /proc/cpuinfo | uniq microcode : 0xf0
一个微码软件包包含许多不同 CPU 的更新。但专门适用于你的 CPU 的更新可能并不频繁。 因此,仅查看软件包日期并不能说明厂商何时实际为你的特定 CPU 发布了更新。
如果已安装新的微码软件包并重启 Proxmox VE 主机,且这个新微码同时比 CPU 内置版本和主板固件提供的版本更新, 系统日志中会出现 "microcode updated early" 消息。
# dmesg | grep microcode [ 0.000000] microcode: microcode updated early to revision 0xf0, date = 2021-11-12 [ 0.896580] microcode: Microcode Update Driver: v2.2.
故障排查
出于调试目的,可以按如下方式临时禁用系统启动时常规应用的早期 OS 微码更新:
-
确保主机可以 安全重启
-
重启主机以进入 GRUB 菜单(如果菜单隐藏,请按住 SHIFT)
-
在所需的 Proxmox VE 启动项上按 E
-
转到以 linux 开头的行,并以空格分隔追加 dis_ucode_ldr
-
按 CTRL-X,本次启动将不使用早期 OS 微码更新
如果怀疑问题与最近的微码更新有关,应考虑软件包降级,而不是移除软件包 (dnf remove microcode_ctl)。否则,可能会加载过旧的 持久化微码,即使较新的微码本可以正常运行。
如果 openEuler 软件源中存在较早版本的微码软件包,则可以降级,如以下示例所示:
# dnf --showduplicates list microcode_ctl Installed Packages microcode_ctl.x86_64 4:2.1-53.oe2203sp4 @OS Available Packages microcode_ctl.x86_64 4:2.1-51.oe2203sp4 OS
# dnf downgrade microcode_ctl ... Downgrading: microcode_ctl x86_64 4:2.1-51.oe2203sp4 OS ... Complete! ...
再次确认主机可以 安全重启。要应用该微码软件包中可能包含的、 适用于你 CPU 类型的较旧微码,请立即重启。
|
|
将降级后的软件包保持一段时间,然后稍后再尝试更新版本,是合理的做法。即使未来软件包版本相同, 期间的系统更新也可能已经修复曾遇到的问题。 # dnf versionlock add microcode_ctl # dnf versionlock delete microcode_ctl # dnf makecache # dnf update |
网络配置
Proxmox VE 使用 Linux 网络栈。这使 Proxmox VE 节点上的网络设置具备很高的灵活性。可以通过 GUI 完成配置,也可以手动编辑包含完整网络配置的 /etc/network/interfaces 文件。interfaces(5) 手册页包含完整的格式说明。所有 Proxmox VE 工具都会尽量保留用户的直接修改,但仍然更建议使用 GUI,因为它可以帮助避免错误。
需要使用 Linux bridge 接口(通常称为 vmbrX)将客户机连接到底层物理网络。可以将其理解为一个虚拟交换机,客户机和物理接口都连接到该交换机。本节提供一些网络设置示例,以适配不同使用场景,例如通过 bond 实现冗余、使用 vlans,或采用 routed 与 NAT 配置。
Software Defined Network 可用于 Proxmox VE 集群中更复杂的虚拟网络。
|
|
如果不确定其影响,不建议使用传统 Debian 工具 ifup 和 ifdown,因为它们存在一些容易踩到的问题。例如执行 ifdown vmbrX 会中断所有客户机流量,但之后对同一 bridge 执行 ifup 时不会重新连接这些客户机。 |
应用网络更改
Proxmox VE 不会将更改直接写入 /etc/network/interfaces。相反,系统会写入名为 /etc/network/interfaces.new 的临时文件,这样可以一次完成多项相关更改。这也允许在应用前确认更改是否正确,因为错误的网络配置可能导致节点无法访问。
命名约定
当前设备名称使用以下命名约定:
-
Ethernet 设备:en*,即 systemd 网络接口名称。自 5.0 版本起,新的 Proxmox VE 安装使用此命名方案。
-
Ethernet 设备:eth[N],其中 0 ≤ N(eth0、eth1 等)。该命名方案用于 5.0 发布前安装的 Proxmox VE 主机。升级到 5.0 时,名称会保持不变。
-
Bridge 名称:通常为 vmbr[N],其中 0 ≤ N ≤ 4094(vmbr0 - vmbr4094),但也可以使用任意以字符开头、最长 10 个字符的字母数字字符串。
-
Bonds:bond[N],其中 0 ≤ N(bond0、bond1 等)。
-
VLAN:直接在设备名称后追加 VLAN 编号,并用句点分隔(eno1.50、bond1.30)。
这样更容易调试网络问题,因为设备名称能够体现设备类型。
Systemd 网络接口名称
Systemd 为网络设备名称定义了带版本的命名方案。该方案对 Ethernet 网络设备使用两个字符的前缀 en。后续字符取决于设备驱动、设备位置和其他属性。可能的模式包括:
-
o<index>[n<phys_port_name>|d<dev_port>] — 板载设备
-
s<slot>[f<function>][n<phys_port_name>|d<dev_port>] — 按热插拔 ID 标识的设备
-
[P<domain>]p<bus>s<slot>[f<function>][n<phys_port_name>|d<dev_port>] — 按总线 ID 标识的设备
-
x<MAC> — 按 MAC 地址标识的设备
以下是最常见模式的一些示例:
-
eno1 — 第一块板载 NIC
-
enp3s0f1 — PCI 总线 3、插槽 0 上 NIC 的功能 1
有关所有可能设备名称模式的完整列表,请参见 systemd.net-naming-scheme(7) 手册页。
新版本的 systemd 可能会定义新版网络设备命名方案,并默认使用该方案。因此,更新到较新的 systemd 版本时,例如进行 Proxmox VE 大版本升级期间,网络设备名称可能发生变化,并需要调整网络配置。为避免因命名方案新版本导致名称变化,可以手动固定特定命名方案版本(见 下文)。
但是,即使命名方案版本已固定,网络设备名称仍可能因内核或驱动更新而变化。要彻底避免特定网络设备名称变化,可以使用 link 文件手动覆盖其名称(见 下文)。
有关网络接口名称的更多信息,请参见 Predictable Network Interface Names。
固定特定命名方案版本
可以通过向 内核命令行 添加 net.naming-scheme=<version> 参数,固定网络设备命名方案的特定版本。有关命名方案版本列表,请参见 systemd.net-naming-scheme(7) 手册页。
例如,要固定版本 v252(这是全新安装 Proxmox VE 8.0 时使用的最新命名方案版本),请添加以下内核命令行参数:
net.naming-scheme=v252
另请参见 本节,了解如何编辑内核命令行。需要重启后更改才会生效。
覆盖网络设备名称
使用 pve-network-interface-pinning 工具
Proxmox VE 提供了一个工具,可自动生成用于覆盖网络设备名称的 .link 文件。它还会自动替换以下文件中出现的旧接口名称:
-
/etc/network/interfaces
-
/etc/pve/nodes/<nodename>/host.fw
-
/etc/pve/sdn/controllers.cfg
|
|
由于生成的映射只属于生成它的本地节点,Firewall Datacenter 配置(/etc/pve/firewall/cluster.fw)中包含的接口名称不会自动更新。 |
生成的 link 文件存放在 /usr/local/lib/systemd/network 中。对于配置文件,会在相同位置生成带 .new 后缀的新文件。这样可以使用 diff(或你选择的其他 diff 查看器)检查对配置所做的更改:
diff -y /etc/network/interfaces /etc/network/interfaces.new
如果发现任何有问题的更改,或希望在重启前撤销 pinning 工具所做的更改,只需删除所有 .new 文件以及 /usr/local/lib/systemd/network 中对应的 link 文件。
以下命令会为尚未拥有 .link 文件的所有物理网络接口生成 .link 文件,并更新选定的 Proxmox VE 配置文件(见上文)。生成的名称将使用默认前缀 nic,因此得到的接口名称会是 nic1、nic2 等。
pve-network-interface-pinning generate
可以使用 --prefix 标志覆盖默认前缀:
pve-network-interface-pinning generate --prefix myprefix
也可以只固定特定接口:
pve-network-interface-pinning generate --interface enp1s0
固定特定接口时,可以指定该接口应固定为的精确名称:
pve-network-interface-pinning generate --interface enp1s0 --target-name if42
要将 pve-network-interface-pinning 所做更改应用到网络配置,需要重启节点。
手动方法
可以使用自定义 systemd.link 文件为特定网络设备手动分配名称。这会覆盖按最新网络设备命名方案原本会分配的名称。通过这种方式,可以避免因内核更新、驱动更新或命名方案新版本导致名称变化。
自定义 link 文件应放在 /etc/systemd/network/ 中,并命名为 <n>-<id>.link,其中 n 是小于 99 的优先级,id 是某个标识符。link 文件包含两个小节:[Match] 决定该文件应用到哪些接口;[Link] 决定这些接口应如何配置,包括其命名。
要为特定网络设备分配名称,需要在 [Match] 小节中以唯一且持久的方式标识该设备。一种做法是使用 MACAddress 选项匹配设备的 MAC 地址,因为它通常不会变化。
[Match] 小节还应包含 Type 选项,以确保只匹配预期的物理接口,而不是具有相同 MAC 地址的 bridge/bond/VLAN 接口。在大多数配置中,Type 应设置为 ether,以便只匹配 Ethernet 设备,但某些配置可能需要其他选择。更多细节请参见 systemd.link(5) 手册页。
然后,可以在 [Link] 小节中使用 Name 选项分配名称。
link 文件会被复制到 initramfs,因此建议在添加、修改或移除 link 文件后刷新 initramfs:
# update-initramfs -u -k all
例如,要将名称 enwan0 分配给 MAC 地址为 aa:bb:cc:dd:ee:ff 的 Ethernet 设备,请创建文件 /etc/systemd/network/10-enwan0.link,内容如下:
[Match] MACAddress=aa:bb:cc:dd:ee:ff Type=ether [Link] Name=enwan0
不要忘记调整 /etc/network/interfaces 以使用新名称,并按上文所述刷新 initramfs。需要重启节点后更改才会生效。
|
|
建议分配以 en 或 eth 开头的名称,使 Proxmox VE 能够将该接口识别为物理网络设备,并通过 GUI 进行配置。同时,应确保该名称未来不会与其他接口名称冲突。一种做法是分配一个不匹配 systemd 网络接口任何命名模式的名称(见上文),例如上例中的 enwan0。 |
有关 link 文件的更多信息,请参见 systemd.link(5) 手册页。
选择网络配置
可以根据当前网络组织方式和可用资源,选择 bridged、routed 或 masquerading 网络配置。
使用 Bridge 的默认配置
安装程序会创建一个名为 vmbr0 的 bridge,并将其连接到第一块 Ethernet 网卡。/etc/network/interfaces 中的对应配置可能如下:
auto lo
iface lo inet loopback
iface eno1 inet manual
auto vmbr0
iface vmbr0 inet static
address 192.168.10.2/24
gateway 192.168.10.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
虚拟机的行为就像直接连接到物理网络一样。反过来,网络会将每台虚拟机视为拥有自己的 MAC,即使所有这些虚拟机实际只通过一根网络线缆连接到网络。
路由配置
大多数托管服务提供商不支持上述配置。出于安全原因,一旦检测到单个接口上存在多个 MAC 地址,它们就会禁用网络。
|
|
某些提供商允许通过其管理界面注册额外 MAC。这可以避免该问题,但配置起来可能比较繁琐,因为需要为每台虚拟机注册一个 MAC。 |
可以通过将所有流量经由单个接口“路由”来避免该问题。这可以确保所有网络数据包都使用同一个 MAC 地址。
auto lo
iface lo inet loopback
auto eno0
iface eno0 inet static
address 198.51.100.5/29
gateway 198.51.100.1
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up echo 1 > /proc/sys/net/ipv4/conf/eno0/proxy_arp
auto vmbr0
iface vmbr0 inet static
address 203.0.113.17/28
bridge-ports none
bridge-stp off
bridge-fd 0
使用 iptables 的 Masquerading(NAT)
Masquerading 允许只有私有 IP 地址的客户机通过主机 IP 地址作为出站流量来源来访问网络。每个出站数据包都会由 iptables 重写,使其看起来像是源自主机;响应也会相应重写,以便路由回原始发送方。
auto lo
iface lo inet loopback
auto eno1
#real IP address
iface eno1 inet static
address 198.51.100.5/24
gateway 198.51.100.1
auto vmbr0
#private sub network
iface vmbr0 inet static
address 10.10.10.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o eno1 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o eno1 -j MASQUERADE
|
|
在某些启用了防火墙的 masquerade 配置中,出站连接可能需要 conntrack zones。否则防火墙可能阻止出站连接,因为它们会优先匹配虚拟机 bridge 的 POSTROUTING,而不是 MASQUERADE。 |
在 /etc/network/interfaces 中添加以下行可以修复此问题:
post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1
有关此问题的更多信息,请参考以下链接:
Linux Bond
Bonding(也称为 NIC teaming 或 Link Aggregation)是一种将多个 NIC 绑定为单个网络设备的技术。它可以实现不同目标,例如提升网络容错能力、提高性能,或同时实现二者。
Fibre Channel 等高速硬件及其配套交换硬件可能非常昂贵。通过链路聚合,两块 NIC 可以呈现为一个逻辑接口,从而获得双倍速度。这是 Linux 内核原生功能,并受大多数交换机支持。如果节点有多个 Ethernet 端口,可以将网络线缆连接到不同交换机,以分散故障点;当网络出现问题时,bonded 连接会故障转移到其中一条线缆。
聚合链路可以降低在线迁移延迟,并提高 Proxmox VE 集群节点之间的数据复制速度。
Bonding 有 7 种模式:
-
Round-robin (balance-rr): 按顺序从第一个可用的从属网络接口(NIC)到最后一个接口传输网络数据包。该模式提供负载均衡和容错能力。
-
Active-backup (active-backup): bond 中只有一个从属 NIC 处于活动状态。仅当活动从属接口失败时,另一个从属接口才会变为活动状态。单个逻辑 bonded 接口的 MAC 地址在外部只会出现在一个 NIC(端口)上,以避免网络交换机产生混乱。该模式提供容错能力。
-
XOR (balance-xor): 根据 [(源 MAC 地址 XOR 目标 MAC 地址) modulo 从属 NIC 数量] 传输网络数据包。该模式会为每个目标 MAC 地址选择相同的从属 NIC,提供负载均衡和容错能力。
-
Broadcast (broadcast): 在所有从属网络接口上传输网络数据包。该模式提供容错能力。
-
IEEE 802.3ad Dynamic link aggregation (802.3ad)(LACP): 创建共享相同速率和双工设置的聚合组。根据 802.3ad 规范使用活动聚合组中的所有从属网络接口。
-
Adaptive transmit load balancing (balance-tlb): Linux bonding 驱动模式,不需要网络交换机提供任何特殊支持。出站网络数据包流量会按照每个从属网络接口当前负载(相对于速率计算)进行分配。入站流量由当前指定的一个从属网络接口接收。如果该接收从属接口失败,另一个从属接口会接管故障接收从属接口的 MAC 地址。
-
Adaptive load balancing (balance-alb): 包含 balance-tlb,并为 IPV4 流量提供接收负载均衡(rlb),不需要网络交换机提供任何特殊支持。接收负载均衡通过 ARP 协商实现。bonding 驱动会拦截本地系统发出的 ARP Replies,并将源硬件地址重写为单个逻辑 bonded 接口中某个从属 NIC 的唯一硬件地址,使不同网络对端使用不同 MAC 地址发送其网络数据包流量。
如果交换机支持 LACP(IEEE 802.3ad)协议,建议使用对应的 bonding 模式(802.3ad)。否则,通常应使用 active-backup 模式。
对于集群网络(Corosync),建议配置多个网络。Corosync 不需要通过 bond 实现网络冗余,因为当某个网络不可用时,它可以自行在网络之间切换。
以下 bond 配置可用作分布式/共享存储网络。其优势是可以获得更高速度,并让网络具备容错能力。
auto lo
iface lo inet loopback
iface eno1 inet manual
iface eno2 inet manual
iface eno3 inet manual
auto bond0
iface bond0 inet static
bond-slaves eno1 eno2
address 192.168.1.2/24
bond-miimon 100
bond-mode 802.3ad
bond-xmit-hash-policy layer2+3
auto vmbr0
iface vmbr0 inet static
address 10.10.10.2/24
gateway 10.10.10.1
bridge-ports eno3
bridge-stp off
bridge-fd 0
auto lo
iface lo inet loopback
iface eno1 inet manual
iface eno2 inet manual
auto bond0
iface bond0 inet manual
bond-slaves eno1 eno2
bond-miimon 100
bond-mode 802.3ad
bond-xmit-hash-policy layer2+3
auto vmbr0
iface vmbr0 inet static
address 10.10.10.2/24
gateway 10.10.10.1
bridge-ports bond0
bridge-stp off
bridge-fd 0
VLAN 802.1Q
虚拟 LAN(VLAN)是在网络二层进行划分和隔离的广播域。因此,可以在一个物理网络中拥有多个彼此独立的网络(4096 个)。
每个 VLAN 网络由一个通常称为 tag 的数字标识。随后网络数据包会被“打标签”,用于标识其所属的虚拟网络。
客户机网络中的 VLAN
Proxmox VE 原生支持此配置。创建虚拟机时可以指定 VLAN tag。VLAN tag 是客户机网络配置的一部分。根据 bridge 配置不同,网络层支持不同模式来实现 VLAN:
-
Linux bridge 上的 VLAN awareness: 在这种情况下,每个客户机的虚拟网卡都会分配一个 VLAN tag,并由 Linux bridge 透明支持。也可以使用 Trunk 模式,但这需要在客户机内进行配置。
-
Linux bridge 上的“传统” VLAN: 与 VLAN awareness 方法不同,此方法不是透明的,并会为每个 VLAN 创建一个 VLAN 设备及其关联 bridge。也就是说,例如在 VLAN 5 上创建客户机时,会创建 eno1.5 和 vmbr0v5 两个接口,并一直保留到发生重启。
-
Open vSwitch VLAN: 此模式使用 OVS VLAN 功能。
-
客户机内配置的 VLAN: VLAN 在客户机内部分配。在这种情况下,配置完全在客户机内完成,无法从外部影响。其优势是可以在单个虚拟 NIC 上使用多个 VLAN。
主机上的 VLAN
为了允许主机与隔离网络通信,可以将 VLAN tag 应用到任意网络设备(NIC、Bond、Bridge)。一般来说,应在自身与物理 NIC 之间抽象层最少的接口上配置 VLAN。
例如,在默认配置中,如果希望将主机管理地址放在单独的 VLAN 上。
auto lo
iface lo inet loopback
iface eno1 inet manual
iface eno1.5 inet manual
auto vmbr0v5
iface vmbr0v5 inet static
address 10.10.10.2/24
gateway 10.10.10.1
bridge-ports eno1.5
bridge-stp off
bridge-fd 0
auto vmbr0
iface vmbr0 inet manual
bridge-ports eno1
bridge-stp off
bridge-fd 0
auto lo
iface lo inet loopback
iface eno1 inet manual
auto vmbr0.5
iface vmbr0.5 inet static
address 10.10.10.2/24
gateway 10.10.10.1
auto vmbr0
iface vmbr0 inet manual
bridge-ports eno1
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
下一个示例使用相同配置,但通过 bond 使该网络具备故障保护能力。
auto lo
iface lo inet loopback
iface eno1 inet manual
iface eno2 inet manual
auto bond0
iface bond0 inet manual
bond-slaves eno1 eno2
bond-miimon 100
bond-mode 802.3ad
bond-xmit-hash-policy layer2+3
iface bond0.5 inet manual
auto vmbr0v5
iface vmbr0v5 inet static
address 10.10.10.2/24
gateway 10.10.10.1
bridge-ports bond0.5
bridge-stp off
bridge-fd 0
auto vmbr0
iface vmbr0 inet manual
bridge-ports bond0
bridge-stp off
bridge-fd 0
在节点上禁用 IPv6
无论是否部署 IPv6,Proxmox VE 都能在所有环境中正常工作。建议保留所有设置的默认值。
如果仍需在节点上禁用 IPv6 支持,请创建适当的 sysctl.conf (5) 片段文件,并设置正确的 sysctls, 例如添加内容如下的 /etc/sysctl.d/disable-ipv6.conf:
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
相比在 内核命令行 中禁用 IPv6 模块加载,更推荐使用此方法。
在 Bridge 上禁用 MAC Learning
默认情况下,bridge 上会启用 MAC learning,以确保虚拟客户机及其网络获得平稳体验。
但在某些环境中,这可能并非期望行为。自 Proxmox VE 7.3 起,可以在 /etc/network/interfaces 中为 bridge 设置 bridge-disable-mac-learning 1 配置,从而禁用该 bridge 上的 MAC learning,例如:
# ...
auto vmbr0
iface vmbr0 inet static
address 10.10.10.2/24
gateway 10.10.10.1
bridge-ports ens18
bridge-stp off
bridge-fd 0
bridge-disable-mac-learning 1
启用后,Proxmox VE 会手动将虚拟机和容器中配置的 MAC 地址添加到 bridge 的 forwarding database,以确保客户机仍可使用网络,但前提是它们使用自身实际的 MAC 地址。
时间同步
Proxmox VE 集群栈本身高度依赖所有节点之间精确同步的时间。其他一些组件(如 Ceph) 也要求所有节点的本地时间保持同步,否则无法正常工作。
节点之间的时间同步可以通过“网络时间协议”(NTP)实现。从 Proxmox VE 7 开始, 默认 NTP 守护进程为 chrony,而 Proxmox VE 6 使用 systemd-timesyncd。 两者都预配置为使用一组公共服务器。
|
|
如果将系统升级到 Proxmox VE 7,建议手动安装 chrony、ntp 或 openntpd 之一。 |
使用自定义 NTP 服务器
在某些情况下,可能需要使用非默认 NTP 服务器。例如,如果 Proxmox VE 节点由于受限的 防火墙规则无法访问公网,则需要设置本地 NTP 服务器,并指示 NTP 守护进程使用它们。
对于使用 chrony 的系统:
在 /etc/chrony/chrony.conf 中指定 chrony 应使用的服务器:
server ntp1.example.com iburst server ntp2.example.com iburst server ntp3.example.com iburst
重启 chrony:
# systemctl restart chronyd
检查 journal,确认新配置的 NTP 服务器正在被使用:
# journalctl --since -1h -u chrony
... Aug 26 13:00:09 node1 systemd[1]: Started chrony, an NTP client/server. Aug 26 13:00:15 node1 chronyd[4873]: Selected source 10.0.0.1 (ntp1.example.com) Aug 26 13:00:15 node1 chronyd[4873]: System clock TAI offset set to 37 seconds ...
对于使用 systemd-timesyncd 的系统:
在 /etc/systemd/timesyncd.conf 中指定 systemd-timesyncd 应使用的服务器:
[Time] NTP=ntp1.example.com ntp2.example.com ntp3.example.com ntp4.example.com
然后重启同步服务(systemctl restart systemd-timesyncd),并通过检查 journal (journalctl --since -1h -u systemd-timesyncd)确认新配置的 NTP 服务器正在使用:
... Oct 07 14:58:36 node1 systemd[1]: Stopping Network Time Synchronization... Oct 07 14:58:36 node1 systemd[1]: Starting Network Time Synchronization... Oct 07 14:58:36 node1 systemd[1]: Started Network Time Synchronization. Oct 07 14:58:36 node1 systemd-timesyncd[13514]: Using NTP server 10.0.0.1:123 (ntp1.example.com). Oct 07 14:58:36 node1 systemd-timesyncd[13514]: interval/delta/delay/jitter/drift 64s/-0.002s/0.020s/0.000s/-31ppm ...
常用命令示例:
timedatectl status chronyc tracking systemctl status chrony
外部指标服务器
当前支持:
-
Graphite(见 https://graphiteapp.org )
-
InfluxDB(见 https://www.influxdata.com/time-series-platform/influxdb/ )
外部指标服务器定义保存在 /etc/pve/status.cfg 中,也可以通过 Web 界面编辑。
Graphite 服务器配置
默认情况下,Proxmox VE 通过 UDP 发送数据,因此 Graphite 服务器必须配置为接受 UDP 数据。在这里也可以为未使用标准 1500 MTU 的环境配置最大传输单元(MTU)。
也可以将插件配置为使用 TCP。为了避免阻塞重要的 pvestatd 统计采集守护进程,需要设置超时时间以应对网络问题。
InfluxDB 插件配置
以下是在 InfluxDB 服务器上的 InfluxDB 配置示例:
[[udp]] enabled = true bind-address = "0.0.0.0:8089" database = "proxmox" batch-size = 1000 batch-timeout = "1s"
使用该配置时,服务器会在所有 IP 地址的 8089 端口监听,并将数据写入 proxmox 数据库。
也可以将插件配置为使用 InfluxDB 2.x 的 http(s) API。InfluxDB 1.8.x 也包含与该 v2 API 向前兼容的 API endpoint。
要使用该方式,请根据配置将 influxdbproto 设置为 http 或 https。默认情况下,Proxmox VE 使用组织 proxmox 和 bucket/db proxmox(可分别通过 organization 和 bucket 配置项设置)。
由于 InfluxDB 的 v2 API 只能在认证后使用,因此必须生成一个能够写入正确 bucket 的 token 并进行设置。
在 1.8.x 的 v2 兼容 API 中,如有需要,可以使用 user:password 作为 token;由于 organization 在 InfluxDB 1.x 中没有意义,因此可以省略。
还可以通过 timeout 设置 HTTP 超时时间(默认 1s),并通过 max-body-size 设置最大批量大小(默认 25000000 字节)。后者对应 InfluxDB 中同名设置。
磁盘健康监控
虽然建议使用健壮且具备冗余能力的存储,但监控本地磁盘的健康状况仍然非常有用。
从 Proxmox VE 4.3 开始,系统会安装并依赖 smartmontools
[smartmontools homepage https://www.smartmontools.org]
软件包。这是一组用于监控和控制本地硬盘
S.M.A.R.T. 系统的工具。
可以通过执行以下命令获取磁盘状态:
# smartctl -a /dev/sdX
其中 /dev/sdX 是某块本地磁盘的路径。
如果输出显示:
SMART support is: Disabled
可以使用以下命令启用:
# smartctl -s on /dev/sdX
有关 smartctl 用法的更多信息,请参见 man smartctl。
默认情况下,smartmontools 守护进程 smartd 处于启用和运行状态,并每 30 分钟扫描 /dev/sdX 和 /dev/hdX 下的磁盘以检查错误和警告;如果检测到问题,会向 root 发送电子邮件。
有关如何配置 smartd 的更多信息,请参见 man smartd 和 man smartd.conf。
逻辑卷管理器 (LVM)
多数用户会将 Proxmox VE 直接安装到本地磁盘上。Proxmox VE 安装 CD 为本地磁盘管理提供了多种选项, 当前默认配置使用 LVM。安装程序允许你为这种配置选择一块单独的磁盘,并将该磁盘作为 卷组(Volume Group,VG)pve 的物理卷。以下输出来自一套使用小型 8GB 磁盘的测试安装:
# pvs PV VG Fmt Attr PSize PFree /dev/sda3 pve lvm2 a-- 7.87g 876.00m # vgs VG #PV #LV #SN Attr VSize VFree pve 1 3 0 wz--n- 7.87g 876.00m
安装程序会在该 VG 中分配三个逻辑卷(Logical Volumes,LV):
# lvs LV VG Attr LSize Pool Origin Data% Meta% data pve twi-a-tz-- 4.38g 0.00 0.63 root pve -wi-ao---- 1.75g swap pve -wi-ao---- 896.00m
- root
-
格式化为 ext4,并包含操作系统。
- swap
-
交换分区。
- data
-
该卷使用 LVM-thin,用于存储虚拟机镜像。LVM-thin 更适合这类用途,因为它能高效支持快照和克隆。
对于 Proxmox VE 4.1 及更早版本,安装程序会创建名为 “data” 的标准逻辑卷,并挂载到 /var/lib/vz。
从 4.2 版本开始,逻辑卷 “data” 是一个 LVM-thin 池,用于存储基于块的客户机镜像, 而 /var/lib/vz 只是根文件系统上的一个目录。
引导加载器
默认会安装两个引导加载器。第一个分区包含标准 GRUB 引导加载器。第二个分区是 EFI System Partition(ESP),用于在 EFI 系统上启动,并允许从用户空间应用 持久化固件更新。
创建卷组
假设有一块空磁盘 /dev/sdb,我们希望在其上创建名为 “vmdata” 的卷组。
|
|
请注意,以下命令会销毁 /dev/sdb 上的所有现有数据。 |
首先创建一个分区。
# sgdisk -N 1 /dev/sdb
创建一个物理卷(Physical Volume,PV),不要求确认,并使用 250K 元数据大小。
# pvcreate --metadatasize 250k -y -ff /dev/sdb1
在 /dev/sdb1 上创建名为 “vmdata” 的卷组。
# vgcreate vmdata /dev/sdb1
为 /var/lib/vz 创建额外 LV
可以通过创建新的 thin LV 轻松完成。
# lvcreate -n <Name> -V <Size[M,G,T]> <VG>/<LVThin_pool>
实际示例:
# lvcreate -n vz -V 10G pve/data
现在必须在该 LV 上创建文件系统。
# mkfs.ext4 /dev/pve/vz
最后需要将其挂载。
|
|
请确保 /var/lib/vz 为空。在默认安装中,它并不是空目录。 |
要使其始终可访问,请将以下行添加到 /etc/fstab。
# echo '/dev/pve/vz /var/lib/vz ext4 defaults 0 2' >> /etc/fstab
Linux 上的 ZFS
ZFS 是由 Sun Microsystems 设计的文件系统与逻辑卷管理器组合。从 Proxmox VE 3.4 开始,ZFS 文件系统的原生 Linux 内核移植版本作为可选文件系统引入,同时也可作为根文件系统的额外选择。无需手动编译 ZFS 模块,所有软件包均已包含。
通过使用 ZFS,可以在低预算硬件上获得丰富的企业级功能,也可以借助 SSD 缓存甚至纯 SSD 部署构建高性能系统。ZFS 可以用适度的 CPU 和内存负载以及易于管理的方式,替代成本较高的硬件 RAID 卡。
-
可通过 Proxmox VE GUI 和 CLI 轻松配置和管理。
-
可靠。
-
防止数据损坏。
-
文件系统级数据压缩。
-
快照。
-
写时复制克隆。
-
多种 RAID 级别:RAID0、RAID1、RAID10、RAIDZ-1、RAIDZ-2、RAIDZ-3、 dRAID, dRAID2, dRAID3
-
可使用 SSD 作为缓存。
-
自愈能力。
-
持续完整性检查。
-
面向大容量存储设计。
-
通过网络进行异步复制。
-
开源。
-
加密。
-
…
硬件
ZFS 对内存依赖较高,因此起步至少需要 8GB。实践中,应在硬件和预算允许的范围内尽量配置更多内存。为防止数据损坏,建议使用高质量 ECC RAM。
如果使用专用缓存盘和/或日志盘,应使用企业级 SSD。这可以显著提升整体性能。
|
|
不要在带有自身缓存管理的硬件 RAID 控制器之上使用 ZFS。ZFS 需要直接与磁盘通信。HBA 适配器,或刷入 “IT” 模式的 LSI 控制器一类设备更合适。 |
如果是在虚拟机中实验安装 Proxmox VE(嵌套虚拟化),不要为该虚拟机的磁盘使用 virtio,因为 ZFS 不支持这种磁盘。请改用 IDE 或 SCSI(也可使用 virtio SCSI 控制器类型)。
作为根文件系统安装
使用 Proxmox VE 安装程序安装时,可以为根文件系统选择 ZFS。安装时需要选择 RAID 类型:
|
RAID0
|
也称为 “striping”。此类卷的容量是所有磁盘容量之和。但 RAID0 不提供任何冗余,因此单块磁盘故障就会导致该卷不可用。 |
|
RAID1
|
也称为 “mirroring”。数据会以相同方式写入所有磁盘。此模式至少需要 2 块同等大小的磁盘,最终容量等同于单块磁盘。 |
|
RAID10
|
RAID0 与 RAID1 的组合。至少需要 4 块磁盘。 |
|
RAIDZ-1
|
RAID-5 的变体,单校验。至少需要 3 块磁盘。 |
|
RAIDZ-2
|
RAID-5 的变体,双校验。至少需要 4 块磁盘。 |
|
RAIDZ-3
|
RAID-5 的变体,三重校验。至少需要 5 块磁盘。 |
安装程序会自动对磁盘分区,创建名为 rpool 的 ZFS pool,并将根文件系统安装到 ZFS 子卷 rpool/ROOT/pve-1 上。
安装程序还会创建名为 rpool/data 的子卷用于存储虚拟机镜像。为了让 Proxmox VE 工具使用该子卷,安装程序会在 /etc/pve/storage.cfg 中创建以下配置项:
zfspool: local-zfs
pool rpool/data
sparse
content images,rootdir
安装完成后,可以使用 zpool 命令查看 ZFS pool 状态:
# zpool status
pool: rpool
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda2 ONLINE 0 0 0
sdb2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
errors: No known data errors
zfs 命令用于配置和管理 ZFS 文件系统。以下命令会列出安装后的所有文件系统:
# zfs list NAME USED AVAIL REFER MOUNTPOINT rpool 4.94G 7.68T 96K /rpool rpool/ROOT 702M 7.68T 96K /rpool/ROOT rpool/ROOT/pve-1 702M 7.68T 702M / rpool/data 96K 7.68T 96K /rpool/data rpool/swap 4.25G 7.69T 64K -
ZFS RAID 级别考量
选择 ZFS pool 布局时,需要考虑几个因素。ZFS pool 的基本构建块是虚拟设备,即 vdev。pool 中的所有 vdev 都会被均衡使用,数据会在它们之间条带化(RAID0)。有关 vdev 的更多详情,请查看 zpoolconcepts(7) manpage。
性能
每种 vdev 类型都有不同的性能行为。主要关注的两个参数是 IOPS(每秒输入/输出操作数)以及数据读写带宽。
写入数据时,mirror vdev(RAID1)在这两个参数上的表现大致类似单块磁盘。读取数据时,性能会随 mirror 中磁盘数量线性扩展。
一种常见场景是有 4 块磁盘。将其设置为 2 个 mirror vdev(RAID10)时,从 IOPS 和带宽角度看,该 pool 的写入特性相当于两块单盘。读取操作则接近 4 块单盘。
任意冗余级别的 RAIDZ 在 IOPS 方面大致类似单块磁盘,但具有较高带宽。具体带宽取决于 RAIDZ vdev 的大小和冗余级别。
dRAID pool 的性能应与等价的 RAIDZ pool 相当。
对于运行虚拟机而言,在多数情况下 IOPS 是更重要的指标。
大小、空间使用和冗余
由 mirror vdev 组成的 pool 具有最佳性能特性,但可用空间只有可用磁盘容量的 50%。如果一个 mirror vdev 由超过 2 块磁盘组成,例如 3-way mirror,则可用空间更少。每个 mirror 至少需要一块健康磁盘,pool 才能保持可用。
由 N 块磁盘组成的 RAIDZ 类型 vdev 可用空间大致为 N-P,其中 P 为 RAIDZ 级别。RAIDZ 级别表示在不丢失数据的情况下可任意故障的磁盘数量。4 块磁盘的 RAIDZ2 pool 是一个特殊场景;这种情况下通常最好使用 2 个 mirror vdev,因为可用空间相同但性能更好。
使用任意 RAIDZ 级别时,另一个重要因素是用于虚拟机磁盘的 ZVOL dataset 的行为。对于每个数据块,pool 都需要校验数据,其大小至少为 pool 的 ashift 值所定义的最小块大小。ashift 为 12 时,pool 块大小为 4k。ZVOL 的默认块大小为 8k。因此,在 RAIDZ2 中,每写入一个 8k 块,就会额外写入两个 4k 校验块,即 8k + 4k + 4k = 16k。当然这是简化说明,实际情况会因元数据、压缩等因素而略有不同,本示例未将这些因素计入。
检查 ZVOL 的以下属性时,可以观察到这种行为:
-
volsize
-
refreservation(如果 pool 未使用 thin provisioning)
-
used(如果 pool 使用 thin provisioning 且不存在快照)
# zfs get volsize,refreservation,used <pool>/vm-<vmid>-disk-X
volsize 是呈现给虚拟机的磁盘大小,而 refreservation 显示 pool 上的预留空间,其中包含校验数据预计需要的空间。如果 pool 使用 thin provisioning,则 refreservation 会设置为 0。另一种观察方式是比较虚拟机内部已用磁盘空间与 used 属性。请注意,快照会影响该值。
有几种方式可以抵消空间使用增加的问题:
-
增大 volblocksize 以改善数据与校验的比例
-
使用 mirror vdev 替代 RAIDZ
-
使用 ashift=9(块大小为 512 字节)
volblocksize 属性只能在创建 ZVOL 时设置。默认值可以在存储配置中修改。这样做时,需要对客户机进行相应调优;并且根据使用场景,写放大问题可能只是从 ZFS 层转移到了客户机内部。
创建 pool 时使用 ashift=9 可能会导致性能较差,具体取决于底层磁盘,并且之后无法更改。
Mirror vdev(RAID1、RAID10)对虚拟机工作负载更友好。除非环境有特定需求和特性,且 RAIDZ 性能特征可以接受,否则应优先使用 mirror vdev。
ZFS dRAID
在 ZFS dRAID(declustered RAID)中,热备盘会参与 RAID。其备用容量会被保留,并在某块磁盘故障时用于重建。根据配置不同,发生磁盘故障时,这可以比
RAIDZ 提供更快的重建速度。更多信息请参见官方 OpenZFS 文档。
[OpenZFS dRAID
https://openzfs.github.io/openzfs-docs/Basic%20Concepts/dRAID%20Howto.html]
|
|
dRAID 适用于一个 dRAID 中包含超过 10-15 块磁盘的场景。在大多数使用场景中,磁盘数量较少时 RAIDZ 配置通常更合适。 |
|
|
GUI 要求的磁盘数量比最低要求多一块(例如 dRAID1 需要 3 块)。它会假定同时添加一块备用磁盘。 |
-
dRAID1 或 dRAID:至少需要 2 块磁盘,可在丢失数据前容忍 1 块磁盘故障
-
dRAID2:至少需要 3 块磁盘,可在丢失数据前容忍 2 块磁盘故障
-
dRAID3:至少需要 4 块磁盘,可在丢失数据前容忍 3 块磁盘故障
更多信息可在 manual page 中找到:
# man zpoolconcepts
Bootloader
Proxmox VE 使用 proxmox-boot-tool 管理 bootloader 配置。详情请参见 Proxmox VE 主机 bootloader 章节。
ZFS 管理
本节给出一些常见任务的使用示例。ZFS 本身功能非常强大,并提供大量选项。管理 ZFS 的主要命令是 zfs 和 zpool。这两个命令都带有完善的 manual page,可以通过以下命令阅读:
# man zpool # man zfs
创建新的 zpool
创建新 pool 至少需要一块磁盘。ashift 应与底层磁盘的扇区大小(2 的 ashift 次方)相同或更大。
# zpool create -f -o ashift=12 <pool> <device>
|
|
Pool 名称必须遵循以下规则:
|
要启用压缩(参见 ZFS 中的压缩 章节):
# zfs set compression=lz4 <pool>
创建带 RAID-10 的新 pool
至少 4 块磁盘
# zpool create -f -o ashift=12 <pool> mirror <device1> <device2> mirror <device3> <device4>
创建带 RAIDZ-1 的新 pool
至少 3 块磁盘
# zpool create -f -o ashift=12 <pool> raidz1 <device1> <device2> <device3>
创建带 RAIDZ-2 的新 pool
至少 4 块磁盘
# zpool create -f -o ashift=12 <pool> raidz2 <device1> <device2> <device3> <device4>
设置 pool 前,请阅读 ZFS RAID 级别考量 章节,以粗略估算 IOPS 和带宽预期,特别是在计划使用 RAID-Z 模式时。
创建带缓存(L2ARC)的新 pool
可以使用专用设备或分区作为二级缓存以提升性能。此类缓存设备尤其有助于大部分为静态数据的随机读取工作负载。由于它作为实际存储与内存中 ARC 之间的额外缓存层,如果由于内存约束必须降低 ARC,也能提供帮助。
# zpool create -f -o ashift=12 <pool> <device> cache <cache-device>
这里仅使用了单个 <device> 和单个 <cache-device>,但也可以使用更多设备,如 创建带 RAID 的新 pool 中所示。
请注意,缓存设备不存在 mirror 或 RAID 模式,它们只是简单累加。
如果任何缓存设备在读取时产生错误,ZFS 会透明地将该请求转向底层存储层。
创建带日志(ZIL)的新 pool
可以为 ZFS Intent Log(ZIL)使用专用磁盘或分区。它主要用于提供安全的同步事务,因此常用于数据库等性能关键路径,或其他频繁发出 fsync 操作的程序。
pool 是默认的 ZIL 位置。将 ZIL I/O 负载转移到独立设备,可以在减轻主 pool 负载的同时降低事务延迟,从而提升整体性能。
对于直接作为日志设备或通过分区作为日志设备的磁盘,建议:
-
使用具备掉电保护的快速 SSD,因为这类设备的提交延迟更低。
-
为分区(或整个设备)至少使用几 GB 空间,但超过已安装内存的一半不会带来实际优势。
# zpool create -f -o ashift=12 <pool> <device> log <log-device>
上例使用了单个 <device> 和单个 <log-device>,但也可以结合其他 RAID 变体使用,如 创建带 RAID 的新 pool 章节所述。
也可以将日志设备 mirror 到多个设备。这主要用于确保单个日志设备故障时,性能不会立即下降。
如果所有日志设备均故障,ZFS 会重新使用主 pool 本身,直到日志设备被替换。
向现有 pool 添加缓存和日志
如果某个 pool 没有缓存和日志,也可以在任何时候添加二者或其中之一。
例如,假设有一块具备掉电保护的优质企业级 SSD,并希望用它提升 pool 的整体性能。
由于日志设备最大大小应约为已安装物理内存的一半,这意味着 ZIL 很可能只占用 SSD 的一小部分,剩余空间可以用作缓存。
首先需要使用 parted 或 gdisk 在 SSD 上创建两个 GPT 分区。
然后即可将它们添加到 pool:
# zpool add -f <pool> log <device-part1> cache <device-part2>
只需将 <pool>、<device-part1> 和 <device-part2> 替换为 pool 名称以及两个分区的 /dev/disk/by-id/ 路径。
也可以分别添加 ZIL 和缓存。
# zpool add <pool> log <log-device>
更换故障设备
# zpool replace -f <pool> <old-device> <new-device>
根据 Proxmox VE 的安装方式,它会通过 proxmox-boot-tool
[Systems installed with Proxmox VE 6.4 or later,
EFI systems installed with Proxmox VE 5.4 or later]
使用 systemd-boot 或 GRUB,或者使用普通 GRUB 作为 bootloader(参见
主机 Bootloader)。可以通过运行以下命令检查:
# proxmox-boot-tool status
复制分区表、重新生成 GUID 并替换 ZFS 分区的前几个步骤相同。为了让系统能够从新磁盘启动,还需要根据所使用的 bootloader 执行不同步骤。
# sgdisk <healthy bootable device> -R <new device> # sgdisk -G <new device> # zpool replace -f <pool> <old zfs partition> <new zfs partition>
|
|
使用 zpool status -v 命令监控新磁盘 resilvering 过程的进度。 |
# proxmox-boot-tool format <new disk's ESP> # proxmox-boot-tool init <new disk's ESP> [grub]
|
|
ESP 表示 EFI System Partition。从版本 5.4 起,使用 Proxmox VE 安装程序时,它会在可启动磁盘上设置为第 2 个分区。详情请参见 设置新分区以用作同步 ESP。 |
|
|
如果 proxmox-boot-tool status 表明当前磁盘使用 GRUB,请确保将 grub 作为模式传递给 proxmox-boot-tool init,尤其是在启用 Secure Boot 时。 |
# grub-install <new disk>
|
|
普通 GRUB 仅用于使用 Proxmox VE 6.3 或更早版本安装且尚未手动迁移到 proxmox-boot-tool 的系统。 |
配置电子邮件通知
ZFS 带有事件守护进程 ZED,用于监控 ZFS 内核模块生成的事件。该守护进程也可以在发生 pool 错误等 ZFS 事件时发送电子邮件。较新的 ZFS 软件包将该守护进程放在独立的 zfs-zed 软件包中,该软件包应已在 Proxmox VE 中默认安装。
可以使用喜欢的编辑器通过 /etc/zfs/zed.d/zed.rc 文件配置该守护进程。电子邮件通知所需设置为 ZED_EMAIL_ADDR,默认设置为 root。
ZED_EMAIL_ADDR="root"
请注意,Proxmox VE 会将发往 root 的邮件转发到为 root 用户配置的电子邮件地址。
限制 ZFS 内存使用
默认情况下,ZFS 使用主机内存的 50 % 作为 Adaptive Replacement Cache (ARC)。从 Proxmox VE 8.1 开始的新安装中,ARC 使用上限会设置为已安装物理内存的 10 %,最大限制为 16 GiB。该值写入 /etc/modprobe.d/zfs.conf。
为 ARC 分配足够内存对 I/O 性能至关重要,因此降低该值时应谨慎。一般经验是至少分配 2 GiB Base + 1 GiB/TiB-Storage。例如,如果 pool 有 8 TiB 可用存储空间,则应为 ARC 使用 10 GiB 内存。
ZFS 还会强制执行 64 MiB 的最小值。
可以通过直接写入 zfs_arc_max 模块参数,为当前启动周期修改 ARC 使用上限(重启会重置该更改):
echo "$[10 * 1024*1024*1024]" >/sys/module/zfs/parameters/zfs_arc_max
要*永久更改* ARC 限制,请在 /etc/modprobe.d/zfs.conf 中添加(或修改已有的)以下行:
options zfs zfs_arc_max=8589934592
此示例设置会将使用量限制为 8 GiB(8 * 230)。
|
|
如果期望的 zfs_arc_max 值小于或等于 zfs_arc_min(默认为系统内存的 1/32),则 zfs_arc_max 会被忽略,除非同时将 zfs_arc_min 设置为至多 zfs_arc_max - 1。 |
echo "$[8 * 1024*1024*1024 - 1]" >/sys/module/zfs/parameters/zfs_arc_min echo "$[8 * 1024*1024*1024]" >/sys/module/zfs/parameters/zfs_arc_max
在总内存超过 256 GiB 的系统上,此示例设置会将使用量(临时)限制为 8 GiB(8 * 230)。在这种情况下,单独设置 zfs_arc_max 不会生效。
|
|
如果根文件系统是 ZFS,每次该值变化后都必须更新 initramfs: # update-initramfs -u -k all 必须*重启*才能激活这些更改。 |
ZFS 上的 SWAP
在 zvol 上创建的 swap 空间可能会产生一些问题,例如阻塞服务器或造成高 I/O 负载,这种情况常见于开始向外部存储执行备份时。
强烈建议使用足够内存,使系统通常不会遇到低内存情况。如果需要或希望添加 swap,首选是在物理磁盘上创建分区并将其用作 swap 设备。可以在安装程序高级选项中为此预留一些空间。此外,还可以降低 “swappiness” 值。服务器上的一个较好取值是 10:
# sysctl -w vm.swappiness=10
要使 swappiness 持久化,请使用喜欢的编辑器打开 /etc/sysctl.conf 并添加以下行:
vm.swappiness = 10
| 值 | 策略 |
|---|---|
vm.swappiness = 0 |
内核只会为了避免 out of memory 情况而使用 swap |
vm.swappiness = 1 |
在不完全禁用 swap 的情况下,尽量减少 swap 使用量。 |
vm.swappiness = 10 |
当系统内存充足时,有时建议使用该值以改善性能。 |
vm.swappiness = 60 |
默认值。 |
vm.swappiness = 100 |
内核会积极使用 swap。 |
加密的 ZFS Dataset
|
|
Proxmox VE 中的原生 ZFS 加密仍处于实验阶段。已知限制和问题包括加密 dataset 的复制
[Bugzilla #2350] ,以及使用快照或 ZVOL 时的 checksum 错误。 [OpenZFS issue #11688] |
ZFS on Linux 0.8.0 版本引入了对 dataset 原生加密的支持。从较早 ZFS on Linux 版本升级后,可以按 pool 启用加密特性:
# zpool get feature@encryption tank NAME PROPERTY VALUE SOURCE tank feature@encryption disabled local # zpool set feature@encryption=enabled # zpool get feature@encryption tank NAME PROPERTY VALUE SOURCE tank feature@encryption enabled local
|
|
目前不支持使用 GRUB 从包含加密 dataset 的 pool 启动,并且对启动时自动解锁加密 dataset 仅提供有限支持。不支持加密的旧版 ZFS 将无法解密已存储数据。 |
|
|
建议在启动后手动解锁存储 dataset,或编写自定义 unit,在启动时将解锁所需 key material 传递给 zfs load-key。 |
|
|
在为生产数据启用加密前,请建立并测试备份流程。如果相关 key material/passphrase/keyfile 丢失,将无法再访问加密数据。 |
加密需要在创建 dataset/zvol 时设置,并默认由子 dataset 继承。例如,要创建加密 dataset tank/encrypted_data 并将其配置为 Proxmox VE 中的存储,请运行以下命令:
# zfs create -o encryption=on -o keyformat=passphrase tank/encrypted_data Enter passphrase: Re-enter passphrase: # pvesm add zfspool encrypted_zfs -pool tank/encrypted_data
在该存储上创建的所有客户机卷/磁盘都会使用父 dataset 的共享 key material 加密。
要实际使用该存储,需要加载关联的 key material 并挂载 dataset。可以通过以下命令一步完成:
# zfs mount -l tank/encrypted_data Enter passphrase for 'tank/encrypted_data':
也可以通过设置 keylocation 和 keyformat 属性,使用(随机)keyfile 替代交互式输入 passphrase。这既可以在创建时设置,也可以通过 zfs change-key 对现有 dataset 设置:
# dd if=/dev/urandom of=/path/to/keyfile bs=32 count=1 # zfs change-key -o keyformat=raw -o keylocation=file:///path/to/keyfile tank/encrypted_data
|
|
使用 keyfile 时,必须特别注意保护 keyfile,避免未授权访问或意外丢失。没有 keyfile,就无法访问明文数据。 |
在加密 dataset 下创建的客户机卷会相应设置其 encryptionroot 属性。每个 encryptionroot 只需加载一次 key material,其下所有加密 dataset 即可使用。
更多详情和高级用法,请参见 encryptionroot、encryption、keylocation、keyformat 和 keystatus 属性,zfs load-key、zfs unload-key、zfs change-key 命令,以及 man zfs 中的 Encryption 章节。
ZFS 中的压缩
在 dataset 上启用压缩后,ZFS 会尝试在写入所有*新*块之前压缩它们,并在读取时解压缩。已存在的数据不会被追溯压缩。
可以使用以下命令启用压缩:
# zfs set compression=<algorithm> <dataset>
建议使用 lz4 算法,因为它只会带来很小的 CPU 开销。也可以使用其他算法,例如 lzjb 和 gzip-N,其中 N 是从 1(最快)到 9(最佳压缩率)的整数。根据算法和数据可压缩性不同,启用压缩甚至可能提升 I/O 性能。
可以随时使用以下命令禁用压缩:
# zfs set compression=off <dataset>
同样,只有新块会受到该更改影响。
ZFS Special Device
自 0.8.0 版本起,ZFS 支持 special 设备。pool 中的 special 设备用于存储元数据、去重表,并可选择存储小文件块。
对于由慢速机械硬盘组成且存在大量元数据变更的 pool,special 设备可以提升速度。例如,涉及创建、更新或删除大量文件的工作负载会从 special 设备中受益。还可以配置 ZFS dataset,将整个小文件存储在 special 设备上,从而进一步提升性能。special 设备应使用快速 SSD。
|
|
special 设备的冗余级别应与 pool 保持一致,因为 special 设备是整个 pool 的故障点。 |
|
|
向 pool 添加 special 设备后无法撤销。 |
# zpool create -f -o ashift=12 <pool> mirror <device1> <device2> special mirror <device3> <device4>
# zpool add <pool> special mirror <device1> <device2>
ZFS dataset 暴露 special_small_blocks=<size> 属性。size 可以为 0,表示禁用在 special 设备上存储小文件块;也可以是 512B 到 1M 范围内的 2 的幂。设置该属性后,小于 size 的新文件块会分配到 special 设备上。
|
|
如果 special_small_blocks 的值大于或等于 dataset 的 recordsize(默认 128K),则*所有*数据都会写入 special 设备,因此请谨慎设置。 |
在 pool 上设置 special_small_blocks 属性会改变所有子 ZFS dataset 该属性的默认值(例如该 pool 中的所有容器都会选择使用小文件块)。
# zfs set special_small_blocks=4K <pool>
# zfs set special_small_blocks=4K <pool>/<filesystem>
# zfs set special_small_blocks=0 <pool>/<filesystem>
ZFS Pool 特性
ZFS 磁盘格式的变更只会在主版本变更之间进行,并通过 features 指定。所有 feature 以及通用机制都在 zpool-features(5) manpage 中有详细记录。
由于启用新 feature 可能导致旧版 ZFS 无法导入 pool,因此必须由管理员主动在 pool 上运行 zpool upgrade 完成(参见 zpool-upgrade(8) manpage)。
除非需要使用某个新 feature,否则启用它们没有额外收益。
事实上,启用新 feature 存在一些缺点:
-
如果 root on ZFS 系统仍使用 GRUB 启动,而 rpool 上激活了新 feature,由于 GRUB 中的 ZFS 实现不兼容,系统将无法启动。
-
使用仍随附旧 ZFS 模块的旧内核启动时,系统将无法导入任何已升级的 pool。
-
启动较旧的 Proxmox VE ISO 来修复无法启动的系统也同样不可行。
|
|
如果系统仍使用 GRUB 启动,*不要*升级 rpool,因为这会导致系统无法启动。这包括在 Proxmox VE 5.4 之前安装的系统,以及使用 legacy BIOS boot 启动的系统(参见 如何判断所使用的 bootloader)。 |
# zpool upgrade <pool>
BTRFS
|
|
BTRFS 集成目前在 Proxmox VE 中仍是 technology preview。 |
BTRFS 是 Linux 内核原生支持的现代写时复制文件系统,实现了快照、内置 RAID, 以及通过数据和元数据校验和进行自修复等特性。从 Proxmox VE 7.0 开始,BTRFS 作为根文件系统的可选项引入。
-
主系统设置与传统基于 ext4 的设置几乎相同
-
快照
-
文件系统级数据压缩
-
写时复制克隆
-
RAID0, RAID1 and RAID10
-
防止数据损坏
-
自修复
-
Linux 内核原生支持
-
RAID 级别 5/6 仍处于实验阶段且存在风险,请参见 BTRFS Status
作为根文件系统安装
使用 Proxmox VE 安装程序安装时,可以为根文件系统选择 BTRFS。需要在安装时选择 RAID 类型:
|
RAID0
|
也称为`‘条带化’'。此类卷的容量是所有磁盘容量之和。但 RAID0 不提供 任何冗余,因此单个驱动器故障就会使该卷不可用。 |
|
RAID1
|
也称为`‘镜像’'。数据会以相同方式写入所有磁盘。此模式至少需要 2 块相同容量的磁盘。最终容量等同于单块磁盘容量。 |
|
RAID10
|
RAID0 和 RAID1 的组合。至少需要 4 块磁盘。 |
安装程序会自动对磁盘分区,并在 /var/lib/pve/local-btrfs 创建一个额外子卷。 为了让 Proxmox VE 工具使用该子卷,安装程序会在 /etc/pve/storage.cfg 中创建 以下配置条目:
dir: local
path /var/lib/vz
content iso,vztmpl,backup
disable
btrfs: local-btrfs
path /var/lib/pve/local-btrfs
content iso,vztmpl,backup,images,rootdir
这会显式禁用默认的 local 存储,改用额外子卷上的 BTRFS 专用存储条目。
btrfs 命令用于配置和管理 BTRFS 文件系统。安装完成后,以下命令会列出所有 额外子卷:
# btrfs subvolume list / ID 256 gen 6 top level 5 path var/lib/pve/local-btrfs
BTRFS 管理
本节给出一些常见任务的使用示例。
创建 BTRFS 文件系统
创建 BTRFS 文件系统时使用 mkfs.btrfs。-d 和 -m 参数分别用于设置数据和 元数据的 profile。可选的 -L 参数可用于设置标签。
通常支持以下模式:single、raid0、raid1、raid10。
在单块磁盘 /dev/sdb 上创建标签为 My-Storage 的 BTRFS 文件系统:
# mkfs.btrfs -m single -d single -L My-Storage /dev/sdb
或者在两个分区 /dev/sdb1 和 /dev/sdc1 上创建 RAID1:
# mkfs.btrfs -m raid1 -d raid1 -L My-Storage /dev/sdb1 /dev/sdc1
挂载 BTRFS 文件系统
随后可以手动挂载新的文件系统,例如:
# mkdir /my-storage # mount /dev/sdb /my-storage
BTRFS 也可以像其他挂载点一样添加到 /etc/fstab,从而在启动时自动挂载。 建议避免使用块设备路径,而是使用 mkfs.btrfs 命令输出的 UUID 值, 尤其是在 BTRFS 设置中包含多块磁盘时。
例如:
# ... 为简洁起见,省略其他挂载点 # 强烈建议使用 mkfs.btrfs 输出中的 UUID UUID=e2c0c3ff-2114-4f54-b767-3a203e49f6f3 /my-storage btrfs defaults 0 0
|
|
如果不再持有 UUID,可以使用 blkid 工具列出块设备的所有属性。 |
之后可以通过执行以下命令触发首次挂载:
mount /my-storage
下一次重启后,系统会在启动时自动执行该挂载。
将 BTRFS 文件系统添加到 Proxmox VE
可以通过 Web 界面将现有 BTRFS 文件系统添加到 Proxmox VE,也可以使用 CLI,例如:
pvesm add btrfs my-storage --path /my-storage
创建子卷
创建子卷会将其关联到 BTRFS 文件系统中的某个路径,在该路径下它会表现为普通目录。
# btrfs subvolume create /some/path
之后 /some/path 会像普通目录一样工作。
创建子卷快照
BTRFS 实际上并不区分快照和普通子卷,因此创建快照也可以理解为创建一个子卷的 任意副本。按照约定,Proxmox VE 在为客户机磁盘或子卷创建快照时会使用只读标志, 但该标志之后也可以更改。
# btrfs subvolume snapshot -r /some/path /a/new/path
这会在 /a/new/path 创建 /some/path 上该子卷的只读“克隆”。以后对 /some/path 的任何修改都会使被修改的数据在修改前先被复制。
如果省略只读(-r)选项,则两个子卷都将可写。
启用压缩
默认情况下,BTRFS 不会压缩数据。要启用压缩,可以添加 compress 挂载选项。 注意,已经写入的数据不会在事后被压缩。
默认情况下,rootfs 会在 /etc/fstab 中按如下方式列出:
UUID=<uuid of your root file system> / btrfs defaults 0 1
可以直接在上面的 defaults 后追加 compress=zstd、compress=lzo 或 compress=zlib,如下所示:
UUID=<uuid of your root file system> / btrfs defaults,compress=zstd 0 1
该更改会在重启后生效。
Proxmox 节点管理
Proxmox VE 节点管理工具(pvenode)允许你控制节点特定的设置和资源。
目前,pvenode 可用于设置节点描述、对节点上的客户机执行各种批量操作、查看节点 任务历史,以及管理节点 SSL 证书;这些证书会通过 pveproxy 用于 API 和 Web GUI。
常用命令示例
以下命令可用于查看节点任务、唤醒集群节点或批量启动已配置自启动的客户机:
pvenode task list pvenode wakeonlan <node> pvenode startall
Wake-on-LAN
Wake-on-LAN(WoL)允许你通过发送 magic packet 来启动网络中处于睡眠状态的计算机。 至少需要有一个 NIC 支持此功能,并且需要在计算机固件(BIOS/UEFI)配置中启用相应 选项。选项名称可能从 Enable Wake-on-Lan 到 Power On By PCIE Device 不等; 如果不确定,请查阅主板厂商手册。可以运行以下命令,使用 ethtool 检查 <interface> 的 WoL 配置:
ethtool <interface> | grep Wake-on
pvenode 允许你通过 WoL 唤醒集群中处于睡眠状态的成员,使用命令:
pvenode wakeonlan <node>
这会在 UDP 端口 9 上广播 WoL magic packet,其中包含从 wakeonlan 属性获取的 <node> MAC 地址。可以使用以下命令设置节点特定的 wakeonlan 属性:
pvenode config set -wakeonlan XX:XX:XX:XX:XX:XX
发送 WoL 数据包所使用的接口由默认路由决定。可以通过以下命令设置 bind-interface 来覆盖它:
pvenode config set -wakeonlan XX:XX:XX:XX:XX:XX,bind-interface=<iface-name>
发送 WoL 数据包时使用的广播地址(默认 255.255.255.255)还可以通过以下命令 显式设置 broadcast-address 来修改:
pvenode config set -wakeonlan XX:XX:XX:XX:XX:XX,broadcast-address=<broadcast-address>
任务历史
排查服务器问题时,例如备份作业失败,查看此前运行任务的日志通常很有帮助。在 Proxmox VE 中,可以通过 pvenode task 命令访问节点的任务历史。
可以使用 list 子命令获取节点已完成任务的过滤列表。例如,要获取与虚拟机 100 相关且以错误结束的任务列表,可使用:
pvenode task list --errors --vmid 100
随后可以使用任务的 UPID 打印该任务日志:
pvenode task log UPID:pve1:00010D94:001CA6EA:6124E1B9:vzdump:100:root@pam:
批量客户机电源管理
如果有许多虚拟机/容器,可以使用 pvenode 的 startall 和 stopall 子命令对 客户机执行批量启动和停止操作。默认情况下,pvenode startall 只会启动已设置为 开机自动启动的虚拟机/容器(参见 虚拟机的自动启动和关闭);不过可以使用 --force 标志覆盖此行为。 这两个命令也都有 --vms 选项,可将停止/启动的客户机限制为指定 VMID。
例如,要启动虚拟机 100、101 和 102,无论它们是否设置了 onboot,可以使用:
pvenode startall --vms 100,101,102 --force
要停止这些客户机(以及可能正在运行的任何其他客户机),请使用命令:
pvenode stopall
|
|
stopall 命令会先尝试执行干净关机,然后等待所有客户机成功关闭,或等待可 覆盖的超时时间(默认 3 分钟)到期。到达该状态后,如果 force-stop 参数没有显式 设置为 0(false),所有仍在运行的虚拟客户机都会被强制停止。 |
首个客户机启动延迟
如果虚拟机/容器依赖启动较慢的外部资源,例如 NFS 服务器,也可以按节点设置延迟: 从 Proxmox VE 启动完成到第一个配置为自动启动的虚拟机/容器启动之间等待一段时间 (参见 虚拟机的自动启动和关闭)。
可以通过以下设置实现这一点(其中 10 表示以秒为单位的延迟):
pvenode config set --startall-onboot-delay 10
批量客户机迁移
如果升级场景要求将所有客户机从一个节点迁移到另一个节点,pvenode 也提供了用于 批量迁移的 migrateall 子命令。默认情况下,该命令会将系统上的每个客户机迁移到 目标节点;不过也可以设置为只迁移一组客户机。
例如,要将虚拟机 100、101 和 102 迁移到节点 pve2,并启用本地磁盘在线 迁移,可以运行:
pvenode migrateall pve2 --vms 100,101,102 --with-local-disks
Ballooning 的 RAM 使用率目标
自动内存分配的目标百分比默认为 80%。可以通过 设置 ballooning-target 属性按节点自定义此目标。例如,要改为以 90% 主机内存 使用率为目标:
pvenode config set --ballooning-target 90
证书管理
集群内部通信证书
每个 Proxmox VE 集群默认都会创建自己的(自签名)证书颁发机构(CA),并为每个节点生成由该 CA 签名的证书。 这些证书用于与集群的 pveproxy 服务进行加密通信,并在使用 SPICE 时用于 Shell/Console 功能。
CA 证书和密钥存储在 Proxmox Cluster File System (pmxcfs) 中。
API 和 Web GUI 证书
REST API 和 Web GUI 由运行在每个节点上的 pveproxy 服务提供。
对于 pveproxy 使用的证书,可以选择以下方式:
-
默认使用 /etc/pve/nodes/NODENAME/pve-ssl.pem 中特定于节点的证书。 该证书由集群 CA 签名,因此不会被浏览器和操作系统自动信任。
-
使用外部提供的证书(例如由商业 CA 签名的证书)。
-
使用 ACME(Let’s Encrypt)获取可信证书并自动续期;该功能也集成在 Proxmox VE API 和 Web 界面中。
对于方式 2 和 3,会使用文件 /etc/pve/local/pveproxy-ssl.pem(以及必须不带密码的 /etc/pve/local/pveproxy-ssl.key)。
|
|
请记住,/etc/pve/local 是指向 /etc/pve/nodes/NODENAME 的节点专用符号链接。 |
证书通过 Proxmox VE 节点管理命令进行管理(参见 pvenode(1) 手册页)。
|
|
不要替换或手动修改 /etc/pve/local/pve-ssl.pem 和 /etc/pve/local/pve-ssl.key 中自动生成的节点证书文件,也不要修改 /etc/pve/pve-root-ca.pem 和 /etc/pve/priv/pve-root-ca.key 中的集群 CA 文件。 |
通过 Let’s Encrypt (ACME) 获取可信证书
Proxmox VE 包含 Automatic Certificate Management Environment (ACME)协议的实现,使 Proxmox VE 管理员可以使用 Let’s Encrypt 等 ACME 提供方, 轻松设置在现代操作系统和 Web 浏览器中默认被接受并信任的 TLS 证书。
目前实现的两个 ACME 端点是 Let’s Encrypt (LE) 生产环境及其 staging 环境。 我们的 ACME 客户端支持使用内置 Web 服务器验证 http-01 挑战, 也支持通过 DNS 插件验证 dns-01 挑战;这些 DNS 插件支持 acme.sh 支持的所有 DNS API 端点。
ACME 账户
可以通过 Web 界面 Datacenter -> ACME 注册和停用 ACME 账户,也可以使用 pvenode 命令行工具。
pvenode acme account register account-name mail@example.com
|
|
由于存在 速率限制,在实验或首次使用 ACME 时应使用 LE staging。 |
ACME 插件
ACME 插件的任务是自动验证你以及由你操作的 Proxmox VE 集群确实是某个域名的所有者。 这是自动证书管理的基础构件。
ACME 协议定义了不同类型的挑战,例如 http-01:Web 服务器提供包含特定内容的文件,以证明它控制某个域名。 有时由于技术限制,或记录地址无法从公网访问,这种方式不可行。此时可以使用 dns-01 挑战。 该挑战通过在域名区域中创建特定 DNS 记录来完成。
ACME 插件配置存储在 /etc/pve/priv/acme/plugins.cfg 中。插件可供集群中的所有节点使用。
ACME HTTP 挑战插件
始终会隐式配置一个 standalone 插件,用于通过在端口 80 上启动的内置 Web 服务器验证 http-01 挑战。
|
|
名称 standalone 表示它可以自行提供验证,而不需要任何第三方服务。因此,该插件也适用于集群节点。 |
要将其用于 Let’s Encrypt ACME 的证书管理,需要满足几个前提条件。
-
必须接受 Let’s Encrypt 的 ToS 才能注册账户。
-
节点的 端口 80 需要可从互联网访问。
-
端口 80 上 不得 有其他监听程序。
-
请求的(子)域名需要解析到该节点的公网 IP。
ACME DNS API 挑战插件
在无法或不希望通过 http-01 方法进行外部访问验证的系统上,可以使用 dns-01 验证方法。 此验证方法要求 DNS 服务器允许通过 API 配置 TXT 记录。
配置用于验证的 ACME DNS API
Proxmox VE 复用为 acme.sh
[acme.sh https://github.com/acmesh-official/acme.sh]
项目开发的 DNS 插件。有关特定 API 的配置详情,请参阅其文档。
使用 DNS API 配置新插件的最简单方式是通过 Web 界面(Datacenter -> ACME)。
选择 DNS 作为挑战类型。然后可以选择 API 提供方,并输入通过其 API 访问账户所需的凭据数据。 验证延迟决定了设置 DNS 记录到提示 ACME 提供方进行验证之间的时间(秒),因为提供方通常需要一些时间在其基础设施中传播记录。
|
|
关于如何获取提供方 API 凭据的更多详细信息,请参见 acme.sh How to use DNS API wiki。 |
由于 DNS 提供方和 API 端点众多,Proxmox VE 会为部分提供方自动生成凭据表单。 对于其他提供方,会显示一个较大的文本区域,只需将所有凭据 KEY=VALUE 对复制进去。
ACME 证书自动续期
如果节点已成功配置由 ACME 提供的证书(无论通过 pvenode 还是 GUI),该证书将由 pve-daily-update.service 自动续期。目前,如果证书已经过期,或将在未来 30 天内过期,将尝试续期。
|
|
如果使用会颁发短期证书的自定义目录,建议禁用 pve-daily-update.timer 单元的随机延迟, 以避免重启后错过证书续期。 |
使用 pvenode 的 ACME 示例
示例:用于 Let’s Encrypt 证书的 pvenode 调用示例
root@proxmox:~# pvenode acme account register default mail@example.invalid Directory endpoints: 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory) 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory) 2) Custom Enter selection: 1 Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf Do you agree to the above terms? [y|N]y ... Task OK root@proxmox:~# pvenode config set --acme domains=example.invalid root@proxmox:~# pvenode acme cert order Loading ACME account details Placing ACME order ... Status is 'valid'! All domains validated! ... Downloading certificate Setting pveproxy certificate and key Restarting pveproxy Task OK
示例:设置 OVH API 以验证域名
|
|
无论使用哪种插件,账户注册步骤都相同,此处不再重复。 |
|
|
OVH_AK 和 OVH_AS 需要根据 OVH API 文档从 OVH 获取。 |
首先需要获取所有信息,以便你和 Proxmox VE 能够访问该 API。
root@proxmox:~# cat /path/to/api-token
OVH_AK=XXXXXXXXXXXXXXXX
OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
root@proxmox:~# source /path/to/api-token
root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
https://eu.api.ovh.com/1.0/auth/credential -d '{
"accessRules": [
{"method": "GET","path": "/auth/time"},
{"method": "GET","path": "/domain"},
{"method": "GET","path": "/domain/zone/*"},
{"method": "GET","path": "/domain/zone/*/record"},
{"method": "POST","path": "/domain/zone/*/record"},
{"method": "POST","path": "/domain/zone/*/refresh"},
{"method": "PUT","path": "/domain/zone/*/record/"},
{"method": "DELETE","path": "/domain/zone/*/record/*"}
]
}'
{"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
(打开验证 URL,并按照说明将 Application Key 与账户/Consumer Key 关联)
root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
现在可以设置 ACME 插件:
root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token root@proxmox:~# pvenode acme plugin config example_plugin ┌────────┬──────────────────────────────────────────┐ │ key │ value │ ╞════════╪══════════════════════════════════════════╡ │ api │ ovh │ ├────────┼──────────────────────────────────────────┤ │ data │ OVH_AK=XXXXXXXXXXXXXXXX │ │ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │ │ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │ ├────────┼──────────────────────────────────────────┤ │ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │ ├────────┼──────────────────────────────────────────┤ │ plugin │ example_plugin │ ├────────┼──────────────────────────────────────────┤ │ type │ dns │ └────────┴──────────────────────────────────────────┘
最后,可以配置要为其获取证书的域名,并为其提交证书订单:
root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin root@proxmox:~# pvenode acme cert order Loading ACME account details Placing ACME order Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222 Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333' The validation for example.proxmox.com is pending! [Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu [Wed Apr 22 09:25:30 CEST 2020] Checking authentication [Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok. [Wed Apr 22 09:25:31 CEST 2020] Adding record [Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds. Add TXT record: _acme-challenge.example.proxmox.com Triggering validation Sleeping for 5 seconds Status is 'valid'! [Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu [Wed Apr 22 09:25:48 CEST 2020] Checking authentication [Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok. Remove TXT record: _acme-challenge.example.proxmox.com All domains validated! Creating CSR Checking order status Order is ready, finalizing order valid! Downloading certificate Setting pveproxy certificate and key Restarting pveproxy Task OK
示例:从 staging 切换到常规 ACME 目录
不支持更改某个账户的 ACME 目录,但由于 Proxmox VE 支持多个账户,可以直接创建一个以生产(可信)ACME 目录作为端点的新账户。 也可以停用 staging 账户并重新创建它。
root@proxmox:~# pvenode acme account deactivate default Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4' Task OK root@proxmox:~# pvenode acme account register default example@proxmox.com Directory endpoints: 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory) 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory) 2) Custom Enter selection: 0 Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf Do you agree to the above terms? [y|N]y ... Task OK
主机引导加载器
Proxmox VE 当前会根据安装程序中选择的磁盘设置,使用两种引导加载器之一。
对于以 ZFS 作为根文件系统安装的 EFI 系统,除非启用了 Secure Boot,否则会使用 systemd-boot。所有其他部署都使用标准 GRUB 引导加载器(这通常也适用于安装在 Debian 之上的系统)。
目前在OpenEuler版本上,本工具不可用。
安装程序使用的分区方案
Proxmox VE 安装程序会在所有被选作安装目标的磁盘上创建 3 个分区。
创建的分区包括:
-
一个 1 MB 的 BIOS Boot Partition(gdisk 类型 EF02)
-
一个 512 MB 的 EFI System Partition(ESP,gdisk 类型 EF00)
-
第三个分区,占用设定的 hdsize 参数范围,或占用所选存储类型使用的剩余空间
使用 ZFS 作为根文件系统的系统,会通过存储在 512 MB EFI System Partition 上的 内核和 initrd 镜像启动。对于传统 BIOS 系统以及启用了 Secure Boot 的 EFI 系统, 会使用 GRUB;对于未启用 Secure Boot 的 EFI 系统,会使用 systemd-boot。两者 都会被安装并配置为指向 ESP。
在所有使用 GRUB 启动的系统上,BIOS 模式的 GRUB(--target i386-pc)会安装到
所有所选磁盘的 BIOS Boot Partition 上
[这些包括根文件系统位于 ext4
或 xfs 的所有安装,以及非 EFI 系统上根文件系统位于 ZFS 的安装]
。
使用 proxmox-boot-tool 同步 ESP 内容
proxmox-boot-tool 是一个用于确保 EFI System Partition 内容正确配置并保持同步的
工具。它会将特定内核版本复制到所有 ESP,并配置相应的引导加载器,使其从格式化为
vfat 的 ESP 启动。在以 ZFS 作为根文件系统的场景中,这意味着可以在根池上使用
所有可选功能,而无需受限于 GRUB 中 ZFS 实现也支持的子集,也无需创建单独的小型
boot-pool
[使用 GRUB 从 ZFS 根文件系统启动
https://openzfs.github.io/openzfs-docs/Getting%20Started/Debian/Debian%20Bookworm%20Root%20on%20ZFS.html]
.
在具备冗余的设置中,安装程序会在所有磁盘上划分 ESP。这样即使第一个启动设备故障, 或者 BIOS 只能从特定磁盘启动,系统仍能启动。
在常规运行期间,ESP 不会保持挂载状态。这样有助于在系统崩溃时避免格式化为 vfat 的 ESP 文件系统损坏,也避免在主启动设备故障时需要手动调整 /etc/fstab。
proxmox-boot-tool 处理以下任务:
-
格式化并设置新分区
-
将新的内核镜像和 initrd 镜像复制并配置到所有列出的 ESP
-
在内核升级和其他维护任务期间同步配置
-
管理要同步的内核版本列表
-
配置引导加载器以启动特定内核版本(固定)
可以运行以下命令查看当前已配置的 ESP 及其状态:
# proxmox-boot-tool status
要将某个分区格式化并初始化为同步 ESP,例如在 rpool 中更换故障 vdev 后,或将早于 同步机制的现有系统转换为使用该机制时,可以使用 proxmox-kernel-helper 提供的 proxmox-boot-tool。
|
|
format 命令会格式化 <partition>,请确保传入正确的设备/分区。 |
例如,要将空分区 /dev/sda2 格式化为 ESP,请运行:
# proxmox-boot-tool format /dev/sda2
要将位于 /dev/sda2 且未挂载的现有 ESP 纳入 Proxmox VE 的内核更新同步机制,请使用:
# proxmox-boot-tool init /dev/sda2
或:
# proxmox-boot-tool init /dev/sda2 grub
用于强制使用 GRUB 而不是 systemd-boot 初始化,例如用于支持 Secure Boot。
之后,/etc/kernel/proxmox-boot-uuids 中应包含一行新增分区的 UUID。init 命令 还会自动触发所有已配置 ESP 的刷新。
要复制并配置所有可启动内核,并保持 /etc/kernel/proxmox-boot-uuids 中列出的所有 ESP 同步,只需运行:
# proxmox-boot-tool refresh
(等同于在根文件系统为 ext4 或 xfs 的系统上运行 update-grub)。
如果更改了内核命令行,或希望同步所有内核和 initrd,则需要执行此操作。
|
|
update-initramfs 和 apt(必要时)都会自动触发刷新。 |
默认配置以下内核版本:
-
当前正在运行的内核
-
软件包更新中新安装的版本
-
已安装的最新两个内核
-
倒数第二个内核系列的最新版本(例如 5.0、5.3),如适用
-
任何手动选择的内核
如果希望将某个内核和 initrd 镜像添加到可启动内核列表,请使用 proxmox-boot-tool kernel add。
例如,运行以下命令可将 ABI 版本为 5.0.15-1-pve 的内核添加到需要保留安装并同步到 所有 ESP 的内核列表:
# proxmox-boot-tool kernel add 5.0.15-1-pve
proxmox-boot-tool kernel list 会列出当前选定用于启动的所有内核版本:
# proxmox-boot-tool kernel list Manually selected kernels: 5.0.15-1-pve Automatically selected kernels: 5.0.12-1-pve 4.15.18-18-pve
运行 proxmox-boot-tool kernel remove 可从手动选择的内核列表中移除某个内核,例如:
# proxmox-boot-tool kernel remove 5.0.15-1-pve
|
|
在按上述方式手动添加或移除内核后,需要运行 proxmox-boot-tool refresh 来更新 所有 EFI System Partition(ESP)。 |
以下命令可用于查看 ESP 同步状态、列出已选择的内核,并在更改后刷新 ESP 配置:
# proxmox-boot-tool status # proxmox-boot-tool kernel list # proxmox-boot-tool refresh
确定正在使用的引导加载器
你会看到 GRUB 的蓝色界面,或者简洁的黑白 systemd-boot 界面。
# efibootmgr -v
如果返回 EFI 变量不受支持的信息,则说明正在以 BIOS/Legacy 模式使用 GRUB。
如果输出包含类似以下内容的行,则说明正在以 UEFI 模式使用 GRUB。
Boot0005* proxmox [...] File(\EFI\proxmox\grubx64.efi)
如果输出包含类似以下内容的行,则说明正在使用 systemd-boot。
Boot0006* Linux Boot Manager [...] File(\EFI\systemd\systemd-bootx64.efi)
运行:
# proxmox-boot-tool status
可以确认是否已配置 proxmox-boot-tool,这能够较好地反映系统的启动方式。
GRUB
多年来,GRUB 一直是启动 Linux 系统的事实标准,并且文档相当完善
[GRUB Manual https://www.gnu.org/software/grub/manual/grub/grub.html]
.
Systemd-boot
systemd-boot 是轻量级 EFI 引导加载器。它会直接从安装位置所在的 EFI Service Partition(ESP)读取内核和 initrd 镜像。直接从 ESP 加载内核的主要优势在于, 无需重新实现用于访问存储的驱动程序。在 Proxmox VE 中, proxmox-boot-tool 用于保持 ESP 上的配置同步。
配置
systemd-boot 通过 EFI System Partition(ESP)根目录中的 loader/loader.conf 文件进行配置。详情请参见 loader.conf(5) 手册页。
每个引导加载器条目都会放在 loader/entries/ 目录下的独立文件中。
entry.conf 示例类似如下(/ 表示 ESP 的根目录):
title Proxmox version 5.0.15-1-pve options root=ZFS=rpool/ROOT/pve-1 boot=zfs linux /EFI/proxmox/5.0.15-1-pve/vmlinuz-5.0.15-1-pve initrd /EFI/proxmox/5.0.15-1-pve/initrd.img-5.0.15-1-pve
编辑内核命令行
可以根据所使用的引导加载器,在以下位置修改内核命令行:
内核命令行需要放在 /etc/default/grub 文件中的 GRUB_CMDLINE_LINUX_DEFAULT 变量内。运行 update-grub 会将其内容追加到 /boot/grub/grub.cfg 中所有 linux 条目。
内核命令行需要作为一行写入 /etc/kernel/cmdline。要应用更改,请运行 proxmox-boot-tool refresh,它会将该内容设置为 loader/entries/proxmox-*.conf 中所有配置文件的 option 行。
完整的内核参数列表可在以下地址找到: https://www.kernel.org/doc/html/v<YOUR-KERNEL-VERSION>/admin-guide/kernel-parameters.html. 请将 <YOUR-KERNEL-VERSION> 替换为 major.minor 版本。例如,对于基于 6.5 版本的 内核,URL 为: https://www.kernel.org/doc/html/v6.5/admin-guide/kernel-parameters.html
可以通过查看 Web 界面(Node -> Summary)或运行以下命令来查找内核版本:
# uname -r
使用输出开头的前两个数字。
为下次启动覆盖内核版本
要选择当前默认内核之外的内核,可以采用以下方式之一:
-
使用启动过程开始时显示的引导加载器菜单
-
使用 proxmox-boot-tool 将系统一次性或永久(直到重置固定设置)pin 到某个内核版本。
这有助于规避较新内核版本与硬件之间的不兼容问题。
|
|
应尽快移除此类固定设置,以便最新内核中的所有当前安全补丁也能应用到系统。 |
例如:若要永久选择版本 5.15.30-1-pve 用于启动,请运行:
# proxmox-boot-tool kernel pin 5.15.30-1-pve
|
|
固定功能适用于所有 Proxmox VE 系统,不仅限于使用 proxmox-boot-tool 同步 ESP 内容的系统。如果系统没有使用 proxmox-boot-tool 进行同步,也可以跳过最后的 proxmox-boot-tool refresh 调用。 |
也可以设置只在下一次系统启动时引导某个内核版本。例如,这可用于测试更新后的内核 是否已解决最初导致需要 pin 某个版本的问题:
# proxmox-boot-tool kernel pin 5.15.30-1-pve --next-boot
要移除任何已固定的版本配置,请使用 unpin 子命令:
# proxmox-boot-tool kernel unpin
虽然 unpin 也有 --next-boot 选项,但它用于清除通过 --next-boot 设置的固定版本。 由于该操作在启动时已经会自动发生,手动调用的实际用途很小。
设置或清除固定版本后,还需要运行 refresh 子命令来同步 ESP 上的内容和配置。
|
|
如果以交互方式调用该工具,对于由 proxmox-boot-tool 管理的系统,会提示你 自动执行此操作。 |
# proxmox-boot-tool refresh
Secure Boot
自 Proxmox VE 8.1 起,通过签名软件包以及与 proxmox-boot-tool 的集成,Secure Boot 可开箱即用。
Secure Boot 正常工作需要以下软件包。可以使用 proxmox-secure-boot-support 元软件包一次性安装它们。
-
shim-signed(由 Microsoft 签名的 shim 引导加载器)
-
shim-helpers-amd64-signed(由 Proxmox 签名的 fallback 引导加载器和 MOKManager)
-
grub-efi-amd64-signed(由 Proxmox 签名的 GRUB EFI 引导加载器)
-
proxmox-kernel-6.X.Y-Z-pve-signed(由 Proxmox 签名的内核镜像)
开箱即用的引导加载器仅支持 GRUB,因为其他引导加载器当前不符合 Secure Boot 代码签名条件。
任何新的 Proxmox VE 安装都会自动包含上述所有软件包。
关于 Secure Boot 工作方式以及如何自定义设置的更多详情,请参见 我们的 wiki。
将现有安装切换到 Secure Boot
|
|
如果操作不正确,在某些情况下这可能导致安装无法启动。重新安装主机时, 如果 Secure Boot 可用,会自动完成设置,无需额外交互。请确保你拥有可用且经过充分 测试的 Proxmox VE 主机备份! |
如有需要,可以将现有 UEFI 安装切换到 Secure Boot,而无需从头重新安装 Proxmox VE。
首先,确保整个系统均为最新状态。然后安装 proxmox-secure-boot-support。GRUB 会自动创建通过默认 shim 启动所需的 EFI 启动项。
如果使用 systemd-boot 作为引导加载器(参见 确定正在使用的引导加载器),则需要一些额外设置。 只有在 Proxmox VE 以 ZFS-on-root 方式安装时才会如此。
要检查后一种情况,请运行:
# findmnt /
如果主机确实使用 ZFS 作为根文件系统,则 FSTYPE 列应包含 zfs:
TARGET SOURCE FSTYPE OPTIONS / rpool/ROOT/pve-1 zfs rw,relatime,xattr,noacl,casesensitive
接下来,必须找到合适的潜在 ESP(EFI system partition)。可以使用如下 lsblk 命令完成:
# lsblk -o +FSTYPE
输出应类似如下:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS FSTYPE sda 8:0 0 32G 0 disk ├─sda1 8:1 0 1007K 0 part ├─sda2 8:2 0 512M 0 part vfat └─sda3 8:3 0 31.5G 0 part zfs_member sdb 8:16 0 32G 0 disk ├─sdb1 8:17 0 1007K 0 part ├─sdb2 8:18 0 512M 0 part vfat └─sdb3 8:19 0 31.5G 0 part zfs_member
在此示例中,分区 sda2 和 sdb2 是目标。可以通过它们的 512M 大小以及 FSTYPE 为 vfat 来识别;这里对应的是一个 ZFS RAID-1 安装。
必须使用 proxmox-boot-tool 正确设置这些分区,以便通过 GRUB 启动。以下命令 (以 sda2 为例)必须分别针对每个 ESP 单独运行:
# proxmox-boot-tool init /dev/sda2 grub
之后,可以运行以下命令对设置进行基本检查:
# efibootmgr -v
该列表应包含类似如下的条目:
[..] Boot0009* proxmox HD(2,GPT,..,0x800,0x100000)/File(\EFI\proxmox\shimx64.efi) [..]
|
|
旧的 systemd-boot 引导加载器会被保留,但会优先使用 GRUB。这样,如果由于 任何原因无法在 Secure Boot 模式下使用 GRUB 启动,仍可在关闭 Secure Boot 后使用 systemd-boot 启动系统。 |
现在可以重启主机,并在 UEFI 固件设置工具中启用 Secure Boot。
重启后,UEFI 固件启动菜单中应可选择一个名为 proxmox 的新条目,它会使用预签名的 EFI shim 启动。
如果由于任何原因在 UEFI 启动菜单中找不到 proxmox 条目,可以尝试手动添加 (如果固件支持),将文件 \EFI\proxmox\shimx64.efi 添加为自定义启动项。
|
|
已知某些 UEFI 固件会在重启时丢弃 proxmox 启动选项。如果 proxmox 启动项 指向某个磁盘上的 GRUB 安装,但该磁盘本身不是启动选项,就可能发生这种情况。如果可行, 请尝试在 UEFI 固件设置工具中将该磁盘添加为启动选项,然后再次运行 proxmox-boot-tool。 |
|
|
如需注册自定义密钥,请参见配套的 Secure Boot wiki 页面。 |
在 Secure Boot 下使用 DKMS/第三方模块
在启用了 Secure Boot 的系统上,内核会拒绝加载未由受信任密钥签名的模块。内核软件包 随附的默认模块集合使用嵌入在内核镜像中的临时密钥签名,该密钥受该特定版本内核镜像信任。
要加载其他模块,例如使用 DKMS 构建或手动构建的模块,需要用 Secure Boot 栈信任的 密钥对其签名。最简单的方式是使用 mokutil 将这些密钥注册为 Machine Owner Key (MOK)。
dkms 工具会自动在 /var/lib/dkms/mok.key 和 /var/lib/dkms/mok.pub 中生成密钥对和 证书,并用其为它构建和安装的内核模块签名。
可以使用以下命令查看证书内容:
# openssl x509 -in /var/lib/dkms/mok.pub -noout -text
并使用以下命令将其注册到系统中:
# mokutil --import /var/lib/dkms/mok.pub input password: input password again:
mokutil 命令会要求输入两次(临时)密码,该密码需要在流程的下一步中再输入一次。 重启系统后,应会自动启动进入 MOKManager EFI 二进制程序,它允许你验证密钥/证书, 并使用通过 mokutil 开始注册时选择的密码确认注册。之后,内核应允许加载使用 DKMS 构建的模块(这些模块使用已注册的 MOK 签名)。如有需要,MOK 也可用于签名自定义 EFI 二进制文件和内核镜像。
同一流程也可用于不由 DKMS 管理的自定义/第三方模块,但在这种情况下,需要手动完成 密钥/证书生成和签名步骤。
Kernel Samepage Merging (KSM)
Kernel Samepage Merging(KSM)是 Linux 内核提供的一项可选内存去重功能, 在 Proxmox VE 中默认启用。KSM 的工作方式是扫描一段物理内存页,查找内容相同的页面, 并识别映射到这些页面的虚拟页。如果发现相同页面,对应的虚拟页会被重新映射, 使它们都指向同一个物理页,并释放旧页面。虚拟页会被标记为“写时复制”, 因此对它们的任何写入都会写入新的内存区域,从而保持共享物理页不变。









