TrueNAS 硬切换实录

我决意要脱离十分可靠、但顽固不化的群晖系统,投入“开放系统”之怀抱——尽管事实表明这个系统同样处处设限。过程非常漫长而艰辛,在此一一记录。
本文是《资料服务器升级换代》的精神续作。

零、起因

多年来,群晖系统的确提供了简洁的操作环境、稳定的服务质量、堪用的扩展空间。在新资料服务器引入群晖系统后,尽管其依旧任劳任怨,但时间一长,许多问题浮出水面,令我苦恼:

  • 系统安全性不足,新版限制较多。四年间,所用群晖系统停留于 6.2 版本;自 7.0 版本发布以来,群晖不仅逐渐收缩对 6.2 版本之支持,且在新系统中做出更多针对非授权设备的限制。非授权设备普遍有个特点,即不能随意升级系统,否则后续不可引导;得不到更新,也便增加一分受到网络攻击的风险。即使要升级,很不幸,Redpill、RR 等引导程序相继停止更新或不再公开,后续第三方维护版本是否可靠有待商榷。
  • 内核版本陈旧。尽管当前群晖系统所用内核(Linux 4.4)可以基本适配资料服务器,但它也有安全性和对未来新硬件的兼容性问题(例如,要利用九代及后续 Core 的集成 GPU 需打内核补丁或干脆不支持),不利于日后的进一步升级。TrueNAS、Unraid 所用内核(6.1.x)要先进很多。
  • 内网传输速度有隐性限制。不知为何,通过 SMB 自服务器下载时,速度被限制于 60 MB/秒。
  • 应用版本较旧或依赖于第三方分发源。以 Docker 和 Tailscale 为例,前者因群晖停止支持,停留于 20.3 版本;后者则需从“矿神”软件库获取,随着群晖 6.2 版本日薄西山,该软件库结束支持只是时间问题。

旧的不去,新的不来;是时候回炉再造,拥抱新技术了。

一、理论考究

凡事做好功课,方可有备无患。我开始就新软硬件方案进行考究。

1.1 操作系统考究

我对新操作系统的要求是:安全、可靠,软硬件易于升级和维护,免于破费,支持 Docker。汇总一下较流行的、可用于资料服务器的操作系统:

TrueNAS Core 基于 FreeBSD 内核,不具备支持 Docker 之基础,故略过。
Unraid 需购买授权(有免费的办法,但如此则软件升级受阻);需通过 U 盘运行,可靠性稍逊。略过。
OMV 系统在早年是有试水经验的;功能马马虎虎,软件获取有一定阻碍,浅尝辄止。
只要给以恰当的配置和足够大的软件源,普通 Linux 也有成为资料服务器的潜力——不过我当下没那份闲心去重温 Arch Linux 安装之路……
至于 Windows,自身的资源开销就不小,Docker 支持则要绕些弯路(依赖 Linux 子系统,微软文档有详细说明),我对网上各种授权工具也不放心。
仅剩下 TrueNAS Scale:基于 Debian Linux 而建,稳定可靠且完全免费,有新式 NVMe 固态盘和 Docker 支持。

1.2 TrueNAS Scale 相关特性考究

新系统在很多特性上无疑是区别于群晖系统的——尤其是 ZFS 文件系统的支持。针对这种文件系统,我特意做了相关调查,结论是:ZFS 文件系统之可靠性基本与 BTRFS 相当;现有硬件无需调整即可支持新系统;可以引入 NVMe 固态盘用于引导或缓存。
具体而言,我通读了 Jason Rose 撰写的《TrueNAS 和 OpenZFS 入门详解》以及 Reddit、TrueNAS 社区等论坛帖子,其中和硬件相关的有:

  • 处理器需求。一般“四核”处理器可堪一用,部分需求如 ZFS 加密需更高算力。
  • 内存需求。TrueNAS 会利用闲置内存空间作为一级缓存;8 GB 是底线,16 GB 适合小型服务器;并发用户越多、文件访问频次越高,内存需求越大。考虑到家中几乎只有我一个用户,故现有内存无需调整。
    此外,据传 ZFS 文件系统有“每增加 1TB 存储需额外配备 1GB 内存”之要求;经查证,该要求当且仅当存储池的区块去重(Deduplication)功能启用时成立,其余情况下,内存仅略为影响系统的读取性能,即缓存命中率。
    对于内存校验纠错功能(ECC),TrueNAS 官方文档和《详解》称并非强制要求,但推荐使用。考虑到内存比特翻转风险极低,即使在进行全盘校验(即“数据清理”或 Scrubbing)时,发生不可逆错误的风险也微乎其微。此前在群晖系统中曾进行多次数据清理,未见错误报告;故 ECC 不是目前需要关注的特性。此外,如将来有就地升级处理器之需,如七代 Core i5,则新处理器连支持 ECC 的余地也剥夺了。
  • 二级缓存需求。选项有“二级动态切换式缓存(L2ARC)”“独立 ZFS 意向记录(SLOG)”以及“元数据专用分区(Special Metadata VDev)”。L2ARC 对并发读取有益,SLOG 对并发写入有益,但在家庭环境中罕见并发操作;据官方文档,“元数据分区”是和存储池强绑定的,一荣俱荣,一损俱损。最终决定通过 SLOG 试水——毕竟这次硬切换要求从多地往回倾倒数据,可以验证 SLOG 是否适用于当前环境。
  • 固态硬盘需求。TrueNAS 支持从 NVMe 固态盘引导,非常可靠;系统本身占地较小,小至 16GB 的固态盘也足以承载——这里包括我垂涎已久的蓝厂 Optane 固态盘。既有 120G 固态盘可用于托管 Docker 容器数据。
  • 其余硬件需求不影响新系统之运作。

对于软件,我比较关心的是如何管理各种应用。得知新系统依赖 Kubernetes 容器提供额外服务,但要连接 GitHub 方可获得这些容器必需的信息,且据传容器管理方式和 Docker 稍有不同;早期版本(注意,这是个伏笔)的 Scale 对 Docker 有充分支持。可以考虑绕过系统管理界面,安装 Portainer 以便统一管理诸容器。

二、前期准备

2.1 资料备份

这次“硬切换”要求格式化文件系统,故需要清空资料服务器的一切数据。我准备总计 11 TB 的海量空间来备份:

硬盘接入点
Seagate Barracuda (2TB)旧资料服务器
Toshiba P300 (2TB)
注:磁头故障,仅利用一半空间
旧资料服务器
Seagate SkyHawk (4TB)新服务器 => 旧服务器
Seagate Backup+ (1TB)移动硬盘
WD Red (3TB)联想个人云
ADATA SX8200 Pro (1TB)移动硬盘

其中文档、照片、音乐等重要资料需有两个副本(总大小不足 1 TB),其余保留单副本。既有 Docker 容器数据一律遗弃。

2.2 硬件之添置

如上文所述,硬件需求基本等同于群晖系统;此次出于尝鲜和寻求耐久度高的二级缓存之需,购置 Optane 固态盘三根,作价 38.7 元。此外准备了 PCIe—M.2 转接卡两片,成本 30.8 元(其实早前这批转接卡用来安置返修下来的 ADATA 固态盘,但主机存储远未饱和,用不上它们,这次权当重新分配)。主机配备四个 PCIe 槽位和两处 M.2 槽位(分别供无线网卡和固态盘使用),故三根 Optane 可一并安装。

我也曾考虑二手企业级 M.2 固态盘,如三星 PM953a、PM983a;但成本较高,分别以 150 元和 330 元起步,用作缓存稍显奢侈。(当然好处是可以承接离线下载时的缓存需求,避免文件碎片化。)

2.3 系统之安装

升级 BIOS 至撰稿时最新的 v2.48 版本。(商用机型就是好,直到 2023 年尚可得到支持。)

服务器支持从 NVMe 固态盘引导,故安装 TrueNAS 至其中一根 Optane。硬盘均格式化为 ZFS;16 TB 硬盘划入主存储池,另两根 Optane 分别划为主存储池 SLOG应用级二级缓存池(实为普通存储池);启用 SMB 服务,向主存储池恢复数据。恢复完毕后,取回 Seagate 4TB 硬盘并格式化,作为热备份存储池

格式化后,可见主存储池之可用容量为 14.42 TB,较群晖系统中的 13.97 TB 增加良多——增量近乎 500 GB。但是,热备份池的容量仅增加 0.02 TB。

三、调试和验证

基本存储服务就绪,让我们为它增添更多可能性!

3.1 SLOG 在实际环境中的可行性

从监测数据可见,恢复资料过程中,SLOG 的吞吐量接近于零,证明其对经 SMB 共享产生的请求无效。数日后取消 SLOG,改为划入缓存池。

3.2 数据集/目录访问权限

目录权限的设置难度明显高于群晖系统。一般设置下,选项有目录所有人、所属用户组,以及所有人、用户组和其他用户的访问权限。同时有高级访问控制(ACL),可以认为 ACL 功能与群晖系统的权限管理基本一致。比较简明的做法是,将根目录以下一切数据集/目录的所有者一律改为可公开访问的非 root 用户(组)。

3.3 Docker 可用性

系统自备的 Charts 应用服务不尽人意。一方面,Charts 列表要从 GitHub 下载,不可能直连,“镜像”更新频率也不高;另一方面,“Custom App”在唯一一个 Charts 列表不可用的情况下根本没有入口,即使有入口,设置也是歪歪扭扭、不知所云。
正当我试图以命令行操作 Docker 时,出现意想不到的情况:Docker 命令根本不存在!这意味着最新版 Scale 23.10.1 根本没有预装 Docker!试图利用 apt 时,又发现尽管 Apt 命令存在,却不能提权使用;换言之,iXsystems 故意取消了 apt 的执行权限!通过 chmod +x /usr/bin/apt* 给予权限后,再来搜索官方仓库,确有提供 Docker,虽版本较早(20.10.24),但聊胜于无,遂安装。(引入普通 Debian 软件库的话,虽可加速下载,但我担心有破坏某些定制组件的可能,故未采用。)
中文社区就此问题有零星讨论,这里找到了一篇知乎专栏,其介绍通过 Jailmaker 引入 Docker;此法较为复杂,但可确保获取到最新版 Docker。

安装并启动 Portainer,一切都方便操作了。

3.4 Docker 应用安装

需要部署的 Docker 应用如下。

  • 媒体管理:Jellyfin、Plex
  • 私有 Git 服务:Gitea
  • 文件同步:NextCloud + MariaDB、Syncthing
  • 离线下载:qBittorrent
  • Docker 容器管理:Portainer
  • 内网穿透:Tailscale
  • 文件在线管理:File Browser

不同于群晖,Portainer 界面不会提供 Docker Hub 等仓库的搜索结果,需要手打镜像名称(分支)来引入。另外,创建容器时,Portainer 提供的选项远远丰富于群晖:例如,GPU 等硬件设备可以单独指定,毋须给予高权限即可调用。
群晖的文件同步功能非常实用;为替代之,选择 Nextcloud 及其依赖的 MySQL (MariaDB) 并安装。MariaDB 需要预先指定以下设置:

  • 环境变量:MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORD / MYSQL_ROOT_PASSWORD。前三者是初始数据库名称和用户,供 Nextcloud 使用;后者是数据库最高权限密码。
  • 命令行参数:--transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
  • 映射目录 /var/lib/mysql,存储数据库。
  • 分支:lts。无需跟进最新版本 latest
  • 主机名称(Hostname):mariadb

二者被划入独立的内联网络。Nextcloud 预先指定的设置有:

  • 环境变量:MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORD / MYSQL_HOST = 'mariadb'
  • 映射目录 /var/www/html,存储网页、凭证、同步文件夹等。(我说,就不能将同步文件和旁的东西分离?)

Gitea、Jellyfin 等应用设置与早前基本无异。其中,Jellyfin 和 Plex 单独指定 GPU /dev/dri/renderD128 以便转码,无需再赋予高权限。
如果在容器的环境变量中指定宿主用户 PUID 和用户组 PGID ,需要注意被映射的数据集/目录所有者要与设置一致,且有读写权限。这两项设置并非强制;大多数容器的设置当中并未指定用户(组)。在群晖系统,管理员帐户被赋予一切共享文件夹的读写权限,平时仅指定管理员帐户,故这个问题并不明显。

3.4.1 Jellyfin 运行表现

由于早前放弃了刮削好的数据库,这回要重新刮削,但好像主机 Hosts 设置没什么作用……
更新: 本文撰稿时,The Movie Database 等接口对应 IP 地址取自“站长之家”的海外测速服务,但这批 IP 似乎有被污染之嫌。通过外地在线 DNS 检索服务找到正确 IP,写入 /etc/hosts,并重启 Jellyfin 容器,即可使后者接收到。绝大多数影视剧刮削正常,此前以群晖系统作为宿主时不曾检索到集数的剧集也可以检索到了。
需人工检索 IP 地址的有:api.themoviedb.org api.thetvdb.com image.tmdb.org

转码表现相当出色,同一视频流和码率设置下,转码速率达 75 fps;相比之下,刚组装时测试的转码速率有 60 fps。原因可能有:

  1. 去年新补充 4GB 内存构成的双通道有性能增益。
  2. 新内核带来性能优化。

同时观察到转码产生的临时文件被均匀写入缓存池的两根 Optane。现在缓存池有约 21.3 GB 空间,以转码目标码率为 10 Mbps 计算,可存储约 12 小时的视频,那么可应付至少 4 部电影的转码视频流——堪称实用。

3.5 热备份和容灾设置

数据安全方面,TrueNAS 管理界面提供多种方案:数据清理、云同步、定期快照、Rsync 同步、复制和硬盘运行参数(SMART)检查。云同步支持较有限,仅有国外云服务商接口和 SFTP、WebDAV 等通用协议可用。联想个人云支持 WebDAV 挂载。最终作出以下安排:

  • 数据清理:所有存储池每月一次。(系统盘 boot-pool 在他处单独设置,默认每周一次。)
  • 云同步:通过 WebDAV 挂载联想个人云,同步文档、照片,每日一次。
  • 快照:Docker 容器数据和重要资料每日一次;前者保留两日,后者保留两周。
  • Rsync 同步:无。
  • 复制:Docker 容器数据和重要资料从固态盘、主存储池复制到热备份池,每日一次。
    • 群晖系统中,与“复制”相似的做法是设置一个定期运行 Rsync 的任务。
  • 硬盘运行参数检查:短检查每两周一次,长检查每四个月一次。

3.6 不间断电源支持

去年“双十一”,我购得硕天牌不间断电源(UPS)一台,群晖对其支持良好;网上资料称该品牌同样受 TrueNAS 支持。在“服务 - UPS”设置中选用 usbhid-ups 为驱动(型号任意),随后启动服务即可。

四、评价

作为推出两年有余的新分支(相对 Core 而言),TrueNAS Scale 在其最基本的用途——网络存储服务上是非常称职的;阵列冗余、数据保护、外地备份、SSH 公钥鉴权,应有尽有。但在其余方面,该系统似乎不大上心:例如在管理界面,“仪表板”上可见网络实时吞吐量是实际值的 8 倍(或为单位运用错误),以及线程由“零”起计;简体中文页面尚有多处未被翻译;Charts 和应用系统在大陆的可用性存疑,而 Docker 不再随新版系统预装;apt 被故意锁定;等等。尽管如此,其自由度仍远超群晖系统免授权亦使其不复有后顾之忧行百里者半九十;望再接再厉。

这也是首次尝试将多个 Optane 固态硬盘应用于资料服务器上。Optane 因耐久度高,用于缓存是非常合适的,但也需因地制宜;家用环境中鲜见并发访问和 iSCSI 这类并发应用,因此作为存储池的二级缓存作用有限;而作为独立的缓存池时,实用性更强,但也受制于容量,仅部分应用可从中受益。有大缓存之需时,要考虑采用企业级 NAND 固态盘产品。


五、后记

5.1 后记一:Docker 和系统升级

Scale 23.10.1.1 版本修复了仪表板上的网络吞吐量单位运用问题。但是!一次更新把 Docker 消灭了,再看“引导环境”,竟发现新旧版系统并存的模样,这也意味着新版不是在旧版基础上升级,而是安装了新的实例!我还是头一回见识如此“独特”的更新方式。幸好它保留了旧实例,回退成功。

由此可得出结论:如有通过命令行自行添置的服务,例如 Docker,切勿随意升级!

5.2 后记二:Alist 和移动云盘

就在一月 31 日,我蓦然发现,移动云盘每月可免费领取 1TB 空间额度(默认 20GB)。如此一来,零成本云存储就具备可行性了。早前已耳闻 Alist 可挂载国内外诸多云存储服务,遂引入。

抓取 xhofe/alist:latest 镜像,然后:

  1. 映射目录 /opt/alist/data,存储设置;
  2. 映射端口 5244,主机端必须一致,否则报 Unsafe Port 错误(这是什么鬼才设计);
  3. 确保指定的用户(组)具有存储目录的读写权限。

初次启动时,Alist 自动设置管理员帐户及密码,须进入其日志查看,而后自行更改。添加移动云盘非常便利,仅需提供 Cookies 字段之一 Authorization 以鉴权。如未指定“根文件夹 ID”,从主页进入会发现林林总总 18 项目录——这大约是移动云盘所提供的全部功能了。

指定“根文件夹”为“我的文件夹”对应数字序列(即 Payload 字段之一 catalogID)以后,便仅列出移动云盘主页所展示的文件。也许这样安全性还高些,毕竟通讯录这些东西过于敏感。
通过 WebDAV 挂载经 Alist 中转的移动云盘,即可以“云同步”方式备份文档及照片。电信网络中,同步过程充分利用了上行带宽。

其实,我也曾考虑引入对象存储服务。以阿里云为例,如采用“存档”类方案,现有照片、文档等每月仅需 3.5 元;但是,成本会随照片的增加而递增,当达到 250GB 以上的时候可能要考虑购买年包。此外,“存档”方案要求同一副本保留一定时间,否则追究其剩余时间的存储成本,故修改频繁的文档不适用于“归档”存储,而照片正合适。

5.3 后记三:未来展望

目前 Scale 正在如火如荼地迭代中。至四月,24.04 版本便会推出,届时我无疑将予以跟进。如后记一所述,我必将面临 Docker 服务和镜像迁移问题,当下拟定的计划是:

  1. 停止 Docker 服务,将镜像目录自 /var/lib/docker 迁移到 Cache 数据集;
  2. 更新系统;
  3. 在新实例下,借由 zfs 将镜像目录挂载至 /var/lib/docker
  4. 重新安装并启动 Docker 服务。

理论上,镜像和容器设置均得以保留,拭目以待罢。