明确需求
- 无公网
IPv4
,仅公网IPv6
,需要外网访问 - 目前存储需求不强,且预算有限,硬盘组合是
10t+4t+4t+2t
,需要在保证冗余的同时提供灵活的扩展性 - 缓存加速,主要针对机械硬盘的小文件读写优化
- 手机文件同步,主要针对手机系统备份和录音
- 相册同步
- 需要具备基本的网络安全保障
- 按需扩展影音功能
解决方案
每条对应于上一节的需求:
- 使用
DDNS
,外网使用域名访问即可 - 存储上拆分
10t
的硬盘,4t+6t
组合作为校验盘,考虑到snapraid
的1
拖4
,可暂时先只用6t
做校验盘,4t
校验盘当数据盘使用,此时的数据盘为4t+4t+4t+2t
,其中一个4t
是10t
分出来的,本人情况是2t
的盘检测有错误,随时挂掉。这个分出来的4t
虽然有冗余但是和校验盘是同一个物理盘,冗余功能是无法保证的,禁止存放重要数据 - 缓存加速使用
bcache
,随便加了一块120G
的固态作为缓存盘 - 手机文件同步使用
nextcloud
,不用seafile
是因为后者免费版没有搜索功能至于阉割这种功能吗?这么抠搜 - 相册同步使用
immich
,目前应用开发活跃,更新较快,建议锁死版本使用 - 应用访问层面使用防火墙过滤访问源,系统的
ssh
使用key
登录 - 影音功能主要为
jellyfin
或者选择emby上述除了bcache
和snapraid
是系统层面的应用需要直接安装,其他应用全部使用docker
安装
存储配置
-
磁盘配置
-
LVM
拆分10t
硬盘(sdh)bash# 创建 pv,必须在创建 vg 前 sudo pvcreate /dev/sdh # 使用已有的 pv 创建 vg sudo vgcreate nas-vg /dev/sdh # 在 vg 中 创建 lv,大小为 40%,即 4t sudo lvcreate -n sp1 -l 40%FREE nas-vg # 在 vg 中 创建 lv,使用全部的剩余空间,即 6t sudo lvcreate -n sp2 -l 100%FREE nas-vg
操作完成后磁盘存储就是
6t+4t+4t+4t+2t
-
-
bcache
-
配置
bcache
bash# 安装 bcache sudo apt install bcache-tools # 清除原有磁盘,包括缓存盘和后端盘 sudo wipefs -a /dev/sdb # 缓存盘 sudo wipefs -a /dev/sdc # 后端盘 4t sudo wipefs -a /dev/sdd # 后端盘 4t sudo wipefs -a /dev/sde # 后端盘 2t sudo wipefs -a /dev/mapper/nas--vg-sp1 # 后端盘 4t # 创建关联 sudo make-bcache -C /dev/sdb -B /dev/sdc /dev/sdd /dev/sde /dev/mapper/nas-vg--sp1
上述操作执行完成后可以使用
sudo bcache-super-show /dev/sdc
查看各个盘,每个后端盘的cset.uuid
项都是/dev/sdb
的cset.uuid
即表示成功 -
磁盘分区
fdisk
无法对大于2t
的磁盘分区,因此统一使用parted
分区bashsudo parted /dev/mapper/nas--vg-sp2 # print 查看分区 mklabel gpt mkpart # start? 1M, end? 100%
分区后建立文件系统
bashsudo mkfs.xfs /dev/mapper/nas--vg-sp2
其他做了缓存加速的盘直接对
/dev/bcache{0}
建立文件系统即可 -
优化
bcache
bcache{0}
替换为实际的设备,可以使用lsblk
查看,cset.uuid
使用sudo bcache-super-show /dev/sdb
得到bash# 回写策略 sudo bash -c 'echo writeback > /sys/block/bcache{0}/bcache/cache_mode' # Let bcache completely sync with the hard drive,同步策略 sudo bash -c "echo 0 > /sys/block/bcache{0}/bcache/writeback_percent" # Don't let sequential IO bypass the cache,即所有读写都过缓存盘 # 可以更改为其他数值,默认4M,注意,只能传数字,单位是Byte,4M就是4194304 sudo bash -c "echo 0 > /sys/block/bcache{0}/bcache/sequential_cutoff" # 关闭拥塞控制,指定缓存盘的 cset.uuid,这个是检测读写延迟,大于该值就旁路缓存盘直写 sudo bash -c "echo 0 > /sys/fs/bcache/{cset.uuid}/congested_read_threshold_us" sudo bash -c "echo 0 > /sys/fs/bcache/{cset.uuid}/congested_write_threshold_us"
-
验证
bcache
bash# 先安装 fio sudo apt install fio # 随机读写 # 第一次执行时没有区别,因为没有缓存,第一次以后的结果才是有缓存加速后的速率 # 机械盘的4k随机读写大概在 300KB/s 左右,4k顺序读写大概 1MB/s 左右 # bcache 加速后,读写根据固态性能不同有差异, # 在垃圾固态上 4k 随机将近 5MB/s,4k 顺序大概 6MB/s # 4k 随机读写 sudo fio -filename=/dev/bcache3 -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=4k -size=5G -numjobs=30 -runtime=8 -group_reporting -allow_mounted_write=1 -name=mytest # 4k 顺序读写 sudo fio -filename=/dev/bcache3 -direct=1 -iodepth 1 -thread -rw=rw -ioengine=psync -bs=4k -size=5G -numjobs=30 -runtime=8 -group_reporting -allow_mounted_write=1 -name=mytest # 4M 随机读写,参考意义不大,默认的bcache在这个大小就旁路了,除非关闭了 sequential_cutoff sudo fio -filename=/dev/bcache3 -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=4m -size=5G -numjobs=30 -runtime=8 -group_reporting -allow_mounted_write=1 -name=mytest # 4k 顺序读写,参考意义不大,默认的bcache在这个大小就旁路了,除非关闭了 sequential_cutoff sudo fio -filename=/dev/bcache3 -direct=1 -iodepth 1 -thread -rw=rw -ioengine=psync -bs=4m -size=5G -numjobs=30 -runtime=8 -group_reporting -allow_mounted_write=1 -name=mytest
-
-
snapraid
由于
bcache
的配置需要清除分区,如果snapraid
在bcache
的下层,则每次添加磁盘后都需要清除分区,与预期不符,因此snapraid
只能在bcache
上层配置。-
安装
bash# ubuntu 20.04 apt 没法直接安装,ppa 源又连不上,只能手动安装 sudo apt install -y g++ make wget https://mirror.ghproxy.com/github.com/amadvance/snapraid/releases/download/v12.2/snapraid-12.2.tar.gz tar xf snapraid-12.2.tar.gz cd snapraid-12.2 ./configure make make check sudo make install
-
snapraid
配置bash# 编辑配置文件 # sudo touch /etc/snapraid.conf # sync过程自动保存Parity,单位是GB,感觉没什么必要 autosave 0 exclude *.unrecoverable exclude lost+found/ exclude aquota.user exclude aquota.group exclude /tmp/ exclude .content exclude *.bak exclude /snapraid.conf* exclude thumbs/ # 以实际挂载路径为准,这里使用DISK{A,B,C,D,E}指代 parity DISKA/snapraid.parity content DISKB/snapraid.content content DISKC/snapraid.content content DISKD/snapraid.content content DISKE/snapraid.content data d1 DISKB data d2 DISKC data d3 DISKD data d4 DISKE
配置完成后执行
sudo snapraid sync
即可开始第一次同步校验
-
-
mergerfs
配置完成后统一挂载路径,方便文件和路径的管理。
bash# 安装 mergerfs sudo apt install mergerfs # 磁盘挂载点,已经挂载的磁盘可不做处理,但建议路径有规律性 sudo mkdir /ponit2mountpoint/bcache{0,1,2,3} sudo mkdir /MFS # 编辑挂载配置文件,实现开机自动挂载 # sudo nano /etc/fstab # 注意:以下内容要在 /swap.img 所在的行之后 # ---fstab--start--- # <file systems> <dir> <type> <options> <dump> <pass> # 要挂载设备 位置 类型 默认即可 备份 fsk检查 /dev/bcache0 /srv/bcache0 xfs defaults /dev/bcache1 /srv/bcache1 xfs defaults /dev/bcache2 /srv/bcache2 xfs defaults /dev/bcache3 /srv/bcache3 xfs defaults # 分开挂载无效 /srv/bcache* /data fuse.mergerfs defaults,allow_other,minfreespace=10G,fsname=mergerfs,ignorepponrename=true 0 0 # ---fstab--end--- sudo mount -a # 更新挂载 df -TH # 查看结果 # defaults:开启以下 FUSE 参数以提升性能:atomic_o_trunc, auto_cache, big_writes, default_permissions, splice_move, splice_read, splice_write # allow_other:允许挂载者以外的用户访问 FUSE。你可能需要编辑 /etc/fuse.conf来允许这一选项 # use_ino:使用 mergerfs 而不是 libfuse 提供的 inode,使硬链接的文件 inode 一致 # minfreespace=10G:选择往哪个下层文件系统写文件时,跳过剩余空间低于 10G 的文件系统 # fsname=mergerfs:设置文件系统的名称为 mergerfs,也可以自定义其他名字如mount,df等 # ignorepponrename=true:重命名文件时,不再遵守路径保留原则,保持原来的存储路径
与
snapraid
一起使用时,多个盘有同名文件snapraid.content
,测试发现同名文件的策略为:mergerfs
路径的文件以磁盘加载顺序为准,显示的是第一个加载磁盘的文件,修改其他盘的同名文件,不会产生影响mergerfs
显示第一个加载磁盘的文件,在原始盘上删除该文件后,mergergs
中的文件列表不会更新,仍然为删除的文件内容- 经过上面的删除文件操作,打开
mergerfs
路径下的文件,修改并保存,内容会覆盖到位于顺序加载的下一个磁盘上的同名文件上
应用配置
应用全部使用docker,主打一个方便省心
-
docker
安装bashcurl -fsSL https://get.docker.com -o install.sh sed -i 's|download.docker.com|mirrors.ustc.edu.cn/docker-ce|g' install.sh sudo bash install.sh
免
root
配置bashsudo chown root:docker /var/run/docker.sock sudo groupadd docker # 添加docker用户组,安装docker后一般都已经存在 sudo gpasswd -a $USER docker # 将登陆用户加入到docker用户组中 newgrp docker # 更新用户组 docker ps # 测试docker命令是否可以正常使用
-
docker-compose
安装
版本不能太旧,否则后续如果需要nvidia
硬解环境时会无法启动bashsudo curl -L "https://mirror.ghproxy.com/github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/bin/docker-compose
-
docker
配置
编辑/etc/docker/daemon.json
文件,没有则新建bash{ "experimental": true, "ip6tables": true, "log-opts": { "max-size": "2m" }, "registry-mirrors": [ "https://docker.nju.edu.cn/" ] }
日志限制
2M
大小,开启IPv6
,镜像拉取使用南京大学镜像站加速,配置完后sudo systemctl restart docker
重启服务。开启IPv6
,主要是后期如果使用磁力相关的镜像下载东西时可以使用。 -
DDNS
实现外网域名访问
镜像:newfuture/ddns
docker-compose
配置:ymlversion: "3.7" services: ddns: image: newfuture/ddns@sha256:ac3a3942023ccc4f0d16df89ca945161caeec10ab3fd0291481119170ac7a6ea container_name: ddns restart: always volumes: - ${DDNS_CONFIG}:/config.json environment: Ali_Key: ${Ali_Key} Ali_Secret: ${Ali_Secret} network_mode: host
在
docker-compose.yml
目录下新建.env
文件,添加变量ini# 指向一个配置文件,该配置文件被newfuture/ddns镜像需要 DDNS_CONFIG=path/to/config.json
config.json
配置详情:json{ "$schema": "https://ddns.newfuture.cc/schema/v2.8.json", "id": "********", "token": "********", "dns": "alidns", "ipv4": [], "ipv6": ["www.example.com","example.com"], "index4": 0, "index6": "default", "ttl": null, "proxy": null, "debug": false }
上述文件根据实际情况填写,且
id
和token
较敏感,需要小心保存。更多配置详情可以参考官方说明。 准备完成后在docker-compose.yml
目录下执行docker-compose up -d
即可。
访问验证 :- 首先
docker logs ddns
查看日志,检查是否已经成功完成dns
解析,同时检查域名提供商比如阿里云中dns
是否已经有对应的dns
记录 - 在服务器不禁
ping
的前提下,在外网ping
域名,ping
通即可,因为各个dns
服务器之间数据刷新有延迟,dns
解析记录不是立即生效,需要稍等片刻。
- 首先
安全配置
每个人对安全的需求不同,这里安全配置进攻参考。
-
ssh
安全bashtouch ~/.ssh/authorized_keys # 编辑ssh配置 # sudo vi /etc/ssh/sshd_config PubKeyAuthentication yes // 取消注释,如果没有则新加 AuthorizedKeysFile .ssh/authorized_keys // 取消注释,如果没有则新加 PasswordAuthentication no // 取消注释,如果没有则新加 # 修改文件权限,重要 chmod 700 -R ~/.ssh/ chmod 600 ~/.ssh/authorized_keys # 重启ssh systemctl restart sshd
将需要连接的主机公钥添加至
authorized_keys
即可 -
应用安全 因为是纯
IPv6
环境,限制访问源即可,IPv6
的访问源有一定规律,这里提供部分地址特征ini电信公众宽带 240e:300::/24、240e:b00::/24 电信LTE网络 240e:400::/24 联通公众宽带 2408:8200::/23 联通LTE网络 2408:8400::/24 移动公众宽带 2409:8a00::/24 移动LTE网络 2409:8900::/24
在防火墙上仅放行上述
ip
的tcp
协议即可,icmp
按需放行。 如果是ip6tables
,以下命令仅供参考:bashsudo ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT sudo ip6tables -A INPUT -s 240e:300::/24,240e:b00::/24 -j ACCEPT -m comment --comment "电信宽带" sudo ip6tables -A INPUT -s 240e:400::/24 -j ACCEPT -m comment --comment "电信LTE" sudo ip6tables -A INPUT -s 2408:8200::/24 -j ACCEPT -m comment --comment "联通宽带" sudo ip6tables -A INPUT -s 2408:8400::/24 -j ACCEPT -m comment --comment "联通LTE" sudo ip6tables -A INPUT -s 2409:8a00::/24 -j ACCEPT -m comment --comment "移动宽带" sudo ip6tables -A INPUT -s 2409:8900::/24 -j ACCEPT -m comment --comment "移动LTE" sudo ip6tables -A INPUT -j DROP
完工
第1期配置到此结束,磁盘配置、缓存配置、挂载配置、应用配置和安全配置都在本期完成配置。NAS
的基础已经搭建完成,后续会继续添砖加瓦,将NAS
该有的功能都添加进去。本期的内容后续如果发现有遗漏,会继续补充。下一期开始基本就是应用的配置了,包括需求的4.5.7点。本期因为需要先将基础功能做好,因此这几点需求的配置分到下一期。