PVE 虚拟机安装 UNRAID:直通、阵列与性能调优
1. 先把账算清楚为什么要在 PVE 里套一层 UNRAID把 UNRAID 装进 PVE 的虚拟机里这个玩法在折腾存储的那批人里流传了好几年。我最初接触这个组合是因为手头只有一台机器一台装了 PVE 的塔式主机上面跑着几个必用的服务同时又想弄一套带校验盘的存储池。裸装 UNRAID 就意味着 PVE 里那些跑得好好的虚拟机要全部搬家成本太高。于是就有了把 UNRAID 当成一台虚拟机跑在 PVE 上的方案。这个方案的本质是把 UNRAID 当作一个“存储应用层”来用而不是把它当成整台机器唯一的操作系统。PVE 继续负责虚拟化调度和硬件抽象UNRAID 负责阵列管理、共享目录、Docker 容器这几件事。两者各管一段互不抢饭碗。这种套娃结构在硬件资源紧张、又想同时保留两套生态的场景下性价比很高。1.1 裸机 UNRAID 和 PVE 套娃的取舍裸机装 UNRAID 的优势在于磁盘控制器可以完全由 UNRAID 掌控阵列成员盘的识别路径短出问题时排查链路清晰。缺点是这台机器基本就锁定在存储这一件事上了想在上面额外跑几台不同架构的虚拟机UNRAID 自带的 KVM 功能虽然能用但管理界面的细致程度和快照、模板、集群这些能力跟 PVE 不在一个量级。反过来PVE 套 UNRAID 的优势是资源可以复用。同一台机器上你可以用它跑软路由、跑容器、跑开发环境再顺手把几块大盘交给虚拟机里的 UNRAID 做阵列。硬件利用率上去了缺点也很明显磁盘直通、USB 直通、IOMMU 分组这几件事会把新手卡在门口而且一旦直通配置写错PVE 宿主机会跟着起不来。我自己最终选套娃核心原因是我的数据盘和系统盘混在同一台机器上而 PVE 的备份和快照机制对系统盘的保护更顺手。如果你的机器就是纯粹做存储、不打算跑别的东西那裸装 UNRAID 反而少一层故障点没必要为了套娃而套娃。1.2 硬件清单与前置条件自查这套方案对硬件有几个硬性要求缺一个都会在某个环节卡住。下面这张表是我踩过坑之后整理的自查清单动手前对着过一遍能省掉很多来回。检查项具体要求不满足会怎样CPU 虚拟化Intel VT-x 或 AMD-VBIOS 里开启PVE 里建不了 64 位虚拟机直通支持Intel VT-d 或 AMD-ViBIOS 里开启无法做 PCIe 设备直通只能走块设备映射IOMMU 分组目标设备所在分组内无其他关键设备只能整组直通可能把宿主机网卡一起带走内存建议 16GB 起步UNRAID 单机分配 8GB阵列校验时内存吃紧缓存命中率低USB 接口至少留一个可直通给虚拟机的 USB 控制器或端口UNRAID 找不到启动盘存储盘校验盘容量必须大于等于最大数据盘阵列无法启动校验盘报错内存这一项很多人低估了。UNRAID 本身对内存的占用不算夸张但它的写缓存机制会尽量把数据先堆在内存里再落盘内存给得越足写入体验越接近内存盘。我一开始只给了 4GB往共享目录里拖一个几十 GB 的素材包机器直接卡到界面都刷不出来。后来加到 12GB同样的操作顺畅得多。另外提醒一句动手前把 PVE 里现有的虚拟机快照清理一下尤其是那些占着大块磁盘的旧快照。直通配置做完要重启宿主机重启前腾出空间和资源能避免不少意外。2. 宿主机侧的准备工作准备工作分三块内核层面把直通能力打开存储层面把要交给 UNRAID 的盘从 PVE 手里摘出来网络层面规划好桥接方式。这三块任何一块没做干净后面都会以“莫名其妙”的形式报出来所以别跳过。2.1 IOMMU 与内核参数的设置先在 BIOS 里确认 VT-dIntel 平台或者 AMD-ViAMD 平台是开启状态这个不用多说。进系统后第一步是改 GRUB 参数。nano /etc/default/grub找到GRUB_CMDLINE_LINUX_DEFAULT那一行Intel 平台加上intel_iommuon iommuptAMD 平台换成amd_iommuon iommupt。iommupt这个参数的意思是让不需要直通的设备走直通模式减少 DMA 重映射带来的额外开销实际用下来对网卡吞吐有正面影响。update-grub然后是加载 vfio 模块。编辑/etc/modules把下面几行加进去vfio vfio_iommu_type1 vfio_pci注意 PVE 8 用的是 6.x 内核vfio_virqfd这个模块已经并入vfio主模块了网上很多老教程还在让你单独加一行加了会报模块找不到别照抄。保存后重建 initramfsupdate-initramfs -u -k all重启然后用下面这条命令验证 IOMMU 是否真的生效dmesg | grep -E DMAR|IOMMU看到DMAR: IOMMU enabled这类输出就对了。如果什么都没看到回去检查 BIOS 里那个开关别急着往下走。再看设备分组情况这条命令会把每个 IOMMU 组和组内设备列出来for d in /sys/kernel/iommu_groups/*/devices/*; do n${d#*/iommu_groups/*}; n${n%%/*}; printf IOMMU Group %s $n; lspci -nns ${d##*/}; done重点看你想直通的那块 SATA 控制器或者 NVMe 盘落在哪个组组里有没有别的东西。如果一组里混着网卡、USB 控制器和 SATA 控制器那你就只能整组直通这时候要么把网卡也一起交给虚拟机不现实要么放弃 PCIe 直通改走块设备映射。提示BIOS 里如果有关闭 CSM、开启 Above 4G Decoding 的选项一并打开。Above 4G Decoding 对大容量显存和多设备直通有直接影响不开的话某些设备直通会失败或者识别不全。2.2 存储与网络的隔离规划这一步是最容易被忽略、也最容易埋雷的地方。PVE 有个习惯只要它识别到有文件系统的块设备就会尝试挂载甚至自动把它加进某个存储池。你要直通给 UNRAID 的盘必须在交出去之前把它们从 PVE 的视野里摘干净。先看当前磁盘分布lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT如果目标盘已经有挂载点先卸载umount /dev/sdX1然后去/etc/fstab里把对应的自动挂载条目删掉否则重启之后它又被挂回来虚拟机一启动就报设备被占用。如果你之前把这些盘加进过 PVE 的存储配置还要编辑/etc/pve/storage.cfg把相关的存储定义整段删掉。还有一种情况是盘上残留着 LVM 或者 ZFS 的元数据PVE 启动时会自动激活它。用下面这条命令把残留信息清掉wipefs -a /dev/sdX这条命令会清空设备上的文件系统签名执行前务必确认盘里没有你要保留的数据这是不可逆操作。我自己就干过一次把一块还存着旧资料的盘直接 wipe 了只能认栽。网络方面PVE 默认会创建一个vmbr0网桥虚拟机直接桥接到这个网桥上就能和物理网络平级通信。如果你的机器有多张网卡可以单独建一个vmbr1专门给存储流量用把 UNRAID 的共享访问和控制流量分开走互不干扰。nano /etc/network/interfaces在文件里追加一段网桥定义把eno2换成你自己的物理网口名auto vmbr1 iface vmbr1 inet manual bridge-ports eno2 bridge-stp off bridge-fd 0改完执行ifreload -a生效。物理网口名可以用ip link show查别照抄教程里的eth0现在很多主板网口命名是enp3s0这种格式。2.3 U 盘启动盘的制作与引导模式确认UNRAID 有一个和别人不一样的地方它的授权是绑定 U 盘的 GUID 的。这意味着启动盘不能随便换也不能用虚拟磁盘假装。你必须准备一个实体 U 盘用官方工具写入系统镜像然后把这个 U 盘完整地交给虚拟机。制作流程大致是这样准备一个 8GB 以上的 U 盘建议用品牌盘杂牌盘的主控在虚拟化环境里偶尔会认不出来用官方提供的 USB 创建工具写入镜像。写完之后打开 U 盘目录会看到一个EFI或者EFI-命名的文件夹。这里就是引导模式的关键点文件夹名带短横线的EFI-表示当前是传统 BIOS 引导模式把短横线去掉改成EFI才是 UEFI 引导模式。这个改名的操作在官方文档里有说明不是野路子。新建虚拟机时如果选了 OVMFUEFI固件而 U 盘目录还是EFI-开机就是一句“no bootable device”。我的建议是统一用 UEFI 模式。原因有两个一是 UEFI 引导下虚拟机的启动速度明显快一些二是 q35 机型配合 OVMF 对 PCIe 设备的支持更完整后面做硬盘直通时少一些奇奇怪怪的兼容问题。U 盘写完之后先别急着插到主机上先记下它的序列号和容量因为后面要在 PVE 里把这块具体的 U 盘直通给虚拟机插错口会导致虚拟机找不到设备。3. 创建虚拟机每个参数为什么这么填建虚拟机这一步Web 界面点几下就完事但每个下拉框背后都有讲究。参数填错的后果不会立刻显现往往是开机之后才以各种报错的形式冒出来。我把每一项拆开说。3.1 Web 界面建 VM 的参数逐项说明在 PVE 界面右上角点“创建虚拟机”按下面的表格填配置项建议值原因说明名称unraid随意但别用中文和空格操作系统类型Linux内核 6.xUNRAID 基于 Linux选 Linux 能启用对应的优化机型q35支持 PCIe 直通PCI 拓扑更接近真实机器BIOSOVMF (UEFI)配合 U 盘 UEFI 目录启动快添加 EFI 磁盘勾选存储选一个 SSDUEFI 需要一块小的 EFI 变量盘SCSI 控制器VirtIO SCSI single直通盘性能好支持多队列磁盘不添加UNRAID 从 U 盘启动不需要虚拟系统盘CPU 类型host让虚拟机直接使用宿主机的指令集CPU 核心4 核起阵列校验和 Docker 都吃 CPU内存8GB 起前面说过缓存命中率看内存网络模型VirtIO (半虚拟化)吞吐比 e1000 高一个档次防火墙去掉勾选局域网内访问共享目录用“磁盘”这一栏留空是很多人不理解的地方。常规虚拟机都需要一块虚拟系统盘但 UNRAID 的设计是系统和配置全部存在 U 盘上数据全部存在阵列盘上机器内部不需要任何虚拟磁盘。你给它加一块虚拟盘反而占地方又没用。EFI 磁盘那一项存储位置选一块 SSD。这块盘只有几十兆作用是保存 UEFI 的变量信息比如启动顺序。放在机械盘上会让开机自检慢几秒放 SSD 上基本无感。3.2 用 qm create 命令行复刻同一台机器界面操作适合建一台但如果要反复重建、或者想写成脚本命令行更省事。下面这段是我现在用的配置把 ID 和存储名替换成你自己的即可qm create 200 \ --name unraid \ --machine q35 \ --bios ovmf \ --efidisk0 local-lvm:1,efitype4m,pre-enrolled-keys0 \ --cpu host \ --cores 4 \ --sockets 1 \ --memory 8192 \ --balloon 0 \ --scsihw virtio-scsi-single \ --net0 virtio,bridgevmbr0,firewall0 \ --ostype l26 \ --agent 1--balloon 0这个参数值得说一下。它关闭了内存气球机制虚拟机的内存不会被宿主机动态回收。UNRAID 的内存缓存策略对内存波动比较敏感让它安稳地拿住分配的内存比省那点内存更划算。--efidisk0后面的pre-enrolled-keys0是关掉安全启动的预置密钥。UNRAID 的引导文件没有签名开着安全启动反而起不来这个细节不注意会卡很久。建完之后再加直通设备用qm set追加qm set 200 -usb0 host0781:5583这里的0781:5583是 USB 设备的厂商 ID 和产品 ID用lsusb命令能查到。查到的那一行形如Bus 002 Device 004: ID 0781:5583 SanDisk Corp.中间那串0781:5583就是要填的东西。3.3 U 盘、SATA 盘、NVMe 三种直通路线对比直通方式的选择直接决定了方案的性能上限和排查难度。下面把三种主流路线摊开对比直通方式配置难度性能适用场景USB 设备直通低够用只把启动 U 盘交给虚拟机块设备映射中中高SATA 机械盘、单块 SSDPCIe 控制器直通高最高整张 HBA 卡、NVMe 盘USB 直通是最简单的一条命令搞定。但它有个隐患USB 设备直通是按键值对匹配的如果你把 U 盘换个 USB 口插或者系统重启后设备号变了虚拟机可能就找不到盘。稳妥的做法是把 U 盘所在的那个 USB 控制器整块 PCIe 直通给虚拟机这样设备路径固定不会因为插口变化而漂移。块设备映射是给 SATA 机械盘用的。先用下面这条命令列出所有磁盘的稳定标识ls -l /dev/disk/by-id/找到形如ata-WDC_WD40EFRX-68N32N0_WD-WCC7K1234567的标识注意要选ata-或者wwn-开头的那一条不要选scsi-开头的后者在不同内核版本下可能变化。然后qm set 200 -scsi1 /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K1234567用by-id而不是/dev/sdb这种写法是因为设备名会随着启动顺序变化今天 sdb 明天可能变 sdc用 by-id 才能保证每次指向同一块盘。NVMe 盘建议走 PCIe 直通因为块设备映射会经过 PVE 的存储层损失一部分性能而 NVMe 的价值就在那点延迟上。直通前先确认它所在 IOMMU 组是独立的qm set 200 -hostpci0 0000:04:00.0,pcie1地址用lspci查。如果直通后虚拟机里认不到盘八成是 IOMMU 组不独立这时候要么接受整组直通要么退回块设备映射。注意把 SATA 盘映射给虚拟机之后PVE 宿主机上就看不到这些盘了。如果你之前用这些盘建过 ZFS 池或者 LVM 卷组务必先销毁再映射否则虚拟机一启动就报“设备忙”。4. 首次开机到阵列成型配置做完开机。第一次启动可能会花上一两分钟因为 UNRAID 要做硬件初始化。看到屏幕上出现一串 IP 地址说明系统起来了。4.1 网络与时间同步的初始化在另一台电脑的浏览器里输入屏幕上显示的 IP进入 UNRAID 的 Web 管理界面。默认是 DHCP 获取地址建议第一件事就是改成静态 IP不然路由器重启后地址一变你所有指向它的共享挂载、容器配置全要跟着改。在“设置 - 网络设置”里把 IPv4 地址固定下来网关和 DNS 填你局域网的实际值。改完点应用网络会重启浏览器会短暂断连刷新一下用新地址重新进就行。时间同步这一项容易被跳过但它对后续的 Docker 容器影响不小。容器里的日志时间戳、证书校验都依赖系统时间。在“设置 - 日期和时间”里把时区设成你所在的时区NTP 服务器填默认的公共时间服务器就行。我遇到过容器日志时间差八小时的问题排查半天最后发现是时区没设白白浪费半小时。4.2 阵列、校验盘与缓存池的配置顺序UNRAID 的存储结构分三层理解了这个结构后面的配置就顺了阵列Array核心存储池由数据盘和校验盘组成任何一块数据盘坏了都能靠校验盘重建缓存池Pool通常用 SSD存放频繁读写的热数据定时把数据刷到阵列共享目录Share面向用户和容器的目录可以指定优先落在缓存还是阵列配置顺序很关键先分配校验盘再分配数据盘最后配缓存池。这个顺序反了的话UNRAID 会按数据盘的当前状态去推校验盘的初始值可能导致校验数据和实际数据对不上。在主界面“阵列操作”区域把校验盘槽位选成容量最大的那块盘数据盘槽位按顺序放入其他盘然后勾选“启动阵列”。第一次启动会做校验初始化这个过程耗时取决于盘的大小和转速4TB 的盘大概要几个小时。初始化期间阵列可用但性能会受影响建议放在不忙的时候做。缓存池的配置稍微绕一点。如果你用的是单块 SSD直接建一个单盘池即可如果是两块以上UNRAID 支持 RAID1 或者 ZFS 镜像模式。我用的是两块 SSD 做镜像一块挂了还有另一块顶着。4.3 Docker 与共享目录的落地阵列起来之后去“设置 - Docker”里把 Docker 服务打开。这里有两个路径要设置Docker 镜像存储位置默认在/mnt/user/system/docker/docker.img可以改成你自己的路径容器数据目录默认/mnt/user/appdata这两个路径建议都放在缓存池上因为容器启动、配置读取都是高频小文件操作放机械盘阵列上会明显变慢。共享目录的配置在“共享”标签页。新建一个共享时有几个选项要留心选项说明我的选择主存储数据优先落在哪缓存池二级存储缓存满了之后落哪阵列缓存模式yes / prefer / only / no按目录用途区分分配方式高水位、填满等高水位“缓存模式”选prefer表示数据优先放缓存缓存满了再写阵列适合存放经常读写的工作目录。选only表示只放缓存不落阵列适合纯临时文件目录。选no表示直接写阵列适合大容量冷数据比如影视库这类文件读一次就很久不读放缓存反而浪费 SSD 寿命。我自己的做法是把工作目录设成prefer影视库存放目录设成no容器配置设成only。这套组合用了大半年SSD 的写入量控制得比较好没有出现缓存被塞满导致的卡顿。5. 故障排查与调优实录再细致的准备工作实际操作中还是会撞上问题。这一节把我自己踩过的和帮别人排查过的典型问题整理出来按类型分组方便对照。5.1 引导类问题速查引导失败是最高频的一类表现就是开机后卡在黑屏或者显示“no bootable device”。现象可能原因处理方式开机即报 no bootable deviceU 盘目录名是 EFI- 但固件选了 OVMF改名成 EFI或固件改回 SeaBIOS能看到 UNRAID 启动菜单但进不去系统U 盘被 PVE 挂载占用在宿主机 umount 该 U 盘启动到一半卡住无输出USB 直通键值对失效检查 lsusb 输出重新设置设备 ID进系统后 u 盘看不到了设备号重启后变化改用 USB 控制器整块直通第三行这个问题的坑我印象很深。当时 U 盘插在一个 USB 3.0 接口上重启宿主机之后接口编号变了虚拟机启动时按旧的键值对找不到设备开机直接失败。后来把整块 USB 控制器直通进去这个问题再也没出现过。还有一种情况是安全启动没关。如果在建虚拟机时没加pre-enrolled-keys0OVMF 会尝试验证引导文件签名UNRAID 的引导文件没有签名验证直接失败。解决方式是编辑虚拟机配置把 EFI 盘的安全启动关掉。5.2 直通与识别类问题磁盘直通了但虚拟机里看不到这类问题排查起来比较绕需要从宿主机和虚拟机两头看。先在宿主机确认设备确实被虚拟机占用了qm config 200 | grep -E scsi|hostpci|usb看看输出里有没有你配置的那几个设备。然后在虚拟机里执行lsblk看有没有对应的盘出现。如果宿主机配置里有、虚拟机里没有多半是控制器类型不匹配。VirtIO SCSI single 需要虚拟机内核有对应的驱动UNRAID 6.9 以后的版本都内置了太老的版本可能识别不了这时候换成 SATA 控制器试试。另一个常见问题是直通之后宿主机反而起不来。原因通常是直通的设备被宿主机也加载了驱动两边抢设备。解决办法是在/etc/modprobe.d/下建一个配置文件把对应设备的驱动加入黑名单echo blacklist nouveau /etc/modprobe.d/blacklist.conf这是我处理显卡直通时用的磁盘和 USB 控制器一般不需要这一步但如果遇到抢夺问题思路是一样的让宿主机彻底不碰这个设备。还有一种报错是 IOMMU 分组不独立。设备直通时如果同组还有别的设备在用PVE 会拒绝直通或者直通后宿主机异常。前面那条分组查询命令在这里就派上用场了看清楚组里有什么再决定是整组直通还是换设备。5.3 性能调优的实际测试默认配置能跑但性能有优化空间。我做过的几次调整效果按明显程度排序如下。第一项是开启多队列。VirtIO 网卡默认单队列在高并发场景下 CPU 单核容易打满。在虚拟机配置里给网卡加多队列参数qm set 200 -net0 virtio,bridgevmbr0,queues4队列数不要超过分配的 CPU 核心数一般设成核心数的一半比较合适。我给 4 核的虚拟机设了 4 队列局域网内大文件传输速度从 90MB/s 提升到了 112MB/s接近千兆网的理论上限。第二项是缓存模式的调整。前面提过把高频读写目录设成prefer冷数据设成no。这一步对日常体验的提升最直接因为写入不再直接落机械盘而是先命中内存和 SSD。第三项是 CPU 类型从kvm64改成host。这个改动不需要重启虚拟机就能在配置里改。改成 host 之后虚拟机可以使用宿主机的全部指令集某些压缩、加密操作会走硬件加速。我用它跑一个带压缩的备份任务耗时从 40 分钟缩短到 26 分钟。第四项是关闭内存气球。前面建虚拟机时已经提到这里不重复。补充一点如果你有多个虚拟机在跑关闭气球意味着内存不能动态回收需要提前规划好总量别让宿主机内存被吃满导致 OOM 杀进程。6. 备份、迁移与后续扩展跑起来之后还有两件事值得提前规划怎么备份以及以后想扩展时怎么动。6.1 虚拟机备份与磁盘克隆PVE 自带的备份功能可以直接备份整台 UNRAID 虚拟机。但这里有个认知误区要澄清备份虚拟机不等于备份你的数据。虚拟机的备份里只有配置文件和 EFI 变量盘真正存储数据的那些直通盘不在备份范围内。所以正确的备份策略是两层第一层定期备份 UNRAID 的 U 盘内容。整个 U 盘目录打包存到别的地方几十兆而已出问题时可以快速恢复配置和授权信息第二层数据本身的备份。这个用 UNRAID 自己的方案解决比如把重要共享目录同步到另一台设备或者云存储虚拟机的配置备份用 PVE 的定时任务就行每周一次保留最近四份。这种备份体积小恢复快改错了配置直接回滚。如果想把整个虚拟机复制一份做测试不要直接克隆因为克隆出来的虚拟机同时启动会和原虚拟机抢直通设备。正确做法是关掉原虚拟机再克隆qm clone 200 201 --name unraid-test --full克隆完之后记得编辑新虚拟机的配置把直通设备删掉或者改成其他设备否则两个虚拟机抢同一个 U 盘轻则其中一个起不来重则数据错乱。6.2 后续可以延伸的方向这套架子搭好之后能玩的东西其实不少。一个方向是把 UNRAID 里的 Docker 和 PVE 里的容器做分工。UNRAID 的 Docker 生态在媒体管理这类场景上开箱即用配置界面友好PVE 的 LXC 更轻量适合跑一些自己写的脚本和定时任务。两者不冲突各用所长就行。另一个方向是给 PVE 加一层网络存储。比如把 UNRAID 的共享目录通过 NFS 挂回 PVE这样 PVE 里的虚拟机可以直接用大容量存储不用给每台虚拟机单独分盘。挂载的时候记得用 NFSv4性能和权限管理都比 v3 顺手。还有个方向是做异地备份。UNRAID 支持把共享目录同步到远程目标配合定时任务重要数据可以做到每天一份异地副本。这个配置起来比想象中简单关键是把带宽和同步窗口规划好别让它和日常工作抢资源。最后分享一个我自己的使用习惯每隔一段时间去 PVE 的日志里翻一翻看看有没有 IOMMU 相关的报错。这类问题往往是渐进式的一开始只是偶发的小异常攒到一定程度才爆发。提前发现处理起来就只是改一行配置的事等它爆发可能要花一整天做数据恢复。这个习惯帮我提前发现过一次 USB 控制器过热导致的设备掉线避免了阵列重建。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →