将你的 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 卡每千兆字节更便宜,尤其是在较大的磁盘上,并且它们不太可能出现故障。 Raspberry Pi 4 现在配备了 USB 3.0 端口,USB 3.0 硬盘驱动器无处不在且价格实惠。 这是一个完美的匹配。 对于这个项目,我将使用插入 Raspberry Pi 4 的 2TB USB 3.0 外部硬盘驱动器,运行 NFS 服务器。

安装 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>

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

对于 options 值,请使用 nosuid,nodev,nofail

关于 man 页面的题外话

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

# Open the man page for fstab
$ man fstab

这将打开与 fstab 命令相关的手册/文档。 在 man 页面中,每个选项都被分解以显示它的作用和常见的选择。 例如,The fourth field (fs_mntopts) 给出了一些关于在该字段中起作用的选项的基本信息,并指导你查阅 man (8) mount 以获得更深入的 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 来决定哪些文件系统与哪些远程客户端共享(导出到)。此文件只是主机 Internet 协议 (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 服务器,这将是 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 系统具有可以使用 apt-get 安装的 libnfs-utils 软件包。

安装 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 许可协议本作品采用 Creative Commons 署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.