一直在寻找适合自己的 NAS 存储方案,也做过一些尝试,可总有些不完美的点。
最近终于找到一个接近完美的方案:Hyper-V + NFS + openmediavault
思路
我对 NAS 几点硬性要求
- 能支持 NTFS 文件系统,否则现有数据迁移成本很高
- 文件共享必须支持回收站,否则数据易丢失
- 文件检索要方便
所以之前一直用 windows 作为 NAS 系统,最大的问题是不支持共享文件夹的回收站。
现有 NAS 方案的对比
good | bad | |
---|---|---|
windows smb | 性能 | 无法扩展功能(如smb回收站,timemachine) |
wsl1 samba | 性能略低于smb,功能可扩展 | 部分共享文件无法打开, 配置略繁琐 |
wsl2 samba(omv) | 功能可扩展 | 无法解决桥接网络,需要更好的cpu |
nfs | 性能最强 | 无法扩展功能 |
群晖 / OMV / FreeNAS | 功能多,功能可扩展 | 无法管理底层文件 |
windows + nfs + vmware(群晖) | 可管理底层文件,功能可扩展 | 物理机休眠虚拟机无法唤醒 |
windows + nfs + hyper-v(omv) | 功能可扩展,性能接近smb,可休眠 | 需要更好的cpu,hyperv使用略繁琐 |
本方案的思路受之前文章的启发 在WSL2中安装openmediavault(OMV)
WSL2 的便利之处在于让 linux 系统能以一个足够快的速度访问 windows 文件,据了解是使用 9p(Plan 9 9p remote filesystem protocol) 协议进行文件共享。
那么我们只要在 Hyper-V 上运行虚拟机,并通过某种方式(这里选择NFS)共享文件到虚拟机里,就能绕开 WSL2 的缺点。
实现 NAS 的底层文件系统由 windows 管理, 上层文件共享等应用由虚拟机中的 NAS 系统处理,兼顾了稳定性和扩展性。
方案
软件环境选择
- windows 10 21H1
- haneWIN NFS server 1.2.59
- openmediavault
Windows 10 安装及配置
- 设置开机自动登录用户(可选): https://zhuanlan.zhihu.com/p/61262940
- 禁止自动从睡眠中唤醒(可选): 控制面板 -> 电源选项 -> 更改计划设置 -> 更改高级计划设置 -> 睡眠 -> 允许使用睡眠唤醒定时器(禁用)
- 启用 Hyper-V:
DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V
- Hyper-V 配置桥接网络:虚拟交换机管理器 -> 新建虚拟网络交换机(外部)
- 安装 haneWIN NFS server 并配置需要共享的硬盘
openmediavault 安装及配置
- 创建 Hyper-V 虚拟机:选择第一代,选择桥接网卡,虚拟硬盘需挂载到 IDE 控制器
- 挂载安装镜像,安装 openmediavault 系统
安装 omv-extras
1
wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | bash
安装插件:openmediavault-sharerootfs(共享系统分区的文件夹) openmediavault-remotemount(远程挂载)
- 挂载 NFS 共享:存储器 -> 远程挂载
- 建立共享文件夹: 选择系统分区上的 NFS 挂载文件夹
- 启用smb共享
- 关闭虚拟机,并配置虚拟机的网卡为静态MAC地址(如果是导入的虚拟机,注意检查MAC地址是否合法)
其他优化配置
samba 性能优化
配置页面:服务 -> SMB/CIFS -> 设置 -> 高级设置 -> 扩展选项
1 | veto files = /.Trashes/$RECYCLE.BIN/System Volume Information/.recycle/ |
samba 回收站优化
默认的回收站不能按天对文件进行分类,不方便进行清理
配置页面:服务 -> SMB/CIFS -> 共享 -> 共享文件夹
启用回收站选项,并在扩展选项中增加
1 | recycle:repository = .recycle/%U/today |
配置页面:系统 -> 计划任务
增加共享文件夹回收站整理脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
set -x -e
BASE=/srv/nfs_root
TODAY=$(date +'%Y%m%d')
USERS=(
data
)
# read -r -a USERS <<< $(groupmems -g users -l)
cd $BASE
for share in $(ls); do
for user in ${USERS[@]}; do
rec="$BASE/${share}/.recycle/$user"
if [[ ! -d $rec ]]; then
mkdir -p $rec
fi
cd $rec
if [[ ! -d $TODAY ]]; then
mkdir $TODAY
fi
if [[ -L today || -f today ]]; then
rm -f today
elif [[ -d today ]]; then
mv today $TODAY/$(date +'bak.%s')
fi
ln -s ./$TODAY today
done
done
windows 系统中,增加定时任务,删除NFS共享目录中的回收站文件到系统回收站
Python 代码如下,超过一定时间的文件会被送到 windows 回收站
1 | import time |
其他
也可考虑将上文 openmediavalut 替换成黑群晖系统,牺牲定制化能力的同时大大增加易用性。
当然,你也可以两者双修