⚠️ 性能提示:确认 CPU 加速

ZFS 加密对 CPU 有一定要求。既然你用的是 Debian 13,请确认内核已经加载了 AES 硬件加速:

# 检查是否支持 AES-NI
grep -o aes /proc/cpuinfo | head -n 1

如果输出 aes,那么开启加密对性能的影响几乎可以忽略不计。

一、 新建zfs pool(带 4K 优化 + 原生加密)

执行:

  1. 销毁旧池【重建-视情况可选】

    zpool destroy myzfs
  2. 重新创建,开启 4K 优化、原生加密、并设置交互式密码

    zpool create -f -o ashift=12 \
     -O encryption=on \
     -O keyformat=passphrase \
     -O keylocation=prompt \
     -O compression=lz4 \
     -O xattr=sa \
     -O acltype=posixacl \
     myzfs /dev/vda4

执行说明:

  • encryption=on:开启 AES-256-GCM 加密。
  • keyformat=passphrase:使用“密码”作为钥匙(最安全,重启后需手动输入)。
  • keylocation=prompt:创建时会立即提示你输入并确认密码。

二、 进阶:如果你不想要“手动输入密码”

在 VPS 环境下,如果你希望机器重启后 ZFS 能够自动挂载(不需要每次 SSH 进去解锁),你可以改用 Keyfile(密钥文件) 模式。

操作方法:

  1. 在根分区生成钥匙文件:
dd if=/dev/urandom of=/etc/zfs/myzfs.key bs=32 count=1
  1. 设置权限

    chmod 600 /etc/zfs/myzfs.key
  2. 创建

    zpool create -f -o ashift=12 \
     -O encryption=on \
     -O keyformat=raw \
     -O keylocation=file:///etc/zfs/myzfs.key \
     -O compression=lz4 \
     -O xattr=sa \
     -O acltype=posixacl \
     myzfs /dev/vda4

为什么这三项不可或缺?

参数作用对你的好处
compression=lz4LZ4 无损压缩变相提速: CPU 压缩比硬盘写入快得多,压缩后写入的数据变少,变相提升了你的磁盘带宽,同时节省空间。
xattr=sa系统属性优化极大提升 IOPS: 默认模式下 ZFS 存文件属性(如权限、时间戳)会产生额外的隐藏文件。sa 模式直接存入 Inode,读写小文件速度翻倍。
acltype=posixacl开启 POSIX ACL兼容性保证: 很多 Linux 软件(特别是容器镜像)需要这种标准的权限控制,不开启可能会导致某些服务启动报错。

在 2026 年的 Proxmox VE 运维实践中,这三项被视为 “必选装”。

如果不加它们,你的 ZFS 池会以默认的非压缩、低效扩展属性模式运行,这在处理大量小文件(如容器、日志、虚拟机快照)时会有明显的性能差距。


执行后的关键检查

运行完上面的命令后,建议执行以下两步确认一切完美:

  1. 确认属性已生效:

    zfs get compression,encryption,ashift,xattr,acltype myzfs
  2. 测试重启自动加载(非常重要):
    由于你把密钥放在了 /etc/zfs/myzfs.key,虽然它在已解密的根分区里,但 ZFS 启动脚本可能早于挂载点。

    • 运行:zpool export myzfs
    • 运行:zpool import myzfs
    • 运行:zfs load-key myzfs (如果提示 Key loaded 就成功了)

  3. 如果路径不匹配,请用这条命令修正属性:

    zfs set keylocation=file:///--root--/zfs/myzfs.key myzfs
  4. 挂载数据 (Mount)

    加载完密钥后,手动挂载:

    zfs mount myzfs

    由于你的根分区(/)已经通过 LUKS 加密了,所以把 ZFS 的钥匙放在 /etc 里是安全的——只要 LUKS 没解开,别人也拿不到这把钥匙。


三、 如果你不追求“全池加密”,只想加密一部分

如果你觉得重做整个池太麻烦,其实还有一个折中方案:在现有的非加密池里,创建一个加密的子集(Dataset)。

# 在不加密的 myzfs 池里,创建一个加密的子文件夹
zfs create -o encryption=on -o keyformat=passphrase myzfs/private
  • 优点: 不需要重做池。
  • 缺点: myzfs 根目录下的元数据(如有哪些子集、空间占用情况)依然是可见的。对于 PVE 存储来说,通常建议全池加密更清爽。


💡 自动化方案:让它随系统启动解锁

由于你的根分区(/)已经是 LUKS 加密的,只要系统能启动到登录界面,说明根分区已经解密。可以通过一个简单的 Systemd 服务,在开机时自动解开ZFS 空间。

首先:告诉 ZFS 钥匙在哪里
你需要先在终端执行这条命令,把路径“刻”在你的 myzfs 池子上:
注意 file:// 后面接的是你的绝对路径

zfs set keylocation=file:///root/zfs/myzfs.key myzfs

验证是否设置成功: 执行

zfs get keylocation myzfs

应该显示available和路径,就说明 ZFS 已经记住它了。

创建一个systemd服务:

  1. 新建服务文件:
    nano /etc/systemd/system/zfs-load-key.service
  2. 粘贴以下内容:

    [Unit]
    Description=Load ZFS encryption keys
    DefaultDependencies=no
    After=zfs-import.target
    Before=zfs-mount.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    # 确保路径指向你实际的 key 文件
    ExecStart=/sbin/zfs load-key -a
    StandardOutput=journal+console
    StandardError=journal+console
    
    [Install]
    WantedBy=zfs-mount.service
  3. 启用服务:

    systemctl daemon-reload && \
    systemctl enable zfs-load-key.service


💡 下一步配置 PVE 存储

当你这个池子建好并加密后,你需要让 Proxmox VE 认出它。请在 PVE 的 Web 界面或命令行中执行:

# 将该 ZFS 池添加到 PVE 存储配置中
pvesm add zfspool myzfs_storage --pool myzfs --content images,rootdir --sparse 1

注:--sparse 1 开启精简配置(稀疏模式)这样虚拟机占多少空间才计多少空间

验证整个流程是否通畅

在重启之前,你可以做一次“实战模拟”:

  1. 卸载并锁定:
    zfs unmount myzfs
    zfs unload-key myzfs
  2. 检查状态:
    zfs get keystatus myzfs(应该显示 unavailable)
  3. 运行你的服务:
    systemctl start zfs-load-key.service
  4. 再次检查:
    zfs get keystatus myzfs(如果变成 available,说明大功告成!)