构建内容
一台裸机服务器运行 Proxmox VE 作为其自身的管理程序,NVMe 驱动器上配置 ZFS 镜像,桥接网络为虚拟机提供真实地址,并启用和验证嵌套虚拟化——这意味着该机器上的虚拟机可以再运行虚拟机。
嵌套是在裸机上而非虚拟实例上执行此操作的原因。你不能在别人的管理程序内以可预测的结果进行嵌套,而在 BM-E 上,没有我们的管理程序挡路:你拥有 IPMI、电源按钮和主板。运行什么由你决定。
开始之前
- 一台 BM-E:三十二个 Zen 4 核心、256 GB ECC 内存、四块 NVMe 驱动器、八个 IPv4 地址。IPMI 可通过 VPN 访问,支持团队在机器交付时设置。
- 订购时选择 Proxmox VE 8,或通过面板上传自定义 ISO。两种方式最终都会进入相同的安装程序。
- 预留半小时,期间无人需要使用机器,因为第一步会多次重启。
1. 安装
通过管理 VPN 连接到控制台,挂载 ISO 并启动。在磁盘选择界面选择全部四块 NVMe 设备,选择 zfs (RAID10),并打开高级选项:
- 将
ashift设为 12,这是 4K 扇区的正确值,之后无法更改,除非重建存储池。 - 将
compress设为 lz4。它只消耗一小部分核心,通常能节省三分之一的空间。 - 减少
hdsize以留出空间给虚拟机存储,除非你希望根存储池独占所有空间。
根据面板信息设置管理地址和网关,并使用机器的完全限定域名作为主机名。两次重启后,你将看到登录提示符和 8006 端口的 Web 界面。
2. 软件源和软件包
企业软件源在没有订阅时会失败,并会在每个 apt update 中产生杂乱信息,直到你处理它:
rm -f /etc/apt/sources.list.d/pve-enterprise.sources
echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-community.list
apt update && apt full-upgrade -y
apt install -y ifupdown2 chrony zfsutils-linux
reboot3. 为 ZFS 分配内存
否则 ARC 会增长到内存的一半,而在一个专门运行虚拟机的机器上,这些内存有更好的用途:
echo "options zfs zfs_arc_max=34359738368" > /etc/modprobe.d/zfs.conf
update-initramfs -u -k all在 256 GB 的机器上,32 GB 的 ARC 既能提供充足的缓存,又不会让虚拟机内存不足。重启以生效,或者如果无法重启,使用 echo 将其即时应用于 /sys/module/zfs/parameters/zfs_arc_max。
4. 网络
八个地址不多,因此虚拟机位于私有桥上,只有需要公共地址的虚拟机才获得路由到它们的地址。编辑 /etc/network/interfaces:
auto lo
iface lo inet loopback
auto enp1s0f0
iface enp1s0f0 inet static
address <public address>/24
gateway <gateway>
auto vmbr0
iface vmbr0 inet static
address 10.20.0.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up iptables -t nat -A POSTROUTING -s 10.20.0.0/24 -o enp1s0f0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s 10.20.0.0/24 -o enp1s0f0 -j MASQUERADE
iface vmbr0 inet6 static
address 2001:db8:1a2b:20::1/64IPv6 不需要地址转换,因为路由到机器的 /64 是真正的路由:将地址分配给桥上的虚拟机,它们就能直接访问互联网。两个协议族之间的这种不对称并不优雅,但这是我们所处地址空间的真实形态。
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/80-pve.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.d/80-pve.conf
ifreload -a5. 嵌套虚拟化
cat /sys/module/kvm_amd/parameters/nested在当前内核上,这应该已经输出 1。如果输出 0:
echo "options kvm-amd nested=1" > /etc/modprobe.d/kvm-amd.conf
update-initramfs -u && reboot嵌套还要求虚拟机看到的 CPU 具备该特性,这意味着处理器类型必须是 host。否则会呈现一个屏蔽了虚拟化扩展的合成 CPU 模型,内部管理程序会拒绝启动,并给出一个未提及此问题的错误。
6. 虚拟机示例
cd /var/lib/vz/template/iso
wget https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2
qm create 100 --name inner --memory 16384 --cores 8 --cpu host \
--net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single --ostype l26 \
--agent enabled=1 --machine q35 --bios ovmf
qm set 100 --efidisk0 local-zfs:1
qm importdisk 100 debian-13-genericcloud-amd64.qcow2 local-zfs
qm set 100 --scsi0 local-zfs:vm-100-disk-1,discard=on,ssd=1
qm set 100 --boot order=scsi0
qm set 100 --ipconfig0 ip=10.20.0.100/24,gw=10.20.0.1
qm set 100 --sshkeys /root/.ssh/authorized_keys
qm set 100 --ciuser admin
qm start 100discard=on 搭配 ssd=1 意味着虚拟机内的删除操作会将空间返还给存储池,而不是积累成你无法追踪的已用空间。
7. 防火墙
8006 端口的 Web 界面不应公开访问。在数据中心层面将其限制为你管理的地址——WireGuard 指南中的隧道端点是最佳选择:
cat > /etc/pve/firewall/cluster.fw <<EOF
[OPTIONS]
enable: 1
policy_in: DROP
[RULES]
IN SSH(ACCEPT) -source 10.7.0.0/24
IN ACCEPT -source 10.7.0.0/24 -dport 8006 -proto tcp
IN ACCEPT -p icmp
EOF
systemctl restart pve-firewall验证
先验证宿主机:
pveversion -v | head -3
zpool status rpool
zpool list -o name,size,alloc,free,frag,cap
arc_summary | head -12存储池报告 ONLINE,两个镜像对,ARC 目标是你设置的 32 GB,而不是机器的内存一半。
现在验证本次构建的真正重点。登录虚拟机并检查分配给它的处理器:
ssh [email protected]
lscpu | grep -E "Model name|Virtuali"
grep -c svm /proc/cpuinfo型号名称应为真实的 EPYC 型号,虚拟化行应显示 AMD-V。第三条命令返回零表示处理器类型不是 host,以下所有操作都将失败。
然后在虚拟机中运行一台机器:
apt install -y qemu-system-x86 qemu-utils cpu-checker
kvm-ok
wget https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/alpine-virt-3.22.0-x86_64.iso
qemu-system-x86_64 -enable-kvm -m 2048 -cdrom alpine-virt-3.22.0-x86_64.iso -nographickvm-ok 显示加速可用,随后 Alpine 启动在几秒钟内到达登录提示符而不是缓慢爬行,这即是验证。没有嵌套,同样的命令要么直接拒绝,要么以约二十分之一的速度进行软件模拟,这是无法忽视的。
最后,确认接口从外部关闭:
curl -m5 -k https://<public address>:8006/ ; echo "exit $?"连接超时是正确的答案。
后续
ZFS 上的快照在产生差异之前是免费的,因此每晚的 zfs-auto-snapshot 计划几乎不花费任何成本,并且比任何备份策略都拯救了更多的机器。裸机重建当天即可完成,但重建返回的是一台空机器,这与恢复你的机器是两回事。