引子
从最初在 ThinkPad T480 上安装 Proxmox VE,到后来陆续折腾 Debian、Arch Linux、FreeBSD、Windows XP、Windows 98、OpenWrt、飞牛 fnOS 等系统,这台笔记本已经陪我完成了不少虚拟化实验。
这段时间,我们研究了虚拟磁盘、网络桥接、NAT、硬件直通、SPICE、QEMU Guest Agent,也解决了不少旧操作系统在现代虚拟化环境下遇到的兼容性问题。
现在,由于 T480 准备挪作其他用途,这套 PVE 实验环境也将暂时告一段落。
但这些虚拟机和配置,我并不想直接删除。
毕竟,安装系统本身并不困难,真正花时间的是后续的配置、测试和问题排查。尤其是 Windows 98、Windows XP 这样的老系统,重新把驱动、显示、音频等配置调试到满意状态,还是很费工夫的。
所以,在结束这一阶段的实验之前,我决定做一次完整备份。
目标很简单:
无论以后继续使用 T480,还是换一台全新的 PVE 主机,都能尽可能恢复现在这套实验环境。
本文记录这次实际的备份过程,也简单整理将来如何恢复。
一、先明确:PVE 究竟需要备份什么?
很多人第一次使用 PVE 的备份功能,可能会以为只要把所有虚拟机备份下来,就完成了整个宿主机的备份。
实际上并不是。
PVE 的vzdump工具主要负责备份虚拟机或 LXC 容器,它并不会顺带备份宿主机自身的全部配置,也不会把上传的 ISO、自己编写的脚本等文件统统保存下来。
因此,我把本次备份分为四类:
| 备份内容 | 包含什么 | 备份方式 |
|---|---|---|
| 虚拟机 | 系统、虚拟磁盘、VM 配置 | vzdump |
| 宿主机配置 | PVE、网络、存储、NAT、服务配置 | tar + 配置数据库 |
| 自定义数据 | /root下的脚本、ROM、文件等 | rsync |
| 安装镜像 | 上传到 PVE 的 ISO、IMG 文件 | rsync |
最后,再把全部备份复制到另一台飞牛 NAS,保存第二份副本。
我的 PVE 环境
本次备份的主机是 ThinkPad T480:
| 项目 | 配置 |
|---|---|
| 主机 | ThinkPad T480 |
| 内存 | 16GB |
| 系统盘 | 256GB NVMe SSD |
| 数据盘 | 1TB HDD |
| PVE | 9.2.11 |
| 主机名 | pve-t480 |
| 网络 | Wi-Fi 上联 + vmbr0 NAT |
| 备份介质 | 东芝 1TB USB 移动硬盘 |
| 第二份备份 | 蜜獾超存飞牛 fnOS NAS |
其中,PVE 的数据主要分布在local-lvm和hdd-data上。
为了让虚拟机在 Wi-Fi 上联网,我还单独配置了vmbr0、NAT 和 dnsmasq。这些配置也必须纳入备份,否则将来恢复虚拟机之后,还需要重新搭建网络。
二、准备 1TB USB 移动硬盘
1. 格式化为 ext4
这次我直接使用一块东芝 1TB USB 移动硬盘作为备份介质。
由于 PVE 和飞牛 NAS 都基于 Linux,我选择 ext4 文件系统。
ext4 的好处是原生支持 Linux 文件权限、符号链接、大文件等特性,不需要考虑 FAT32 的单文件 4GB 限制。
格式化是在另一台 Ubuntu Desktop 电脑上完成的。
打开 GNOME Disks(磁盘)工具,选中对应的 USB 移动硬盘,依次操作:
格式化磁盘,分区表选择 GPT。
创建一个占用整个磁盘的分区。
文件系统选择 ext4。
卷标设置为
PVE_BACKUP。
这里需要格外注意:格式化会删除原有数据,一定要根据容量和设备型号确认操作对象。
完成之后,再把移动硬盘连接到 PVE T480。
2. 在 PVE 中挂载硬盘
先查看磁盘:
lsblk -f我的 USB 分区对应/dev/sdc1,UUID 为:
c9d8e233-25e8-4dff-b1fe-432d81ad03e0创建挂载目录:
mkdir -p /mnt/pve-backup使用 UUID 挂载:
mount UUID=c9d8e233-25e8-4dff-b1fe-432d81ad03e0 \ /mnt/pve-backup这里推荐使用 UUID,而不是固定写/dev/sdc1。
因为 USB 移动硬盘重新插拔之后,Linux 分配的设备名可能发生变化,例如变成/dev/sdd1,但文件系统 UUID 通常不会改变。
检查挂载情况:
df -h /mnt/pve-backup findmnt /mnt/pve-backup最初正常识别时,文件系统容量约为 916GiB。
考虑到这块硬盘后面还要拔下来连接飞牛,我没有急着设置/etc/fstab自动挂载,而是选择手动挂载、备份完成后手动卸载。
3. 在 PVE 中添加备份存储
进入 PVE Web 界面:
Datacenter → Storage → Add → Directory
填写:
| 参数 | 设置 |
|---|---|
| ID | backup-usb |
| Directory | /mnt/pve-backup |
| Content | Backup |
| Nodes | pve-t480 |
| Shared | 不勾选 |
需要注意,PVE 9.2 的界面中,备份文件类型显示为Backup,而不是某些旧教程所说的VZDump backup file。
创建后,我又执行:
pvesm set backup-usb --is_mountpoint 1这项配置非常重要。
它告诉 PVE:这个目录对应外部挂载的存储设备。如果目录没有实际挂载,就应该把该存储视为不可用。
否则,假如 USB 硬盘没有插好,PVE 可能误将备份写入系统盘上的同名目录,甚至把系统盘写满。
最终storage.cfg中新增了:
dir: backup-usb path /mnt/pve-backup content backup is_mountpoint 1 nodes pve-t480 prune-backups keep-all=1 shared 0使用下面的命令检查:
pvesm status确认backup-usb正常显示后,就可以准备备份了。
三、中间遇到一次 USB I/O 错误
这次备份并不是一开始就很顺利。
虽然移动硬盘在 Ubuntu 上格式化成功,也能正常读写,但连接到 T480 后,PVE 在创建备份目录时却出现错误:
failed to create content directory '/mnt/pve-backup/dump' Input/output error (500)最初以为是 ext4 文件系统出了问题。
进一步查看:
dmesg -T | grep -Ei \ 'sdc|ext4|usb|I/O error|shutdown' | tail -n 80发现了关键日志:
usb 2-2: USB disconnect, device number 3 I/O error, dev sdc EXT4-fs (sdc1): shut down requested (2) Aborting journal on device sdc1-8.原来,移动硬盘在挂载成功之后,USB 连接突然中断,导致正在使用的 ext4 文件系统无法继续正常读写。
更容易让人困惑的是,部分命令仍然显示文件系统处于挂载状态,但已经无法创建文件。
后来我把移动硬盘重新插拔,再次挂载后恢复正常。
这次问题提醒了我两点:
第一,mount成功,并不代表后续 I/O 一定正常。
第二,遇到 USB 存储设备 I/O 错误,应该优先查看内核日志,而不是急着重新格式化。
这里也需要强调,重新插拔能够恢复,并不等于已经证明硬盘、线缆和供电完全没有问题。如果故障反复发生,应先排查硬件;之前发生过文件系统异常时,也应在卸载状态下使用e2fsck检查。
后续正式备份没有再遇到同样的问题。
四、使用 vzdump 一次备份所有虚拟机
PVE 自带的vzdump已经能够完成常规的虚拟机备份,不需要额外安装软件。
这次我的目标是做一次完整归档,而不是每天定时备份,所以采用命令行操作。
1. 先正常关闭虚拟机
虽然vzdump支持在线备份,但考虑到我这里有 Windows XP、Windows 98 等旧系统,我还是更倾向于先正常关闭虚拟机。
这样可以减少文件系统和应用程序状态不一致的风险。
之后执行:
vzdump --all 1 \ --storage backup-usb \ --mode stop \ --compress zstd几个参数比较容易理解:
--all 1:备份当前节点上的全部 VM 和 LXC 容器。--storage backup-usb:把备份保存到 USB 硬盘。--mode stop:使用停止模式进行备份。--compress zstd:使用 ZSTD 压缩算法。
如果需要备份正在提供服务、不能长时间停止的虚拟机,也可以研究snapshot模式和 Guest Agent 的一致性保障。
不过,这次用于封存实验环境,采用停止模式已经足够。
2. 实际备份结果
备份完成后执行:
pvesm list backup-usb --content backup这次一共生成了 10 个虚拟机备份:
| VMID | 备份文件大小(约) |
|---|---|
| 110 | 1.8GB |
| 111 | 2.7GB |
| 112 | 4.9GB |
| 120 | 3.4GB |
| 130 | 14MB |
| 150 | 21GB |
| 152 | 920MB |
| 153 | 292MB |
| 160 | 11GB |
| 170 | 2.5GB |
总计:
du -sh /mnt/pve-backup/dump/输出:
48G /mnt/pve-backup/dump/也就是说,虽然这些虚拟机的虚拟磁盘总容量远大于 48GB,但实际经过稀疏数据处理和 ZSTD 压缩后,最终备份文件只有约 48GB。
对于一块 1TB 的移动硬盘而言,空间相当充裕。
3. 为什么 OpenWrt 只有 13MB?
其中最有意思的是 VM 130,也就是 OpenWrt。
它的备份文件只有约 13MB。
查看日志:
cat /mnt/pve-backup/dump/vzdump-qemu-130-*.log可以看到:
VM Name: OpenWRT25.12.6 include disk 'sata0' 'local-lvm:vm-130-disk-1' include disk 'efidisk0' 'local-lvm:vm-130-disk-0' 4M backup is sparse: 93.35 MiB (74%) total zero data archive file size: 13MB Finished Backup of VM 130它实际读取的数据约为 124.5MiB,其中有约 74% 是零数据,再经过压缩,最终只剩下 13MB。
所以备份文件大小不能直接与虚拟磁盘容量比较。
不过,文件小也不意味着一定备份完整。真正需要检查的是备份日志是否包含预期磁盘,以及最后有没有成功完成。
4. vzdump 不会保存所有东西
这里有几个重要限制。
首先,vzdump 备份的是虚拟机当前的磁盘状态,并不包含历史 VM 快照。
例如 OpenWrt 的日志中明确显示:
snapshots found (not included into backup)这意味着将来恢复 OpenWrt,可以恢复备份时的系统状态,却无法恢复原来 PVE 中保存的历史快照。
其次,未被纳入备份的磁盘、通过物理设备直通方式访问的外部数据盘,也需要单独考虑。
另外,ISO 安装镜像、宿主机配置和/root中的文件,都不属于普通 VM 备份的内容。
这些就是下面要补充备份的部分。
五、备份 PVE 宿主机配置
对于我这台 T480,仅仅恢复虚拟机还不够。
因为宿主机上还配置了:
vmbr0NAT 网络。dnsmasq DHCP 和 DNS。
Wi-Fi 上联网卡配置。
本地存储与挂载。
自定义 systemd 服务和脚本。
PVE 的虚拟机定义、存储配置及用户权限等。
尤其是网络部分,重新安装系统以后,不一定能自动恢复原来的行为。
1. 最重要的是/etc/pve
PVE 的大量核心配置保存在:
/etc/pve/例如:
/etc/pve/storage.cfg /etc/pve/nodes/pve-t480/qemu-server/ /etc/pve/firewall/ /etc/pve/user.cfg值得注意的是,/etc/pve并不是普通目录,而是由 PVE 的集群文件系统pmxcfs提供。
它的底层数据库通常保存在:
/var/lib/pve-cluster/config.db因此,我决定同时保存两种形式:
/etc/pve:便于直接查看、参考和恢复具体配置文件。config.db:作为宿主机核心配置数据库的恢复副本。
数据库不能简单地当成普通文件,在运行中随意复制或覆盖。备份时可以使用 SQLite 的在线备份功能;将来恢复数据库,则需要按照 PVE 的恢复步骤停用相关服务。
2. 使用脚本归档宿主机配置
为了以后还能重复使用,我创建了:
/root/backup-pve-host.sh脚本主要执行以下工作:
#!/bin/bash set -euo pipefail umask 077 MNT="/mnt/pve-backup" EXPECTED_UUID="c9d8e233-25e8-4dff-b1fe-432d81ad03e0" DEST="$MNT/host-config/$(date +%Y%m%d-%H%M%S)" # Verify the external backup disk ACTUAL_UUID=$(findmnt -n -o UUID -M "$MNT" || true) [ "$ACTUAL_UUID" = "$EXPECTED_UUID" ] || { echo "Wrong backup disk or disk not mounted" exit 1 } mkdir -p "$DEST" # Important configuration paths FILES=( etc/pve etc/network etc/hostname etc/hosts etc/fstab etc/resolv.conf etc/apt etc/dnsmasq.conf etc/dnsmasq.d etc/nftables.conf etc/sysctl.conf etc/sysctl.d etc/systemd/system etc/ssh etc/wpa_supplicant etc/default etc/kernel etc/initramfs-tools etc/modules-load.d etc/modprobe.d etc/udev/rules.d etc/lvm etc/crontab etc/cron.d var/spool/cron/crontabs usr/local/bin usr/local/sbin ) EXISTING=() for f in "${FILES[@]}"; do if [ -e "/$f" ] || [ -L "/$f" ]; then EXISTING+=("$f") fi done tar --acls --xattrs -czpf \ "$DEST/host-files.tar.gz" \ -C / "${EXISTING[@]}" # Consistent copy of PVE configuration database sqlite3 -readonly /var/lib/pve-cluster/config.db \ ".backup '$DEST/config.db'" sqlite3 "$DEST/config.db" \ "PRAGMA integrity_check;" > "$DEST/db-check.txt" grep -qx ok "$DEST/db-check.txt" # Record system state pveversion -v > "$DEST/pve-version.txt" qm list > "$DEST/vm-list.txt" pct list > "$DEST/ct-list.txt" pvesm status > "$DEST/storage.txt" lsblk -f > "$DEST/disks.txt" blkid > "$DEST/blkid.txt" ip -br addr > "$DEST/network.txt" ip route > "$DEST/routes.txt" ip rule > "$DEST/ip-rules.txt" dpkg-query -W > "$DEST/packages.txt" nft list ruleset > "$DEST/nft-rules.txt" 2>/dev/null || true iptables-save > "$DEST/iptables-rules.txt" 2>/dev/null || true # Verify archive and create checksums tar -tzf "$DEST/host-files.tar.gz" >/dev/null ( cd "$DEST" find . -maxdepth 1 -type f ! -name SHA256SUMS -print0 \ | sort -z \ | xargs -0 -r sha256sum > SHA256SUMS sha256sum -c SHA256SUMS ) sync echo "Backup completed: $DEST"使用前需要安装sqlite3,并将脚本中的 UUID 换成自己的备份设备 UUID。
apt install sqlite3 chmod 700 /root/backup-pve-host.sh /root/backup-pve-host.sh执行完成后,会产生一份带时间戳的目录。
里面既有配置文件归档,也有数据库和系统状态记录。
这种方式比单纯复制/etc/pve更全面,而且将来可以通过软件包列表、网络配置、磁盘布局等信息辅助重建系统。
这里需要说明:这仍然是重要配置归档,并不等于完整克隆宿主机系统盘。个别自行安装的软件,如果把数据放在非常规目录,还需要自行增加备份路径。
六、补充备份/root中的自定义文件
我在/root目录下还保存了一些实验时使用过的文件:
150.conf.before-igd backup-pve-host.sh bios.bin openwrt/ seabios-qemu.zip Universal_noGOP_igd.rom有的是虚拟机配置备份,有的是 BIOS、ROM 或者用于实验的辅助文件。
这些文件不一定容易重新找到,所以也准备全部保留。
这里我没有继续打包,而是直接使用rsync:
mkdir -p /mnt/pve-backup/root chmod 700 /mnt/pve-backup/root rsync -aHAXvh --numeric-ids \ --info=progress2 \ /root/ \ /mnt/pve-backup/root/末尾的/root/非常重要,表示复制目录内部的内容。
rsync会同时处理隐藏文件,例如.ssh、.bashrc等,并尽量保留属主、权限、ACL、扩展属性和硬链接。
相比重新打包,我觉得直接保留原始目录更方便将来查找文件。
但/root目录可能包含 SSH 私钥等敏感信息,不适合随意上传到公共网盘或开放共享目录。
七、ISO 不打包,直接复制
除了虚拟机和宿主机配置,PVE 中还有一批 ISO 安装镜像。
原来的存储配置为:
dir: local path /var/lib/vz content backup,iso,import,vztmpl lvmthin: local-lvm thinpool data vgname pve content images,rootdir dir: hdd-data path /mnt/pve/hdd-data content iso,backup,images,rootdir,snippets,vztmpl is_mountpoint 1 nodes pve-t480通过以下命令查看:
pvesm list local --content iso pvesm list hdd-data --content iso确认这次上传的 ISO 主要都在hdd-data上,包括:
Windows XP、Windows 11。
Debian、Arch Linux、Ubuntu、Kubuntu、Lubuntu、Xubuntu。
Linux Mint、FreeBSD。
fnOS 不同版本的安装镜像。
VirtIO、SPICE、AC97 等驱动镜像。
OpenCore、Windows 98 显示驱动等辅助镜像。
这些文件累计也有几十 GB。
最初考虑使用tar.gz统一压缩,后来觉得完全没必要。
因为 ISO 本身通常已经包含大量压缩内容,继续压缩的收益有限,而且以后需要单独使用一个 ISO 时,还要先解压。
所以我直接执行:
mkdir -p /mnt/pve-backup/iso rsync -avh --info=progress2 \ /mnt/pve/hdd-data/template/iso/ \ /mnt/pve-backup/iso/这样每个 ISO 都以原始文件形式保存。
下次再次执行时,rsync还能跳过没有变化的文件,避免重复复制。
至于 PVE Storage 里的Snippets和vztmpl,前者通常用于 Cloud-Init 自定义配置或虚拟机 Hookscript,后者主要存放 LXC 容器模板。
我的实验环境没有实际使用这些资源,因此这次没有额外备份。其他读者如果使用过,应当检查对应目录,不要因为 Storage 启用了内容类型就误以为文件已包含在 VM 备份中。
八、检查备份是否完整
完成以上操作之后,移动硬盘上的主要目录大致如下:
PVE_BACKUP/ ├── dump/ │ ├── vzdump-qemu-110-....vma.zst │ ├── vzdump-qemu-111-....vma.zst │ ├── ... │ └── vzdump-qemu-170-....vma.zst │ ├── host-config/ │ └── 20261025-xxxxxx/ │ ├── host-files.tar.gz │ ├── config.db │ ├── pve-version.txt │ ├── vm-list.txt │ ├── storage.txt │ └── ... │ ├── root/ │ ├── backup-pve-host.sh │ ├── bios.bin │ ├── openwrt/ │ └── ... │ └── iso/ ├── archlinux-....iso ├── debian-....iso ├── Windows_XP_....iso └── ...其中最关键的是dump和host-config。
我先通过下面的命令检查文件:
pvesm list backup-usb --content backup du -sh /mnt/pve-backup/* df -h /mnt/pve-backup还可以查看各个虚拟机备份任务的日志:
grep -H 'Finished Backup' \ /mnt/pve-backup/dump/vzdump-qemu-*.log确认全部 VM 都有成功完成的记录,也没有遗漏计划备份的磁盘。
对于复制的 ISO,可以使用:
rsync -avhc --dry-run --itemize-changes \ /mnt/pve/hdd-data/template/iso/ \ /mnt/pve-backup/iso/这里的-c会对文件内容计算校验和。数据量比较大时需要一定时间,但比只比较文件大小和修改时间更可靠。
需要强调的是:备份文件存在、大小正常、校验通过,是必要的检查,但还不能百分之百证明虚拟机可以正常恢复。
最可靠的方法仍然是在条件允许时,选择一台虚拟机实际执行恢复测试。
九、再复制一份到飞牛 NAS
这次我没有搭建 Proxmox Backup Server(PBS)。
PBS 很适合长期运行的虚拟化环境,支持去重、增量传输等功能。如果需要频繁备份大量虚拟机,确实值得研究。
但对我当前的需求来说,一次性归档几十 GB 的 VM,加上 ISO 和配置文件,使用 USB 移动硬盘已经足够。
而且接下来 T480 还要挪作其他用途,没必要专门部署一套新的备份服务。
所以,我选择把整个移动硬盘上的备份再复制一份到蜜獾超存飞牛 NAS。
1. 从 PVE 安全卸载移动硬盘
首先确保所有复制任务已经完成:
sync然后:
cd /root umount /mnt/pve-backup使用:
findmnt /mnt/pve-backup确认没有输出,再拔出移动硬盘。
这里不要省略卸载操作,特别是在大量写入之后,避免数据仍留在缓存中就直接拔出设备。
2. 连接飞牛 NAS
将移动硬盘直接接入蜜獾超存,通过飞牛 fnOS 的文件管理器访问外接存储。
在 NAS 内部数据盘上创建一个备份目录,例如:
Backups/ └── PVE-T480/ └── 2026-10-25/然后把 USB 移动硬盘上的dump、host-config、root、iso等目录全部复制进去。
这里选择的是复制,而不是移动。
这样 USB 移动硬盘上的原始备份仍然保留。
由于两台设备可以直接通过 USB 连接传输文件,也没有必要让大量 ISO 和 VM 备份通过 Wi-Fi 网络绕一圈。
需要注意,如果使用文件管理器进行复制,目标文件系统未必会保留所有 Linux 权限和扩展属性。因此,对于需要精确保留系统元数据的文件,原始 USB ext4 副本仍很重要,也可以另外保存 tar 归档。
3. 使用 SHA-256 校验 NAS 副本
为了防止复制过程中出现数据损坏,还可以在 USB 硬盘上提前生成校验文件。
例如,在从 PVE 卸载之前执行:
cd /mnt/pve-backup find . -type f ! -name SHA256SUMS -print0 \ | sort -z \ | xargs -0 -r sha256sum > SHA256SUMS sync这样会为文件生成一份 SHA-256 清单。
将整个目录复制到 NAS 后,在飞牛上进入对应备份目录,执行:
sha256sum -c SHA256SUMS如果所有文件均显示OK,就可以确认 NAS 上的文件与创建校验清单时的源文件内容一致。
最终,我保留了两份不同位置的备份:
| 备份位置 | 用途 |
|---|---|
| 1TB USB 移动硬盘 | 原始备份,断开连接后离线保存 |
| 蜜獾超存飞牛 NAS | 第二份备份,便于长期保管和查找 |
严格来说,断开连接的 USB 硬盘属于真正的冷备份,而一直在线的 NAS 属于另一份在线备份。
两者互为补充,可以减少单个存储设备故障造成的数据损失。
另外,宿主机配置和/root备份中可能包含密码、密钥等敏感信息,应限制 NAS 共享权限,必要时加密保存。
十、以后如何恢复整套 PVE 环境?
备份的最终目的,当然是为了将来能够恢复。
虽然这次暂时不准备迁移到新主机,但还是把恢复流程简单记录下来。
1. 重新安装 PVE
首先,在原 T480 或新的 x86 主机上安装 PVE。
如果需要最大程度还原宿主机环境,优先考虑接近原版本的 PVE。
如果只是恢复虚拟机,也可以考虑兼容的新版本,但恢复前最好确认备份格式和虚拟机硬件配置的兼容性。
安装完成后,先确保网络和存储正常。
2. 连接 USB 备份硬盘
假设移动硬盘仍然采用原来的 ext4 文件系统:
mkdir -p /mnt/pve-backup mount UUID=c9d8e233-25e8-4dff-b1fe-432d81ad03e0 \ /mnt/pve-backup然后重新添加 Directory Storage:
pvesm add dir backup-usb \ --path /mnt/pve-backup \ --content backup \ --is_mountpoint 1这样 PVE 就可以重新识别之前保存的 vzdump 文件。
如果未来 USB 硬盘已经不可用,但 NAS 上还有副本,也可以先把 NAS 中的dump目录复制到新 PVE 的备份存储里,再执行恢复。
3. 恢复虚拟机
可以直接在 Web 界面中选择备份文件,点击Restore。
例如,想恢复 VM 130(OpenWrt),也可以使用:
qmrestore \ /mnt/pve-backup/dump/vzdump-qemu-130-2026_10_25-21_46_32.vma.zst \ 230 \ --storage local-lvm这里把原来的 VM 130 恢复成 VM 230,用于测试,避免与已经存在的 VMID 冲突。
local-lvm是目标虚拟磁盘存储。实际恢复时,可以根据新主机的磁盘布局调整。
如果需要保留原来的 VMID,只要对应 ID 未被占用,就可以按原 ID 恢复。
恢复时,PVE 会从 vzdump 归档中重建虚拟机配置与已包含的虚拟磁盘。
但需要再次提醒:原先的 VM 快照历史并不会重新出现。
4. 恢复宿主机配置
宿主机恢复稍微复杂一些,因为有些配置依赖实际硬件。
例如,我在 T480 上使用了 Wi-Fi 上联、NAT 和 dnsmasq。如果将来换成台式机,网卡名称、网络拓扑都可能发生变化。
因此,不建议直接把旧的/etc/network/interfaces覆盖到新系统上。
更合适的做法是:
从
host-files.tar.gz中提取网络、存储、服务等配置,逐项核对恢复。参考
network.txt、routes.txt、nft-rules.txt重建 NAT 网络。根据新硬盘的 UUID 和目录布局修改挂载配置。
从
/root备份中找回脚本、ROM 及其他文件。将 ISO 复制到新的 PVE ISO 存储目录。
如果必须恢复整个 PVE 配置数据库,可以参考 Proxmox 官方的pmxcfs恢复流程,在适当的离线服务状态下处理config.db。
不过,对新装系统而言,我更推荐先重建基础配置,再通过qmrestore恢复 VM。不要先恢复整套旧 VM 配置数据库,又不加区分地恢复同一批 VM,以免产生配置冲突。
5. 特殊虚拟机还需要额外检查
尤其要注意硬件相关配置。
比如旧实验里使用过的 PCI Passthrough、GPU 直通、自定义 ROM 文件等,都可能依赖原来的 T480 硬件。
换到新主机以后,原来的 PCI 地址、IOMMU 分组、设备型号可能已经不同。
恢复这样的 VM 时,应先检查hostpci等设置,必要时移除旧的直通设备定义,再尝试启动。
另外,如果虚拟机配置仍然引用了旧存储上的 ISO,需要重新上传 ISO,或者先移除虚拟光驱中的无效引用。
至于 Windows XP、Windows 98 等使用 QXL、AC97、特殊机型配置的系统,只要相关虚拟硬件仍然受到支持,通常可以继续沿用,但也应该逐项验证。
最后,再依次检查虚拟机启动、网络连通性、磁盘内容、SPICE 显示和音频等功能。
至此,恢复工作才算真正完成。
写在最后:备份的不只是虚拟机,也是之前的实验成果
回顾这段时间在 T480 上折腾 PVE 的经历,我觉得最大的收获,并不是成功安装了多少种操作系统。
真正有价值的是,通过一台普通的旧笔记本,把很多原本只在文档中接触过的虚拟化技术,变成了可以动手验证的环境。
例如:
通过 OpenWrt、网桥和 NAT,加深对虚拟网络的理解。
通过 PCI 直通,理解物理设备与虚拟机之间的关系。
通过 Windows XP、98,研究虚拟设备、驱动、SPICE 和 QEMU 的兼容性。
通过 fnOS,探索 NAS、虚拟化与家庭存储的结合。
通过不同 Linux、BSD 系统的安装,体验各种操作系统在现代虚拟化环境中的运行方式。
而这次备份,也让我对 PVE 的数据组织有了更加完整的认识。
虚拟机备份、宿主机配置备份、ISO 文件归档,是三个相互关联、但不能互相替代的部分。
把它们分别保存,不但更容易维护,也方便未来在完全不同的硬件上恢复。
目前,10 台虚拟机的 vzdump 备份总共只有约 48GB,加上 ISO、宿主机配置以及自定义文件,放在 1TB 移动硬盘上完全没有问题。
再复制一份到飞牛 NAS,就为这些实验成果提供了第二层保障。
当然,备份完成不等于永远高枕无忧。以后有机会,我还会选择其中一些虚拟机,实际验证在新 PVE 环境中的恢复情况。
至于 T480,本身并没有什么特殊之处:一台几年前的商务笔记本,16GB 内存,有限的存储空间,却已经足够完成相当丰富的虚拟化实验。
现在它将承担其他任务,PVE 实验系列也暂时告一段落。
但这并不意味着以后不会再使用 PVE。
有了这次完整备份,等将来换上另一台机器,只需要重新搭建基础环境,再把需要的虚拟机恢复出来,就可以继续之前的实验。
机器可以更换,环境可以重建,而那些已经投入时间解决的问题,值得被保存下来。
这也算是这段 PVE 折腾经历,一个比较合适的阶段性收尾。