低成本搭建一台家庭存储服务器:前篇

低成本搭建一台家庭存储服务器:前篇

本篇文章,记录搭建备份服务器的过程。

写在前面

今年考虑专门搭建一台用于数据备份的机器,一来今年外出的需求比较多,历史的设备已经用了几年了,需要有更新的设备来“接力”;二来也想验证方案的靠谱程度,解决我接触的一些生产环境的需求以及朋友们的问题。

因为之前已经买过好几台群晖了,加上今年群晖新品的 “CPU 升级” 非常“明智”,于是我决定自建一台。

最终成品

如果不计算硬盘和内存升级,整机连带 UPS 差不多 2000 块,除了能够充当文件服务器之外,还能运行虚拟机和 Docker 容器,相比群晖性价比还是高不少的。

需求明确

我希望这台设备能够满足以下几个诉求:

1.必须支持 macOS 系统的数据备份(时间机器),如果能够支持 Windows (生产环境中会有)就更好啦。2.至少有一种靠谱的方案来保障数据写入是正确可靠的。3.系统稳定可靠,三年五载的不需要额外的维护打理。4.体积相对小巧,运行起来没有噪音。5.不包含存储设备(硬盘、内存)成本相对较低,能够支持快速替换硬件来解决可用性问题。

除此之外提供的能力,都是“附加分”。

因为核心诉求其实是软件诉求,所以我们来看看软件方案。

操作系统和软件的选择

我倾向的方案是能够持续稳定运行,不会随意重启的 Linux 系统,或者基于 Linux 系统封装的 NAS 系统,最低的底限是我能够知道“samba”、“afp(netatalk)” 的程序版本,未来能够完成迁移。

本篇文章,我们先使用 Ubuntu 来完成基础的服务搭建。

为什么没有选择“白”或者“黑苹果”

在此之前,我分别使用 Mac 设备,和兼容 Mac 的硬件(包括这台 Elite Desk)运行 macOS,开启文件共享,做了“时间机器”的测试。

相比 Linux 协议兼容的开源软件 netatalk[1] ,确实稳定性高了不少,但是,如果选择使用白苹果,想要限制成本,那么容量就无法满足实际使用;如果选择黑苹果,即使优化配置到 99% 可用,总归觉得还有 1% 的不稳定因素,而我们并不知道这个 1% 的问题什么时候会“触发”,影响有多严重。况且,很有可能不确定性远大于 1%。

为什么没有选择 Windows

因为近几年,我没有主力使用 Windows,对于 Windows 的熟悉程度是不够的。并且,在最近一次的试验中,我发现非服务器版的 Windows 的长时间运行还是有一些问题的(我购入的是专业版的 Licenses)。

11 月末的时候,我入手了一台机器(Dell Optiplex),购入了正版的 Windows 11 ,系统上低负载运行了一款程序。在过去的两个月中,我遇到了跨系统“远程桌面”失效、毫无预兆的“自动”升级和重启,可能作为文件服务器来说,可靠性还需要进一步验证。

硬件方案选择

基于上面的需求,我将硬件选择范围锁定在了 HP EliteDesk 和 Dell Optiplex 两个系列里。经过对比,这次没有选择全新的设备,而是选择了二手市场上供给充沛的 Elite Desk。最终选择了一台 2021 年激活过,因为 2022 “环境变化”退出服役的二手的主机:EliteDesk 800G6 SFF(硬件规格[2])。

除了机箱有二次喷涂掩盖搬运时的暴力磕碰之外,用酒精擦外壳的时候能够看到喷涂的漆在快速挥发,会有点呛之外,基本没有什么槽点。(不消毒的话,不会触发这个事情,机器本身没气味)

我偷了个懒,选择了搭载 i3-10105T 的机器,成本在 1600 元左右,如果你手头有闲置的 CPU,可以入手 700~800 块左右的准系统。

为什么没有选择新款群晖

我连续购入了前两代的群晖产品 DS918+ 和 DS920+,但是对于 DS 923+,这款“升级到” AMD Ryzen 1600 的产品,实在提不起兴趣。

上文中提到的相对廉价的 i3-10105t CPU 规格[3]可以在 Intel 官网查询到,性价比显然高出不止一头。

为什么没有选择 Apple Time Capsule(时间胶囊)

苹果的时间胶囊

从外观来说,苹果的时间胶囊(技术规格[4])还是很好看的。但是,产品在 2018 年停产,如果硬件出现问题,通过购置相同硬件来完成服务恢复其实有点麻烦。加上产品即使停产,现在的价格也是小贵的,换起来心疼。

更关键的是,设备只能插一颗磁盘,设备本身算力也非常有限。

为什么没有选择阵列硬盘盒

常见品牌的硬盘阵列盒

如果我们已经有一台设备,并且不介意通过 USB 或者雷电数据线来进行数据交互的话,使用外置阵列硬盘盒未见得不是一个好的方案。这个方案最好的一点是,消费市场中硬盘盒的外观的可选性非常多。

不过,多数硬盘阵列盒不能直接提供服务,需要借助“宿主机”来提供服务,更不能运行一些我们想要运行的软件。而且,既然选择搭建一台设备,并且能够使用更靠谱直连主板的 SATA 线以及更可靠的主机电源,那么硬盘盒的方案的性价比也就不是很高了。何况这类设备的“溢价”非常高。

因为文章开头就“谢绝”了群晖,所以群晖的 “Expansion Unit” 也自然就不在讨论之列了啦。(而且也更贵)

为什么没有选择网络硬盘盒

不论是采用 ARMbian 还是 OpenWRT 的“盒子”,只要硬件靠谱,稳定性都是靠谱的,而且普遍成本低廉,能效比也非常高。

之所以没有选择这个方案,主要的顾虑在硬件可靠性方面,包括三部分:散热、IO能力、供电。

盒子类的设备一般是被动散热,所以如果和硬盘“同处一室”,难以保证有合理的温度,我不想这个备份服务器出现“散装 Style”;盒子类的产品考虑能耗和成本,所以 CPU 相对孱弱,IO 能力自然也就比较弱,跑满硬盘 IO 带宽基本不可能;盒子类的产品供电是带不动多块硬盘的,所以需要独立供电,或者需要和前文提到的能够独立供电的硬盘阵列盒组合使用,容易出现“小马拉大车”的情况。

成品的盒子,几年前我也买过 WD My Cloud 和群晖早些时候的 ARM 产品,就传输效率体验来说,个人体验来说真的不算太好。

准备工作

理论结束,轮到实践啦。

购置配件

我购置了上面这些硬件素材,分别有:

1.一台搭载了 CPU 的“准系统”,用于到手后测试“开箱即用”的测试主板和 CPU。2.一台新款的 APC UPS。3.4 根国产的光威 32G DDR4 内存。4.2 块 4T 的西数紫盘,用于数据存储和数据校验。5.一根国产的京造硬盘,用于存放操作系统,以及避免机械硬盘因为有程序运行无法休眠。6.一些配件:数据线和硬盘螺丝。

成本总计 5000 出头,工作功耗 27 瓦左右,总的来说还是比较爽的。当然,你也可以省掉内存升级和固态硬盘的部分,只选购硬件和 UPS ,只需要 2000 出头。

高扩展性的主板

主板的扩展性还不错,默认支持 3 块 SATA 硬盘和 2 块 NVMe 硬盘,4 根内存条,以及两个 PCI-e 插槽。完整的扩展能力,可以阅读上文中提到的“规格资料”。

BIOS 升级

机器到手后,推荐先做两件事,第一件是进入 BIOS ,重置选项为默认选项。第二件则是给机器插上网线,然后使用 BIOS 中的软件升级工具,将 BIOS 升级到最新,避免软件 BUG 和兼容性问题。

BIOS 升级过程

过程中,只有一点注意事项,不要断电,避免造成 BIOS 损坏。

插满内存

考虑到后续想在服务器上运行一些“空间换时间”的程序和虚拟机,我购置了 4 条 32G 的内存,减少分配资源时不必要的“小心翼翼”。

国产内存

插上之后,进入 BIOS ,能够看到正常识别。不过想要确认硬件正常,只是看信息是不够的,还需要进行硬件测试。

BIOS 识别信息

硬件测试

测试硬件需要使用多种方式,如果你的 BIOS 中有测试工具,将能省不少事。

硬件测试

如果你不放心,可以多测试几次,以及使用 PE 或者在完成系统安装之后,使用测试工具进行更持续的测试。

当然,除了一次性测试之外,在使用之前还要进行一些必要的稳定性测试,在实际使用之前,这台设备我通电运行了一周,没有出现意外的异常。

系统的安装和配置

系统待机状态

关于基础的系统安装、配置,可以参考这篇文章《在笔记本上搭建高性价比的 Linux 学习环境:基础篇》[5]

完成系统安装之后,我们还需要一些额外的配置,来让系统性能表现更好。

禁用 Swap

在 Ubuntu 中完全禁用和清理 Swap 需要三步,首先是关闭 Swap 功能:

sudo swapoff a

接着,编辑分区表文件 /etc/fstab,去掉 Swap 相关的记录。

然后,重启机器之后,删除掉“残余”文件即可。

rmrf /swapfile

当你完成上面的动作之后,我们使用 free -g 查看系统资源,就能够看到 Swap 可用量变为零啦:

# free -g               total        used        free      shared  buff/cache   availableMem:125112301123Swap:000

创建 Raid 1 镜像阵列

先使用 mdadm –examine 来检查机械硬盘的状态,检查两块目标硬盘是否容量一致。

# sudo mdadm –examine /dev/sda /dev/sdb/dev/sda:   MBR Magic: aa55Partition[0]:4294967295 sectors at            1(type ee)/dev/sdb:   MBR Magic: aa55Partition[0]:4294967295 sectors at            1(type ee)

接着,使用 sgdisk -R 将两个磁盘的分区表进行一致化处理:

sudo sgdisk /dev/sda /dev/sdb

复制完分区表之后,需要对其中一个磁盘的分区 UUID 进行刷新,避免操作系统在使用的时候出现问题。

sudo sgdisk /dev/sdb G

然后,使用 mdadm –create –level=mirror 创建次盘阵列:

# sudo mdadm –create /dev/md0 –level=mirror –raid-devices=2 /dev/sda /dev/sdbmdadm:/dev/sda appears to be part of a raid array:       level=raid1 devices=2 ctime=ThuJan520:47:302023mdadm: partition table exists on /dev/sda but will be lost or       meaningless after creating arraymdadm:Note: this array has metadata at the start and    may not be suitable as a boot device.If you plan to    store /boot on this device please ensure that    your bootloader understands md/v1.x metadata, or usemetadata=0.90mdadm: partition table exists on /dev/sdbmdadm: partition table exists on /dev/sdb but will be lost or       meaningless after creating arrayContinue creating array?Continue creating array?(y/n) ymdadm:Defaulting to version 1.2 metadatamdadm: array /dev/md0 started.

创建磁盘阵列需要等待一些时间,完成时间和你够买的磁盘的容量,以及磁盘和主板的数据传输协议,以及你的设备 CPU 算力都有关系。

我们可以随时通过 cat /proc/mdstat 来检查阵列构建进度:

# cat /proc/mdstatHPEliteDesk800G6SmallFormFactorPC:ThuJan521:50:562023Personalities:[raid1][linear][multipath][raid0][raid6][raid5][raid4][raid10]md0 : active raid1 sdb[1] sda[0]3906886464 blocks super 1.2[2/2][UU][=>……………….]  resync =9.6%(375538432/3906886464) finish=325.5min speed=180783K/sec      bitmap:28/30 pages [112KB],65536KB chunkunused devices:<none>

当阵列构建完成,我们再次检查 mdstat 的时候,能够看到类似下面的日志输出:

# sudo cat /proc/mdstatPersonalities:[raid1][linear][multipath][raid0][raid6][raid5][raid4][raid10]md0 : active raid1 sdb[1] sda[0]3906886464 blocks super 1.2[2/2][UU]      bitmap:0/30 pages [0KB],65536KB chunkunused devices:<none>

我们也可以使用 mdadm –detail 来查看阵列的详细信息:

# sudo mdadm –detail /dev/md0/dev/md0:Version:1.2CreationTime:ThuJan521:15:242023RaidLevel: raid1ArraySize:3906886464(3.64TiB4.00 TB)UsedDevSize:3906886464(3.64TiB4.00 TB)RaidDevices:2TotalDevices:2Persistence:Superblock is persistentIntentBitmap:InternalUpdateTime:FriJan623:29:382023State: clean ActiveDevices:2WorkingDevices:2FailedDevices:0SpareDevices:0ConsistencyPolicy: bitmapName:0              UUID : bd87e586:257740d3:5fd50282:ccc8b145Events:6144NumberMajorMinorRaidDeviceState0800      active sync/dev/sda18161      active sync/dev/sdb

中止阵列创建过程

如果你在构建过程中,因为一些原因,想停止构建,可以使用 idle 来中止构建,或者使用 frozen 来临时暂停任务。

echo idle >/sys/block/md0/md/sync_actionecho frozen >/sys/block/md0/md/sync_action

如果你希望完全重新建立阵列,可以使用下面的命令来恢复阵列前的状态:

sudo mdadm Esvsudo mdadm stop /dev/md*

在系统中使用磁盘阵列

完成阵列构建之后,想要使用磁盘阵列,首先得完成磁盘的挂载和磁盘的初始化(格式化)。

# sudo mkfs.ext4 /dev/md0mke2fs 1.46.5(30Dec2021)Discarding device blocks:doneCreating filesystem with 9767216164k blocks and 244187136 inodesFilesystem UUID: f7014dd5b7b1466cae422b49c43cbb57Superblock backups stored on blocks:32768,98304,163840,229376,294912,819200,884736,1605632,2654208,4096000,7962624,11239424,20480000,23887872,71663616,78675968,102400000,214990848,512000000,550731776,644972544Allocating group tables:doneWriting inode tables:doneCreating journal (262144 blocks):doneWriting superblocks and filesystem accounting information:done

将磁盘手动挂载到 /data 这个路径,我们可以这样做:

sudo mkdir/datasudo mount /dev/md0 /data

然后使用 df 来检查磁盘是否就绪:

# df -h /dataFilesystemSizeUsedAvailUse%Mounted on/dev/md0        3.6T28K3.4T1%/data

实际使用的时候,比如我们在这个分区上创建了一个文件后,磁盘会自动完成文件的镜像动作,提升文件的访问可靠性。

# touch /data/test.go# sudo mdadm –examine /dev/sda /dev/sdb/dev/sda:Magic: a92b4efcVersion:1.2FeatureMap:0x1Array UUID : bd87e586:257740d3:5fd50282:ccc8b145Name:0CreationTime:ThuJan521:15:242023RaidLevel: raid1RaidDevices:2AvailDevSize:7813772976 sectors (3.64TiB4.00 TB)ArraySize:3906886464KiB(3.64TiB4.00 TB)UsedDevSize:7813772928 sectors (3.64TiB4.00 TB)DataOffset:264192 sectorsSuperOffset:8 sectorsUnusedSpace: before=264112 sectors, after=48 sectorsState: cleanDevice UUID : da33683e:54478a8b:cd6fd10e:1a19114cInternalBitmap:8 sectors from superblockUpdateTime:FriJan623:29:142023BadBlockLog:512 entries available at offset 24 sectorsChecksum:5ad089e9 correctEvents:6144DeviceRole:Active device 0ArrayState: AA (A== active,.== missing,R== replacing)/dev/sdb:Magic: a92b4efcVersion:1.2FeatureMap:0x1Array UUID : bd87e586:257740d3:5fd50282:ccc8b145Name:0CreationTime:ThuJan521:15:242023RaidLevel: raid1RaidDevices:2AvailDevSize:7813772976 sectors (3.64TiB4.00 TB)ArraySize:3906886464KiB(3.64TiB4.00 TB)UsedDevSize:7813772928 sectors (3.64TiB4.00 TB)DataOffset:264192 sectorsSuperOffset:8 sectorsUnusedSpace: before=264112 sectors, after=48 sectorsState: cleanDevice UUID :577ef05f:fa66ff02:8e4085c0:03d798ecInternalBitmap:8 sectors from superblockUpdateTime:FriJan623:29:142023BadBlockLog:512 entries available at offset 24 sectorsChecksum:460982b8 correctEvents:6144DeviceRole:Active device 1ArrayState: AA (A== active,.== missing,R== replacing)

不过,上面手动挂载的磁盘,如果设备重启,将自动被释放。需要我们再次手动进行设备挂载。

想要解决这个问题,我们需要调整 fstab 中的内容,而 fstab 需要我们先获取阵列的“UUID”,以及更新 mdadm 的配置:

# sudo mdadm –detail –scan –verbose | sudo tee -a /etc/mdadm/mdadm.confARRAY /dev/md0 level=raid1 numdevices=2 metadata=1.2 name=0 UUID=bd87e586:257740d3:5fd50282:ccc8b145   devices=/dev/sda,/dev/sdb

获取 UUID 需要使用下面的命令,而不能直接使用 mdadm 输出的 ID:

# sudo dumpe2fs /dev/md0 |grep UUIDdumpe2fs 1.46.5(30Dec2021)Filesystem UUID:          f7014dd5b7b1466cae422b49c43cbb57

然后将下面的内容添加到 /etc/fstab 中:

UUID=f7014dd5b7b1466cae422b49c43cbb57/dev/md0   /mnt/mirror   ext4   defaults   00

搞定之后,更新 initramfs,然后重启设备,检查系统是否能够在启动时,正常挂载阵列分区到 /data 路径即可。

# sudo update-initramfs -uupdateinitramfs:Generating/boot/initrd.img5.15.057generic

安装文件服务

安装文件服务的方案有很多种,比如之前文章《装在笔记本里的私有云环境:网络存储篇(中)》[6]提到的 S3 替代品 MinIO 或者 Syncthing、NextCloud。

不过,为了让 Mac 、Windows 设备能够直接“原生”使用服务,并完成备份,我们可以考虑选择使用 samba 或者 netatalk 提供 smb 或 afp 协议的文件访问能力。如果你希望直接使用本地的 samba 或者 netatalk 程序,直接使用 apt install 即可:

sudo aptget install samba y

如果你觉得这样做不够环保,使用 docker 版本的 samba 或者 netatalk 也未尝不可。比如,Stanback/alpine-samba[7]

当然,用户管理(增加、停用、删除、改密)可能比较麻烦,不过基本都是一次性成本,或许还好。(也可能,再单独展开一篇文章更为合适)

当我们完成服务启动之后,就能够再网络中找到这台“存储服务器”了。

网络服务发现

以及使用 Samba 协议连接服务器。

使用 Samba 访问数据

接下来,如果你愿意的话,就可以直接使用系统自带的“时间机器”,来备份你的设备数据啦。

最后

因为最近比较忙,本篇文章“战线较长”大概经历了两周左右,过程中可能有一些疏漏,如果你有疑问或者建议,欢迎反馈。

下一篇文章中,我们来聊聊如何解决“管理资源”不方便的问题。

–EOF

引用链接

[1] 开源软件 netatalk: https://netatalk.sourceforge.io/

[2] 硬件规格: https://h20195.www2.hp.com/v2/getpdf.aspx/4aa7-7943enuc.pdf

[3] i3-10105t CPU 规格: https://www.intel.com/content/www/us/en/products/sku/201890/intel-core-i310105t-processor-6m-cache-up-to-3-90-ghz/specifications.html

[4] 技术规格: https://support.apple.com/kb/SP679?viewlocale=zh_CN&locale=zh_HK

[5] 《在笔记本上搭建高性价比的 Linux 学习环境:基础篇》: https://soulteary.com/2022/06/21/building-a-cost-effective-linux-learning-environment-on-a-laptop-the-basics.html

[6] 《装在笔记本里的私有云环境:网络存储篇(中)》: https://soulteary.com/2021/11/09/private-cloud-environment-installed-in-a-notebook-storage-part-2.html

[7] Stanback/alpine-samba: https://github.com/Stanback/alpine-samba

如果你觉得内容还算实用,欢迎点赞分享给你的朋友,在此谢过。

如果你想更快的看到后续内容的更新,请戳 “点赞”、“分享”、“喜欢” ,这些免费的鼓励将会影响后续有关内容的更新速度。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Proudly powered by WordPress | Theme: HoneyWaves by SpiceThemes