English日本語

文章

keelOS: 存储怎么设计才更好的适应AIO构架?

keelOS 的答案是两个池:宿主管一个放虚拟机的池,NAS 的盘整个交给 NAS 虚拟机,宿主永远不依赖任何一台虚拟机。按机器上盘的多少,它有三种布局,最少一块盘也能用。这篇讲为什么这样分,以及别的分法差在哪里。

一台机器,两种存储

AIO(All-in-One)是一台机器同时当 NAS 和虚拟机主机。它上面有两种性质不同的数据:

虚拟机的盘 NAS 的数据
内容 系统盘、镜像、检查点 照片、影视、备份、共享文件
容量 几十到几百 GB 几 TB 到几十 TB
要什么 随机读写快,所以放 SSD 容量大、冗余可靠,多数放机械盘
谁在用 宿主上的虚拟化程序 局域网里的电脑、手机和别的虚拟机

问题是这两种数据由谁来管。全交给宿主,宿主一重启 NAS 和虚拟机一起停。全交给一台存储虚拟机,那台虚拟机一出问题所有虚拟机的盘都没了。存储怎么分,决定了这台机器哪一部分坏了会连累哪一部分。

先交代 keelOS 的结构

keelOS 分三层。最下面是 hyp,一个很小的 hypervisor,由 UEFI 启动后常驻内存,虚拟机的内存和 CPU 状态都在它手里。中间是 root,一个精简的 FreeBSD,负责驱动、ZFS、网络和设备模拟(bhyve)。最上面是虚拟机。

root 可以随时重启或升级:虚拟机暂停半分钟左右,内存留在 hyp 里不动,root 起来后原地继续,TCP 连接不断。所以在 keelOS 上,宿主重启不再等于全家停机。存储的设计要配得上这一点:宿主重启时,NAS 的盘也不能断。

别家怎么做:四种结构

现有的 AIO 方案把存储放在四种位置,每一种都有一个躲不开的代价。

结构 例子 池在哪 虚拟机的盘在哪 好处 代价
宿主就是 NAS Unraid、TrueNAS、群晖 DSM、飞牛 fnOS 宿主 宿主的池 最简单,一个界面管全部 宿主重启,NAS 和虚拟机一起停
存储虚拟机供全部存储 napp-it AIO(ESXi 加一台 ZFS 存储虚拟机,“AIO”这个词的出处)、Nutanix 的 CVM 存储虚拟机,HBA 直通给它 存储虚拟机上,经 NFS 或 iSCSI 回供给宿主 整台机器一个池,冗余、快照、备份都在一处 宿主依赖虚拟机:开机要先起存储虚拟机,等它就绪再挂载,再起别的虚拟机;它一挂,全部虚拟机的盘都挂
两个池 Proxmox 加一台 TrueNAS 虚拟机 NAS 的池在 NAS 虚拟机里;宿主另有一个放虚拟机的池 宿主的池 宿主不依赖虚拟机,NAS 挂了别的虚拟机照跑 盘要分成两拨
池在宿主,虚拟机只做协议 vSAN File Services;Proxmox 宿主的 ZFS 加一个跑 Samba 的容器 宿主 宿主的池 一个池;文件服务和宿主隔开 要一条高效的宿主到虚拟机的文件通道;快照、配额要回头找宿主做

这张表是凭我们对这些产品的了解整理的,没有逐条去核对各家最新的版本。

第二种在机房里很成功。Nutanix 的每个节点都是这个结构,但它靠集群兜底:一个节点的存储虚拟机挂了,I/O 转到别的节点。家里和小办公室只有一台机器,没有别的节点可转。

keelOS 的选择:两个池,宿主不依赖虚拟机

keelOS 选第三种,并把它写成一条规矩:root 永远不依赖任何一台虚拟机。没有一台虚拟机在跑的时候,root 也能启动、能建虚拟机、能装系统。

  • zones 池归 root:放虚拟机的系统盘、镜像和检查点,用 SSD。
  • NAS 的盘归 NAS 虚拟机:硬盘控制器整个直通过去,池由虚拟机里的 NAS 系统自己建,root 不碰。
  • 虚拟机的盘不放在 NAS 上:NAS 虚拟机关了、升级了、换了另一个 NAS 系统,别的虚拟机照跑。

为什么不选另外三种:

  1. 宿主就是 NAS:keelOS 的 root 是可以随时重启的一层。共享服务放在 root 里,root 一重启 SMB 连接就断;放进虚拟机,连接只是暂停半分钟。
  2. 存储虚拟机供全部存储:单机上它是全部虚拟机的单点,开机和恢复的顺序也变复杂。
  3. 池在宿主、虚拟机只做协议:bhyve 上宿主到虚拟机的文件通道只有 virtio-9p,慢,Windows 权限要的扩展属性和 ACL 也传不全。

两个池的代价是盘要分成两拨。下面的三种布局就是在回答:有几块盘的时候,这两拨怎么分。

三种盘布局

按盘的数量选:盘够就用 A,盘少用 B,只有一块盘用 C。三种都是两个池,都守住“root 不依赖虚拟机”。

三种盘布局:哪些盘归 root,哪些盘归 NAS 虚拟机
三种盘布局:哪些盘归 root,哪些盘归 NAS 虚拟机

A 和 B 里 NAS 拿到的是真盘;C 里 NAS 的池叠在 root 的池上面。

布局 适合 keelOS 装在哪 zones(放虚拟机) NAS 的盘 ISO 放哪
A 标准 一块小的启动盘,两块 SSD,若干数据盘 单独一块启动盘 两块 SSD 做镜像 其余的 SSD/HDD 直通 启动盘剩下的空间
B 盘少 一块或两块 SSD,若干数据盘 和 zones 同在一块盘上,或同在一对镜像盘上 那块盘或那对镜像的其余空间 其余的盘直通 zones 里
C 只有一块盘 迷你主机、试用 和 zones 同在这块盘上 这块盘的其余空间 zones 上的一个 zvol zones 里

A 是标准做法。 系统、虚拟机、NAS 三拨盘互不相干:启动盘坏了换一块重装,zones 是镜像,坏一块 SSD 虚拟机不停,NAS 的冗余由 NAS 系统自己做。keelOS 的启动分区只占 2 GiB,启动盘剩下的空间正好放安装用的 ISO,这样刚装好、还没建池就能上传 ISO。

B 省一块盘。 keelOS 装在盘的开头,同一块盘剩下的空间建 zones。用一对镜像盘时,每块盘开头各有一份启动分区,坏任何一块都还能启动。

C 是盘实在少的时候。 NAS 虚拟机拿不到真盘,拿到的是 zones 上的一个 zvol,它在上面再建自己的文件系统。NAS 里删掉的空间能还给宿主:虚拟机里 TRIM 之后,zvol 在宿主上占的空间会掉回去,这一点实测过。代价是这块盘坏了全部都没了,要靠备份到别的机器。

盘怎么交给 NAS:整个控制器直通

A 和 B 里“其余的盘直通”指的是把硬盘控制器整个交给 NAS 虚拟机,不是把盘做成虚拟盘。NAS 系统用自己的驱动直接操作硬件,看到的是真盘:SMART、写缓存、真实的错误都在。TrueNAS 官方对虚拟化部署的建议也是这样。

控制器 在 keelOS 上的状态
NVMe(整块盘就是一个控制器) 实测通过,并且跨 root 重启不断
板载 SATA(AHCI) 实测通过:带盘建池、写入、校验一致,scrub 0 错误;带盘跨 root 重启还没测
SAS HBA(LSI IT 模式) 还没有硬件测过

几条为 NAS 场景定的规矩:

  • 按厂商、型号和序列号认设备,不按插槽。 换了插槽照常工作。
  • 开机时就把这些设备留住,root 的驱动没机会碰它们。 root 不会自动导入 NAS 的池,两边同时写会毁数据。
  • 一个设备只归一台虚拟机。 第二台要同一个设备时直接拒绝。
  • IOMMU 由 hyp 管,不由 root 管。 root 重启时控制器的 DMA 一直有效,这是下一节能成立的原因。

控制器直通有一个前提:给 NAS 的盘和 root 自己用的盘不能在同一个控制器上。最常见的搭配是系统和 zones 用 NVMe,机械盘接板载 SATA 或 HBA,正好分得开。分不开的机器(系统盘和数据盘全在板载 SATA 上)要按盘而不是按控制器来交,这个还没做。

实测:宿主重启,存储不断

拿着整块 NVMe 的 NAS 虚拟机,在持续写盘时跨过了 root 重启,没有超时、没有复位、没有错误。开发机是双路 Xeon、192 GB 内存,NAS 虚拟机是 FreeBSD,直通的是一块 Intel P3600。

测试 结果
NVMe 直通后的基本读写 虚拟机里读 1.37 GB/s;ZFS 池写 20 GB,scrub 0 错误
虚拟机一直 fsync 写盘,root 重启 4 次(2026-09-29) 每次暂停 21–23 秒;写盘循环没断,没有 NVMe 超时和复位,池 ONLINE,scrub 0 错误
累计 root 重启次数 14 次,无错误
一台虚拟机带两个整块设备(NVMe 加一个没接盘的板载 AHCI),root 重启 5 次 两个设备都正常,0 错误
17 台虚拟机同时在跑,其中有这台 NAS root 重启 65.5 秒,17 台全部恢复
运行中把 NVMe “拔掉”(关掉它上游端口的链路来模拟) root 不受影响;只有这台虚拟机里的设备失效、池挂起
板载 SATA 控制器带盘直通(另一台开发机,2026-09-30) 建池,写 2366 MiB 随机数据,导出再导入后 sha256 一致,scrub 0 错误

这能成立靠两件事。虚拟机的内存在 hyp 的池里,root 重启时不动。控制器的 IOMMU 映射也在 hyp 手里,所以虚拟机暂停的那一刻已经发给盘的命令照常做完,数据写进虚拟机的内存,恢复后补上中断。虚拟机里看到的只是一段 I/O 延迟。

网络这一侧有一个限制:用 SR-IOV 虚拟功能(VF)做网卡的虚拟机,现在在 root 重启时要关机再开。要让 NAS 的连接也不断,它的网卡用 virtio。

还没做完的

两个池的结构和控制器直通现在就能用;下面这些还没做,或者还没测。

  • 布局 A 的 ISO 放启动盘:ISO 现在只能放在 zones 里,启动盘 2 GiB 之后的空间还没用上。
  • 网页按布局引导:安装向导只装到一块盘,建池(单盘、镜像、raidz)和第二份启动分区在装好后的“存储”页上做。页面还不会问“这块盘给虚拟机还是给 NAS”。
  • 按盘交给 NAS:系统盘和数据盘在同一个控制器上的机器,现在只能用布局 C。
  • SATA 控制器带盘跨 root 重启没测;SAS HBA 没有硬件。
  • 布局 C 的调优:ZFS 叠在 zvol 上,两层的压缩、缓存、块大小怎么分工还没有实测数字。
  • VF 跨 root 重启:带 VF 的虚拟机现在要关机再开。
  • 第三方 NAS 系统带直通盘:飞牛 fnOS 作为虚拟机装过、能用;把直通的盘交给它建存储空间还没测。上面的实测用的都是 FreeBSD。
  • 虚拟机备份到 NAS:还没有。

还有一件在计划里的事:keelNAS,我们自己出的一台 NAS 虚拟机,和 keelOS 并列的项目。现有的 NAS 系统都假设自己是宿主,带着虚拟机和应用功能,装进虚拟机后这些是多余的;keelNAS 只做存储(池、共享、权限、快照、SMART),为“当虚拟机”而设计。它现在只有调研和设计,没有代码。在那之前,NAS 虚拟机里装你喜欢的系统。

结语

AIO 的存储设计归结起来是一个问题:谁依赖谁。keelOS 的回答是宿主不依赖虚拟机,虚拟机的盘和 NAS 的盘各有各的池;再加上宿主重启时虚拟机和直通的盘都不断,三层里任何一层要动,都不必停掉另外两层。

选布局只看盘的数量:有启动盘、两块 SSD 和数据盘,用 A;SSD 不够,让系统和 zones 合用,用 B;只有一块盘,用 C。

相关的文章:《keelOS: 新时代的AIO系统,专为NAS爱好者打造!》讲整体,《keelOS: 强化VM的硬核技术,PCIe直通,SR-IOV,一个都不能少!》讲直通的细节。

← 文章 · 为什么选 keelOS