南风大叔

PVE 下安装 OpenWrt 虚拟机完整指南:从创建到磁盘扩容

前言

在家庭网络中,利用 PVE(Proxmox VE)运行 OpenWrt 虚拟机作为旁路由,再配合 OpenClash 等插件实现透明代理,是一种非常优雅的方案。其他虚拟机只需要将网关指向 OpenWrt 的 IP,即可实现科学上网,无需在每台设备上单独配置。

然而实际操作中会遇到不少坑,尤其是 OpenWrt 官方镜像默认磁盘只有约 120MB,安装 OpenClash 等插件根本不够用。本文完整记录从零开始的全过程,包括踩过的坑和解决方案。

环境信息

第一步:下载 OpenWrt 镜像

SSH 登录 PVE 宿主机,下载 OpenWrt 的 x86-64 镜像。

重要:一定要选择 ext4-combined 版本,不要用 squashfs。ext4 格式才能方便后续扩容。

cd /tmp

# 下载镜像(以 23.05.5 为例,请根据实际最新版本调整)
wget https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz

# 解压
gunzip openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz

解压后得到一个约 130MB 的 .img 文件。

第二步:扩容镜像文件

这一步是在导入 PVE 之前进行的,非常关键。

# 将镜像扩容到 10GB(根据需要调整,装 OpenClash 建议至少 1GB)
qemu-img resize openwrt-23.05.5-x86-64-generic-ext4-combined.img 10G

⚠️ 注意顺序qemu-img resize 只能修改镜像文件本身。一旦通过 qm importdisk 导入到 PVE 后,再对原始 img 文件执行 resize 是无效的,因为 VM 使用的已经是 LVM 卷而非原始文件。

如果已经导入了,也可以用 qm resize <vmid> <disk> <size> 或在 PVE Web 界面中扩容,效果相同。

第三步:在 PVE 中创建虚拟机

在 PVE Web 界面中创建一个新的 VM,注意以下配置要点:

基本设置

操作系统

系统

磁盘

CPU

内存

网络

第四步:导入磁盘到虚拟机

回到 PVE 宿主机的 SSH 终端:

# 将扩容后的镜像导入 VM 101,存储使用 local-lvm
qm importdisk 101 /tmp/openwrt-23.05.5-x86-64-generic-ext4-combined.img local-lvm

导入完成后,回到 PVE Web 界面:

  1. 找到 VM 101 → 硬件
  2. 会看到一个 “未使用的磁盘”(Unused Disk)
  3. 双击它 → 总线选择 SATA(如 sata0)→ 点击"添加"
  4. 进入 选项 → 引导顺序,将 sata0 设为第一启动项

为什么必须选 SATA?

这是一个关键的坑。如果磁盘挂载为 scsivirtio 接口,OpenWrt 启动时会卡在:

Waiting for root device PARTUUID=4c5af05c-02...

这是因为 OpenWrt 的 x86 官方镜像内核默认只包含 IDE/SATA 驱动,无法识别 SCSI 或 VirtIO 磁盘。将磁盘接口改为 SATA 即可解决。

第五步:首次启动与验证

启动 VM 101,进入 OpenWrt 控制台,检查磁盘:

df -h

此时你会看到类似这样的输出:

Filesystem      Size   Used  Available Use% Mounted on
/dev/root     122.3M  27.9M     91.9M  23% /

虽然磁盘已经是 10GB,但 分区和文件系统还是原来的大小,需要手动扩展。

第六步:扩展分区和文件系统

方案一:在 OpenWrt 内部操作(在线扩容)

# 安装工具
opkg update
opkg install parted losetup resize2fs

# 查看磁盘,确认总大小为 10GB
parted -l

# 扩展第二分区(rootfs)到磁盘末尾
parted /dev/sda resizepart 2 100%

# 扩展文件系统
resize2fs /dev/sda2

⚠️ 已知问题:在线执行 resize2fs 时可能会报错:

resize2fs: Invalid argument While trying to add group #1

这是因为 OpenWrt 使用的较老版本 resize2fs 在线扩容大幅度增长时存在 bug。如果遇到此错误,请使用方案二。

方案二:在 PVE 宿主机上离线操作(推荐)

这是更可靠的方式,在 VM 关机状态下从宿主机直接操作 LVM 卷。

# 1. 关闭 OpenWrt 虚拟机
qm stop 101

# 2. 安装 kpartx(如果没有的话)
apt install kpartx

# 3. 映射 LVM 卷内的分区
kpartx -av /dev/pve/vm-101-disk-0

执行后会输出类似:

add map pve-vm--101--disk--0p1 (252:14): 0 32768 linear 252:6 512
add map pve-vm--101--disk--0p2 (252:15): 0 20937728 linear 252:6 33792

⚠️ 注意设备路径:kpartx 映射出来的设备名中,pve 后面是 单横线,而非双横线。

  • ✅ 正确:/dev/mapper/pve-vm--101--disk--0p2
  • ❌ 错误:/dev/mapper/pve--vm--101--disk--0p2

可以用 ls /dev/mapper/pve-vm--101--disk--0p* 确认实际路径。

# 4. 检查并修复文件系统
e2fsck -f /dev/mapper/pve-vm--101--disk--0p2

# 5. 扩展文件系统
resize2fs /dev/mapper/pve-vm--101--disk--0p2

# 6. 清理分区映射
kpartx -dv /dev/pve/vm-101-disk-0

# 7. 启动虚拟机
qm start 101

验证结果

启动后进入 OpenWrt,再次检查:

df -h

输出应该类似:

Filesystem      Size   Used  Available Use% Mounted on
/dev/root       9.9G  27.9M      9.8G   0% /

至此,磁盘扩容完成。

网络拓扑参考

完成以上步骤后,你的网络架构大致如下:

互联网
  │
  ▼
PVE 物理网卡
  │
  ├── vmbr0 (WAN) ──→ OpenWrt VM (eth0/WAN)
  │                         │
  │                    OpenClash 透明代理
  │                         │
  └── vmbr1 (LAN) ←── OpenWrt VM (eth1/LAN) ──→ 其他 VM

其他 VM 的网络配置:

这样所有经过 OpenWrt 的流量都会被 OpenClash 处理,实现透明代理。

常见问题汇总

问题 原因 解决方案
启动卡在 Waiting for root device PARTUUID=... 磁盘接口不是 SATA/IDE 将磁盘改为 SATA 接口
qemu-img resize 对 VM 无效 导入后 VM 使用的是 LVM 卷 导入前 resize,或用 qm resize
resize2fs 在线报 Invalid argument OpenWrt 内 resize2fs 的已知限制 关机后在 PVE 宿主机上离线扩容
kpartx 映射后找不到设备 设备路径中的横线规则搞错 ls /dev/mapper/ 确认实际名称
opkg update 失败 OpenWrt 网络未配置 先配置好 WAN 口 IP 或在宿主机上离线操作

总结

整个流程的核心要点:

  1. 选 ext4-combined 镜像,squashfs 无法扩容
  2. 导入前先扩容 img 文件,这是最省事的时机
  3. 磁盘接口必须选 SATA,否则 OpenWrt 内核无法识别
  4. 分区扩展和文件系统扩展是两步操作,缺一不可
  5. 在线扩容可能失败,离线操作更可靠

希望这篇文章能帮到同样在折腾 PVE + OpenWrt 的朋友,少踩一些坑。

#PVE #Proxmox #OpenWrt #虚拟化 #旁路由 #OpenClash