将你的 Raspberry Pi 家庭实验室变成网络文件系统

使用 NFS 服务器将共享文件系统添加到你的家庭实验室。
176 位读者喜欢这篇文章。
5 tools to support distributed sysadmin teams

Opensource.com

共享文件系统是为家庭实验室增加多功能性和功能的好方法。拥有集中式的文件系统共享给实验室中的客户端可以更容易地组织数据、进行备份和共享数据。这对于跨多个服务器进行负载平衡的 Web 应用程序以及 Kubernetes 使用的持久卷特别有用,因为它允许在任意数量的节点上启动具有持久数据的 Pod。

无论你的家庭实验室是由普通计算机、剩余的企业服务器还是 Raspberry Pi 或其他单板计算机 (SBC) 组成,共享文件系统都是一种有用的资产,而网络文件系统 (NFS) 服务器是创建它的好方法。

我之前写过关于在家设置“私有云”的文章,该家庭实验室由 Raspberry Pi 或其他 SBC 以及一些其他消费类硬件或台式 PC 组成。 NFS 服务器是在这些组件之间共享数据的理想方式。由于大多数 SBC 的操作系统 (OS) 在 SD 卡上运行,因此存在一些挑战。 SD 卡更容易出现故障,尤其是在用作计算机的 OS 磁盘时,并且它们并非设计为持续读取和写入。 你真正需要的是真正的硬盘驱动器:它们通常比 SD 卡每 GB 更便宜,尤其是对于较大的磁盘,并且它们不太可能持续出现故障。 Raspberry Pi 4 现在配备了 USB 3.0 端口,并且 USB 3.0 硬盘驱动器无处不在且价格实惠。 这是一个完美的搭配。 对于本项目,我将使用插入运行 NFS 服务器的 Raspberry Pi 4 的 2TB USB 3.0 外部硬盘驱动器。

安装 NFS 服务器软件

我正在 Raspberry Pi 上运行 Fedora Server,但本项目也可以使用其他发行版完成。 要在 Fedora 上运行 NFS 服务器,你需要 nfs-utils 软件包,幸运的是它已经安装(至少在 Fedora 31 中)。 如果你计划运行 NFSv3 服务,你还需要 rpcbind 软件包,但 NFSv4 并非强制要求。

如果你的系统上尚未安装这些软件包,请使用 dnf 命令安装它们

# Intall nfs-utils and rpcbind
$ sudo dnf install nfs-utils rpcbind

Raspbian 是另一种与 Raspberry Pi 一起使用的流行操作系统,并且设置几乎完全相同。 软件包名称不同,但这是唯一的主要区别。 要在运行 Raspbian 的系统上安装 NFS 服务器,你需要以下软件包

  • nfs-common: 这些文件对于 NFS 服务器和客户端是通用的
  • nfs-kernel-server: 主要 NFS 服务器软件包

Raspbian 使用 apt-get 进行软件包管理(而不是像 Fedora 那样使用 dnf),因此请使用它来安装软件包

# For a Raspbian system, use apt-get to install the NFS packages
$ sudo apt-get install nfs-common nfs-kernel-server

准备一个 USB 硬盘驱动器作为存储

正如我在上面提到的,USB 硬盘驱动器是为 Raspberry Pi 或其他 SBC 提供存储的好选择,尤其是因为用于 OS 磁盘映像的 SD 卡并不理想。 对于你的家庭私有云,你可以使用廉价的 USB 3.0 硬盘驱动器进行大规模存储。 插入磁盘并使用 fdisk 找出分配给它的设备 ID,以便你可以使用它。

# Find your disk using fdisk
# Unrelated disk content omitted
$ sudo fdisk -l

Disk /dev/sda: 1.84 TiB, 2000398933504 bytes, 3907029167 sectors
Disk model: BUP Slim BK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe3345ae9

Device     Boot Start        End    Sectors  Size Id Type
/dev/sda1        2048 3907028991 3907026944  1.8T 83 Linux

为了清楚起见,在上面的示例输出中,我省略了除我感兴趣的磁盘之外的所有磁盘。 你可以看到我想要使用的 USB 磁盘被分配了设备 /dev/sda,你可以看到有关模型的 一些信息(Disk model: BUP Slim BK),这有助于我识别正确的磁盘。 该磁盘已经有一个分区,并且其大小确认它是我要查找的磁盘。

注意: 确保识别你设备的正确磁盘和分区。 它可能与上面的示例不同。

在驱动器上创建的每个分区都会获得一个特殊的通用唯一标识符 (UUID)。 计算机使用 UUID 来确保它使用 /etc/fstab 配置文件将正确的分区挂载到正确的位置。 你可以使用 blkid 命令检索分区的 UUID

# Get the block device attributes for the partition
# Make sure to use the partition that applies in your case.  It may differ.
$ sudo blkid /dev/sda1

/dev/sda1: LABEL="backup" UUID="bd44867c-447c-4f85-8dbf-dc6b9bc65c91" TYPE="xfs" PARTUUID="e3345ae9-01"

在本例中,/dev/sda1 的 UUID 是 bd44867c-447c-4f85-8dbf-dc6b9bc65c91。 你的将有所不同,因此请记下它。

配置 Raspberry Pi 以在启动时挂载此磁盘,然后挂载它

现在你已经识别了要使用的磁盘和分区,你需要告诉计算机如何挂载它,以便在每次启动时都这样做,并立即挂载它。 由于这是一个 USB 磁盘,可能会被拔掉,因此你还将配置 Raspberry Pi 在磁盘未插入或以其他方式不可用时不要等待启动。

在 Linux 中,这是通过将分区添加到 /etc/fstab 配置文件来完成的,包括你希望将其挂载到的位置以及一些参数来告诉计算机如何处理它。 本示例将分区挂载到 /srv/nfs,因此首先创建该路径

# Create the mountpoint for the disk partition
$ sudo mkdir -p /srv/nfs

接下来,使用以下语法格式修改 /etc/fstab 文件

<disk id>     <mountpoint>      <filesystem type>     <options>     <fs_freq> <fs_passno>

使用你之前确定的磁盘 ID 的 UUID。 正如我在前面的步骤中提到的,挂载点是 /srv/nfs。 对于文件系统类型,通常最好选择实际的文件系统,但由于这将是一个 USB 磁盘,因此请使用 auto

对于选项值,请使用 nosuid,nodev,nofail

关于 man 手册的题外话

也就是说,有很多可能的选项,而手册 (man) 页面是查看它们的最佳方式。 调查 fstab 的 man 页面是一个好的开始

# Open the man page for fstab
$ man fstab

这将打开与 fstab 命令关联的手册/文档。 在 man 页面中,每个选项都被分解以显示它的作用以及常见的选择。 例如,第四个字段 (fs_mntopts) 提供有关在该字段中使用的选项的一些基本信息,并引导你到 man (8) mount 以获取更深入的挂载选项说明。 这是有道理的,因为 /etc/fstab 文件本质上告诉计算机如何自动挂载磁盘,就像你手动使用 mount 命令一样。

你可以从 mount 的 man 页面获取有关你将使用的选项的更多信息。 括号中的数字 8 表示 man 页面部分。 在本例中,第 8 节用于系统管理工具和守护程序

有帮助的是,你可以从 man 的 man 页面获取标准部分的列表。

回到挂载磁盘,查看 man (8) mount

# Open Section 8 of the man pages for mount
$ man (8) mount

在此 man 页面中,你可以检查上面列出的选项的作用

  • nosuid: 不要遵守 suid/guid 位。 不允许任何可能在 USB 磁盘上的文件作为 root 执行。 这是一个很好的安全实践。
  • nodev: 不要解释文件系统上的字符或块特殊设备; 也就是说,不要遵守任何可能在 USB 磁盘上的设备节点。 另一个好的安全实践。
  • nofail: 如果设备不存在,请勿记录任何错误。 这是一个 USB 磁盘,可能未插入,因此在这种情况下将被忽略。

返回到你正在添加到 /etc/fstab 文件的行,还有两个最终选项:fs_freqfs_passno。 它们的值与有些遗留选项相关,并且大多数现代系统都只对两者使用 0,尤其是对于 USB 磁盘上的文件系统。 fs_freq 值与 dump 命令和创建文件系统的转储有关。 fs_passno 值定义了在启动时要 fsck 的文件系统及其顺序。 如果设置了它,通常根分区将为 1,任何其他文件系统将为 2。 将该值设置为 0 以跳过在此分区上使用 fsck

在你喜欢的编辑器中,打开 /etc/fstab 文件并添加 USB 磁盘上分区的条目,用在先前步骤中收集的值替换此处的值。

# With sudo, or as root, add the partition info to the /etc/fstab file
UUID="bd44867c-447c-4f85-8dbf-dc6b9bc65c91"    /srv/nfs    auto    nosuid,nodev,nofail,noatime 0 0

启用并启动 NFS 服务器

安装了软件包并将分区添加到你的 /etc/fstab 文件后,你现在可以继续并启动 NFS 服务器。 在 Fedora 系统上,你需要启用并启动两个服务:rpcbindnfs-server。 使用 systemctl 命令来完成此操作

# Start NFS server and rpcbind
$ sudo systemctl enable rpcbind.service
$ sudo systemctl enable nfs-server.service
$ sudo systemctl start rpcbind.service
$ sudo systemctl start nfs-server.service

在 Raspbian 或其他基于 Debian 的发行版上,你只需要使用与上面相同的方式使用 systemctl 命令启用并启动 nfs-kernel-server 服务。

RPCBind

rpcbind 实用程序用于将远程过程调用 (RPC) 服务映射到它们侦听的端口。 根据 rpcbind man 页面

“当启动 RPC 服务时,它会告诉 rpcbind 它正在侦听的地址,以及它准备提供的 RPC 程序号。 当客户端希望对给定的程序号进行 RPC 调用时,它首先联系服务器机器上的 rpcbind 以确定应该将 RPC 请求发送到的地址。”

对于 NFS 服务器,rpcbind 将 NFS 的协议号映射到 NFS 服务器正在侦听的端口。 但是,NFSv4 不需要使用 rpcbind。 如果你使用 NFSv4(通过从配置中删除版本二和三),则不需要 rpcbind。 我在这里包含它是为了与 NFSv3 向后兼容。

导出已挂载的文件系统

NFS 服务器根据另一个配置文件 /etc/exports 决定将哪些文件系统与哪些远程客户端共享(导出)。 此文件只是主机互联网协议 (IP) 地址(或子网)与要共享的文件系统以及一些选项(只读或读写、root squash 等)的映射。 该文件的格式为

<directory>     <host or hosts>(options)

在本例中,你将导出挂载到 /srv/nfs 的分区。 这是“目录”部分。

第二部分,主机,包括你想要将此分区导出到的主机。 这些可以指定为具有完全限定域名或主机名的单个主机、主机的 IP 地址、使用通配符来匹配域的多个主机(例如,*.example.org)、IP 网络(例如,无类别域间路由或 CIDR 表示法)或网络组。

第三部分包含应用于导出的选项

  • ro/rw: 以只读或读写方式导出文件系统
  • wdelay: 如果即将发生另一次写入,则延迟写入磁盘,以提高性能(如果使用的是固态 USB 磁盘,这可能不是很有用)
  • root_squash: 阻止客户端上的任何 root 用户拥有主机上的 root 访问权限,并将 root UID 设置为 nfsnobody 作为安全预防措施

测试将你在 /srv/nfs 挂载的分区导出到单个客户端,例如笔记本电脑。确定客户端的 IP 地址(我笔记本电脑的是 192.168.2.64,但你的可能不同)。 你可以将其共享到大型子网,但为了测试,请将其限制为单个 IP 地址。 仅此 IP 的 CIDR 表示法为 192.168.2.64/32; /32 子网只是一个 IP。

使用你喜欢的编辑器,使用你的目录、主机 CIDR 以及 rwroot_squash 选项编辑 /etc/exports 文件

# Edit your /etc/exports file like so, substituting the information from your systems
/srv/nfs    192.168.2.64/32(rw,root_squash)

注意:如果从其他位置复制 /etc/exports 文件,或者以其他方式使用副本覆盖了原始文件,则可能需要恢复该文件的 SELinux 上下文。 你可以使用 restorecon 命令执行此操作

# Restore the SELinux context of the /etc/exports file
$ sudo restorecon /etc/exports

完成此操作后,重新启动 NFS 服务器以获取对 /etc/exports 文件的更改

# Restart the nfs server
$ sudo systemctl restart nfs-server.service

为 NFS 服务打开防火墙

默认情况下,某些系统不运行防火墙服务。 例如,Raspbian 默认为打开的 iptables 规则,不同的服务打开的端口可立即从机器外部访问。 相比之下,Fedora 服务器默认运行 firewalld 服务,因此你必须为 NFS 服务器(以及 rpcbind,如果你将使用 NFSv3)打开端口。 你可以使用 firewall-cmd 命令执行此操作。

检查 firewalld 使用的区域并获取默认区域。 对于 Fedora Server,这将是 FedoraServer 区域

# List the zones
# Output omitted for brevity
$ sudo firewall-cmd --list-all-zones

# Retrieve just the default zone info
# Make a note of the default zone
$ sudo firewall-cmd --get-default-zone

# Permanently add the nfs service to the list of allowed ports
$ sudo firewall-cmd --add-service=nfs --permanent

# For NFSv3, we need to add a few more ports, nfsv3, rpc-mountd, rpc-bind
$ sudo firewall-cmd --add-service=(nfs3,mountd,rpc-bind)

# Check the services for the zone, substituting the default zone in use by your system
$ sudo firewall-cmd --list-services --zone=FedoraServer

# If all looks good, reload firewalld
$ sudo firewall-cmd --reload

这样,你已经成功配置了带有已挂载 USB 磁盘分区的 NFS 服务器,并将其导出到你的测试系统以进行共享。 现在你可以测试将其挂载在你添加到导出列表中的系统上。

测试 NFS 导出

首先,从 NFS 服务器,在 /srv/nfs 目录中创建一个文件以供读取

# Create a test file to share
echo "Can you see this?" >> /srv/nfs/nfs_test

现在,在你添加到导出列表中的客户端系统上,首先确保已安装 NFS 客户端软件包。 在 Fedora 系统上,这是 nfs-utils 软件包,可以使用 dnf 安装。 Raspbian 系统具有 libnfs-utils 软件包,可以使用 apt-get 安装。

安装 NFS 客户端软件包

# Install the nfs-utils package with dnf
$ sudo dnf install nfs-utils

安装客户端软件包后,你可以测试 NFS 导出。 再次在客户端上,使用带有 NFS 服务器的 IP 和导出路径的 mount 命令,并将其挂载到客户端上的位置,对于此测试,该位置是 /mnt 目录。 在此示例中,我的 NFS 服务器的 IP 是 192.168.2.109,但你的可能不同

# Mount the export from the NFS server to the client host
# Make sure to substitute the information for your own hosts
$ sudo mount 192.168.2.109:/srv/nfs /mnt

# See if the nfs_test file is visible:
$ cat /mnt/nfs_test
Can you see this?

成功! 你现在有一个适用于你的家庭实验室的正在运行的 NFS 服务器,可以与多个主机共享文件、允许多读/写访问,并为你的数据提供集中式存储和备份。 有许多用于家庭实验室的共享存储选项,但 NFS 是古老、高效且可添加到你的“家庭私有云”家庭实验室中的绝佳选择。 本系列中的后续文章将扩展如何自动在客户端上挂载 NFS 共享,以及如何使用 NFS 作为 Kubernetes 持久卷的存储类。

接下来阅读什么
标签
Chris Collins
Chris Collins 是 Red Hat 的 SRE 和 OpenSource.com 的记者,对自动化、容器编排及其周围的生态系统充满热情,并且喜欢在家中娱乐地重新创建企业级技术。

10 条评论

很棒的文章,非常有用的教程!

很好地使你的所有文件可供 ISP 路由器访问...

你可以将导出列表限制为仅你想挂载共享的主机。 如果你担心路由器正在跟踪传输中的流量,那无论如何都是一个更大的问题。 在我自己的实验室中,我有自己的路由器处理网络,而 ISP 路由器只处理进出网络的流量。

回复,作者:Tuga(未经验证)

我的系统设置是这样的,除了我通过 sshfs 在客户端上挂载 nfs 共享....不知道它可以直接挂载...以这种方式挂载更好吗?

我不确定我是否理解你的设置方式。 如果你使用 sshfs,那么 NFS 共享的用途是什么?

无论如何,使用适合你的方法! 我两种都做过。 使用 sshfs,即使使用你的网络,你也可以获得加密的好处。 我认为 NFS 更易于管理。 它们都有好处。

回复,作者:Poul Kalff(未经验证)

很棒的教程,但 nfs 不是云。

我同意。 这将是 Kubernetes 集群动态卷配置器的基础,以模拟在主要云提供商中如何为 k8s 配置卷。 它将结合在一起。

回复,作者:123689(未经验证)

感谢你提供的信息。 它阐明了一些问题。

有没有办法让 Raspberry Pi 在磁盘不使用时停止旋转? 一般来说,有没有办法最大限度地减少这种设置中的功耗?

我没有研究过尝试停止驱动器旋转,但这是一个好主意。 我有兴趣听听你或可能正在阅读此内容的其他人最终做了些什么,以使用带有 Raspberry Pi 的 USB 磁盘来节省电量。

回复,作者:Steve Izma(未经验证)

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.