在 Linux 中挂载 NFS 网络共享

当网络中的文件服务器或 NAS 通过 NFS 共享出一个目录时,你可以像访问本地磁盘一样从另一台 Linux 机器访问这些文件。这对于共享备份、用户主目录和项目存储来说是一种常见配置。

网络文件系统(NFS,Network File System)是实现这一点的分布式文件系统协议。在 Linux 及类 Unix 系统上,mount 命令将远程 NFS 导出挂载到目录树中的一个本地挂载点。之后,你就可以根据服务器上设置的权限来访问远程文件。

本指南介绍如何在 Linux 上挂载 NFS 共享,既包括用于一次性挂载的手动方式,也包括通过 /etc/fstab 自动挂载(使共享在重启后依旧可用)。本文介绍的操作全部在客户端进行。如果导出尚不存在,请先按照我们关于安装和配置 NFS 服务器的指南搭建好服务端,再回来执行挂载。

快速参考

如需可打印的快速参考,请参阅挂载速查表。

Task Command
安装 NFS 客户端(Ubuntu、Debian) sudo apt install nfs-common
安装 NFS 客户端(Fedora、RHEL) sudo dnf install nfs-utils
列出 NFS 服务器上的导出 showmount -e SERVER_IP
挂载 NFS 共享 sudo mount -t nfs SERVER:/export /mountpoint
带选项挂载 sudo mount -t nfs -o rw,sync SERVER:/export /mnt
验证挂载 mount | grep nfs
仅列出 NFS 挂载 findmnt -t nfs,nfs4
卸载 NFS 共享 sudo umount /mountpoint
强制卸载 sudo umount -f /mountpoint
惰性卸载 sudo umount -l /mountpoint
挂载所有 fstab 条目 sudo mount -a

安装 NFS 客户端软件包

要挂载 NFS 共享,首先你需要安装 NFS 客户端软件包。软件包名称因 Linux 发行版而异。

sudo apt update

sudo apt install nfs-common

列出可用的 NFS 导出

在挂载之前,你可以使用 showmount 命令查看 NFS 服务器正在共享哪些目录:

showmount -e 10.10.0.10
Export list for 10.10.0.10:
/backups 10.10.0.0/24
/data    *

这会显示导出的路径以及被允许挂载它们的客户端。如果 showmount 不可用,请随 NFS 客户端工具一起安装它。

该命令查询服务器的挂载服务,而仅支持 NFSv4 的服务器可能不会提供此服务。如果 showmount -e 没有返回任何导出,请在服务器上确认导出路径,或直接尝试挂载已知的 NFSv4 路径。

手动挂载 NFS 共享

挂载远程 NFS 共享与挂载任何常规文件系统并无二致。

要在指定挂载点上挂载 NFS 文件系统,请使用如下形式的 mount 命令:

mount [OPTION...] NFS_SERVER:EXPORTED_DIRECTORY MOUNT_POINT

其中,NFS_SERVER:EXPORTED_DIRECTORY 是远程 NFS 导出,MOUNT_POINT 是你希望在其中访问它的本地目录。

请按以下步骤操作:

sudo mkdir /var/backups

共享挂载完成后,该挂载点就成为所挂载文件系统的根目录。

当你手动挂载共享时,它在重启后不会保留。

通过 /etc/fstab 自动挂载 NFS 共享

对于需要持久化的挂载,请使用 /etc/fstab 文件配置开机自动挂载。该文件包含一系列条目,用于定义开机时挂载哪些文件系统。

该行必须包含 NFS 服务器的主机名或 IP 地址、导出的目录,以及本地机器上的挂载点。

自动挂载 NFS 共享的步骤:

sudo mkdir /var/backups

下次重启系统时,NFS 共享将被自动挂载。

NFS 挂载选项

你可以通过 -o 指定,或添加到 /etc/fstab 条目中的常用选项:

• rw / ro —— 以读写(默认)或只读方式挂载。• sync / async —— 写操作等待服务器的确认(sync)或在本地缓冲(async)。sync 更安全,async 更快。• noexec —— 禁止在挂载的文件系统上执行二进制文件。• nofail —— 若设备开机时不存在则不报错。对于可能无法立即可用的 NFS 共享很有用。• nfsvers=4 / nfsvers=3 —— 强制使用特定的 NFS 协议版本。若不指定,客户端会先尝试 4.2 版本,并协商降级,直到找到服务器支持的版本。较短的 vers= 写法是为兼容其他操作系统而保留的别名。• _netdev —— 将该文件系统标记为需要网络访问。systemd 已经能识别 NFS 为网络文件系统,因此该选项主要对无法被它自动识别的网络后端文件系统有用。• x-systemd.automount —— 创建一个自动挂载单元,并在你首次访问该路径时挂载共享。这可以避免在服务器不可用时因超时而拖慢开机。

可靠性与超时选项

这些选项决定了当服务器停止响应时客户端的行为,也就是“一直等待的命令”与“直接失败退出的命令”之间的区别。

• hard —— 服务器无响应时对 NFS 请求无限重试。这是默认行为,也是为什么从已失效的 NFS 服务器读取数据的进程看起来像是卡住、而非返回错误的原因。• soft —— 在 retrans 次重传后放弃,并向应用程序返回 EIO,而不是永远重试。• softerr —— 行为与 soft 类似,但返回 ETIMEDOUT 而非 EIO,这样应用程序就能将超时与真正的输入/输出错误区分开来。• timeo=600 —— 客户端在重传前等待回复的时长,单位为分秒(十分之一秒)。TCP 上默认是 600,即 60 秒。• retrans=2 —— 在客户端报告超时(或在软挂载下让请求失败)之前,请求被重传的次数。TCP 上默认是 2,UDP 上默认是 3。• bg —— 若首次挂载尝试超时,则派生一个子进程在后台持续重试,而不是直接失败。默认是 fg,即让 mount 以错误退出。当机器在文件服务器可达之前就开机时很有用。

性能与安全性选项

• rsize= / wsize= —— 客户端在单次请求中从服务器读取或写入服务器的最大字节数。除非你在做调优,否则不要设置:客户端和服务器会协商双方都支持的最大值,最高为 1,048,576 字节(1 兆字节)。低于 1024 的值会被替换为 4096。• nconnect=4 —— 与同一服务器建立多条 TCP 连接(上限为 16 条),以免传输受单条连接瓶颈限制。在拥有多个并行读取者的高速网络上效果最为明显。• sec= —— 挂载所用的安全机制(flavor)。合法值有 none、sys、krb5、krb5i 和 krb5p。省略 sec= 时,客户端会协商客户端与服务器双方都支持的机制。常用的 sys 机制信任客户端发送的用户与组 ID,因此拥有客户端 root 权限的用户可以出示任意 ID。Kerberos 系列机制会对用户进行认证(krb5)、增加完整性校验(krb5i),或同时对流量加密(krb5p)。• actimeo= —— 文件大小、修改时间等属性的缓存时长,单位为秒。设置它会用单一值取代单独的 acregmin、acregmax、acdirmin 和 acdirmax 默认值。值较低会增加额外的往返,但在多个客户端写入同一文件时很有帮助。

在旧指南中可能会看到的两个选项已不值得添加。intr 自内核 2.6.25 起即被忽略;而包括 noatime 在内的 atime 系列选项对 NFS 挂载没有任何效果,因为客户端并未实现这些通用选项。

一个用于可靠挂载 NFS 的典型 fstab 条目:

10.10.0.10:/backups /var/backups nfs defaults,nofail,x-systemd.automount 0 0

卸载 NFS 共享

要卸载已挂载的 NFS 共享,请使用 umount 命令,后面接本地挂载点或远程共享:

sudo umount /var/backups

如果该共享在 fstab 文件中定义,请移除该条目,以防开机时重新挂载。

如果挂载的卷正在使用中,umount 命令会失败。要了解哪些进程正在访问 NFS 共享,可以使用 fuser 命令:

fuser -m /var/backups

用 kill 命令终止它们,然后重试。

当常规卸载无法完成时,可用 -l(--lazy)选项进行恢复。它会立即将文件系统从目录树中分离,并在不再繁忙时清理剩余引用:

sudo umount -l /var/backups

如果远程服务器不可达,可使用 -f(--force)选项强制卸载:

sudo umount -f /var/backups

尽可能避免使用强制选项。未保存的写入可能会丢失,而且当服务器不可达时该命令仍可能卡住。

故障排查

“Permission denied”(权限被拒绝):该目录可能在服务器上未被正确导出。请检查 NFS 服务器上的 /etc/exports,并运行 sudo exportfs -ar 重新加载导出。客户端 IP 地址也必须列在导出条目中。

“RPC: Program not registered”(RPC:程序未注册):服务器没有广播所请求 NFS 版本所需的 RPC 服务。从客户端列出服务器上已注册的服务:

rpcinfo -p 10.10.0.10

如果预期的 NFS、mountd 或 rpcbind 服务缺失,请检查服务器日志。在 Fedora、RHEL 及其衍生版上,使用以下命令重启 NFS 服务:

sudo systemctl restart nfs-server

在 Ubuntu、Debian 及其衍生版上,运行:

sudo systemctl restart nfs-kernel-server

“mount.nfs: remote share not in 'host:dir' format”(远程共享不是 “主机:目录” 格式):客户端找不到用来分隔服务器与导出路径的冒号,因此根本没到联系服务器的那一步。请先检查设备参数:10.10.0.10:/backups 是正确的,而 10.10.0.10/backups 和 10.10.0.10 /backups 都会触发此错误。/etc/fstab 条目的第一个字段同样适用该规则。

对于 IPv6 地址,请使用方括号,以便客户端知道地址在哪里结束。若不加括号,客户端会把地址中的第一个冒号当作分隔符,从而错误解析服务器与导出路径,而不一定会报出这种格式错误。对源参数加引号,以防 shell 将方括号当作文件名模式处理:

sudo mount -t nfs 
'[2001:db8::10]:/backups'
 /var/backups

“Stale file handle”(文件句柄失效):这种情况发生在服务器重启、或文件在挂载期间被删除之后。在客户端卸载并重新挂载该共享即可解决。

“Server not responding”(服务器无响应)或连接超时:使用 ping 和 traceroute 检查网络连接。NFSv4 通常使用 TCP 端口 2049。NFSv3 还依赖 rpcbind、mountd 及其他可能使用额外端口的 RPC 服务,因此在添加防火墙规则前,请在服务器上配置固定的服务端口。如果 NFS 版本不匹配,请在挂载选项中显式指定 vers=3 或 vers=4。

当 NFS 服务器不可用时系统在开机时卡住:在 fstab 选项中添加 nofail 和 x-systemd.automount。nofail 在共享无法挂载时让开机继续,而 x-systemd.automount 会将连接推迟到你访问该挂载点时再进行。

常见问题

NFS v3 与 NFS v4 有什么区别?NFSv4 是现代标准,内置了安全性(支持 Kerberos)、有状态操作,以及更好的防火墙兼容性(单一端口 2049)。NFSv3 使用多个端口,并需要 portmapper(端口 111)。大多数现代 Linux 发行版默认使用 NFSv4。仅当服务器不支持 v4 时,才在挂载选项中使用 vers=3。

如何在开机时自动挂载 NFS 共享?在 /etc/fstab 中添加一条条目,包含 NFS 服务器路径、本地挂载点、类型 nfs,以及包含 nofail 的选项。当你希望连接在首次访问时才启动、而非在开机时进行时,添加 x-systemd.automount。在重启前运行 sudo mount -a 测试该条目。

为什么 NFS 挂载在重启后没有保留?使用 mount -t nfs 的手动挂载不是持久化的。若要让挂载在重启后依然保留,请按“自动挂载”一节所述将该条目添加到 /etc/fstab。

如何查看服务器上有哪些可用的 NFS 共享?使用 showmount -e SERVER_IP 查询服务器的导出列表。仅支持 NFSv4 的服务器可能不会暴露 showmount 所用的挂载服务,因此空结果并不总是意味着没有导出存在。

fstab 中的 nofail 选项有什么作用?nofail 告诉系统:如果文件系统无法挂载,不要报错,也不要中断开机流程。这对于 NFS 这类在开机时可能无法立即可用的网络文件系统尤其有用。

结论

在 Linux 上挂载 NFS 共享需要安装客户端工具、创建本地挂载点,并运行 mount -t nfs。对于持久化挂载,请将条目以 nofail 添加到 /etc/fstab;当服务器在开机时可能不可用时,使用 x-systemd.automount。若要了解更多关于通用文件系统挂载的内容,请参阅 mount 命令指南。