实用指南:3.NFS 服务器
作者@小郭
3.NFS 服务器
NFS 服务介绍
在计算机网络存储领域,NFS(Network File System,网络文件系统)是一种实现不同计算机之间文件共享的经典技术。它允许网络中的客户端计算机像访问本地文件一样,透明地访问远程服务器上的文件资源,极大地简化了跨设备的数据共享与管理流程。
NFS 的起源与发展
NFS 技术诞生于 20 世纪 80 年代,由太阳微系统公司(Sun Microsystems)率先开发。最初的设计目标是解决 UNIX 系统之间的文件共享问题,凭借其简洁的架构和良好的跨平台性,迅速成为网络文件共享的主流标准之一。
随着技术的演进,NFS 经历了多个版本的迭代。其中,NFSv3 是应用最为广泛的版本之一,它在早期版本的基础上增强了性能和可靠性,支持更大的文件尺寸和更多的功能。而 NFSv4 则是较新的版本,引入了更强的安全性(如支持 Kerberos 认证)、状态化连接以及更完善的文件锁机制,进一步提升了 NFS 在复杂网络环境中的适用性。
NFS 的核心架构
NFS 采用客户端 - 服务器(Client-Server)架构,主要由两部分组成:
NFS 服务器:负责存储文件资源,并通过 NFS 协议将这些资源共享给授权的客户端。服务器上运行着 NFS 守护进程,用于监听客户端的请求、处理文件访问操作以及维护共享目录的权限控制。
NFS 客户端:通过 NFS 协议访问服务器上的共享文件。客户端需要挂载(Mount)服务器的共享目录到本地文件系统,之后就可以像操作本地文件一样对远程文件进行读写、创建、删除等操作。
NFS 的工作原理

NFS 的工作流程基于远程过程调用(RPC,Remote Procedure Call)机制,具体过程如下:
- 注册阶段:NFS服务端启动服务时,向RPC服务注册服务端口。
- 建立连接阶段:客户端向RPC服务器查询NFS服务器服务端口,然后再向NFS 服务器的服务端口发起挂载请求。
- 挂载阶段:服务器验证客户端的身份和权限,如果通过验证,则允许客户端将共享目录挂载到本地指定的挂载点。
- 文件访问阶段:挂载成功后,客户端对远程文件的操作(如读取、写入)会通过 RPC 协议转换为对服务器的远程过程调用。服务器接收到请求后,执行相应的文件操作,并将结果返回给客户端。
- 权限控制:NFS 通过文件系统的权限机制(如 UNIX 的用户 ID 和组 ID)来控制客户端对文件的访问。服务器会根据客户端的身份以及共享目录的权限设置,决定是否允许客户端的操作。
NFS 的数据传输特点
无状态性(部分版本):NFSv3 及之前的版本属于无状态协议,服务器不保存客户端的连接状态信息。这意味着如果服务器或网络出现故障,客户端重新连接后即可继续操作,无需恢复复杂的状态信息,简化了协议的实现和容错处理。
基于 UDP 和 TCP:NFS 可以使用 UDP(用户数据报协议)或 TCP(传输控制协议)进行数据传输。UDP 具有较低的开销,适用于对实时性要求较高但对可靠性要求相对较低的场景;TCP 则提供可靠的面向连接的传输,适用于数据传输量大、对可靠性要求高的场景,在现代网络中应用更为广泛。
NFS 的优势
透明性:客户端访问远程文件的方式与访问本地文件几乎一致,用户无需关注文件的实际存储位置,降低了使用复杂度。
跨平台性:NFS 支持多种操作系统,如 UNIX、Linux、macOS 等,能够实现不同操作系统之间的文件共享。
高效性:通过优化的数据传输机制和缓存策略,NFS 能够提供较高的文件访问性能,满足多数网络环境下的文件共享需求。
易于管理:NFS 的配置相对简单,管理员可以通过修改配置文件轻松设置共享目录、访问权限等,便于集中管理网络中的文件资源。
NFS 的局限性
安全性较弱(早期版本):NFSv3 及之前的版本在安全性方面存在不足,缺乏强大的身份认证和数据加密机制,容易受到网络监听、身份伪造等攻击。虽然 NFSv4 引入了更多安全特性,但在一些对安全性要求极高的场景中,仍需配合其他安全措施(如 VPN、防火墙)使用。
对网络依赖性强:NFS 的性能和可用性高度依赖网络状况,网络延迟、丢包等问题会直接影响文件访问的速度和稳定性。
文件锁机制复杂:在多客户端同时访问同一文件时,NFS 的文件锁机制相对复杂,处理不当可能导致数据不一致的问题。
NFS 的典型应用场景
企业内部文件共享:在企业局域网中,NFS 可以用于共享办公文档、软件安装包等资源,方便员工在不同的计算机上访问和协作。
服务器集群存储:在 Web 服务器集群、数据库集群等场景中,NFS 可以为集群中的所有节点提供统一的共享存储,确保各节点访问的数据一致性。
嵌入式系统:在一些嵌入式设备(如网络存储设备、路由器等)中,NFS 可以作为简单的文件共享解决方案,实现设备与外部计算机的数据交互。
总结
总之,NFS 作为一种成熟的网络文件共享技术,凭借其简洁、高效、跨平台等优势,在各类网络环境中得到了广泛应用。尽管存在一些局限性,但通过版本迭代和与其他技术的结合,NFS 仍然在网络存储领域发挥着重要作用。
NFS 服务最佳实践
部署服务
NFS服务由nfs-utils软件包提供。
# 安装软件包
[root@server ~ 09:00:28]# yum install -y nfs-utils
# 准备用户,此实验用本机用户gcf,如果想用其他的可以用useradd添加。
# 准备共享目录
[root@server ~ 09:30:17]# mkdir -p /shares/webapp
[root@server ~ 09:32:34]# ll -d /shares/webapp/
drwxr-xr-x 2 root root 6 Nov 21 09:32 /shares/webapp/
[root@server ~ 09:32:51]# chown gcf /shares/webapp/
[root@server ~ 09:33:03]# ll -d /shares/webapp/
drwxr-xr-x 2 gcf root 6 Nov 21 09:32 /shares/webapp/
# #配置防火墙
[root@server ~]# firewall-cmd --permanent --add-service=nfs --add-service=rpc-bind --add-service=mountd
[root@server ~]# firewall-cmd --reload
#此实验中我将防火墙直接关闭了。因为要启用NFS服务时,他依赖的服务也要被启用,使用如果配置防火墙要放行的服务不仅是NFS服务还有其他的依赖服务。
[root@server ~ 09:47:29]# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; `disabled`; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
配置 NFS 导出
NFS服务器主要配置文件是**/etc/exports**,目录**/etc/exports.d中任何以.exports**结尾且不以点(.)开头的文件也会生效。 所有这些文件都使用相同的语法。
==提示:==与编辑文件/etc/exports本身相比,在/etc/exports.d中创建或删除文件可能更容易,并且它可以减少一系列相关配置更改意外破坏现有导出的风险。
配置文件中,每一行都声明一个导出点。 第一个字段是要导出到客户端的目录的名称。 该行的其余部分列出了可以访问共享目录的客户端系统以及授予它们的访问权限。
==提示:==NFS不要使用SMB共享的目录。 如果这样做,则可能会导致文件损坏或其他文件完整性或一致性问题。
配置示例:
- 可解析DNS的主机名,例如client.gcf.cloud。 在以下示例中,client.gcf.cloud系统可以挂载/shares/webapp目录。
/shares/webapp client.gcf.cloud
- DNS解析的主机名,带*通配符。 以下示例允许gcf.cloud域中的所有系统访问NFS共享。
/shares/webapp *.gcf.cloud
- IPv4地址。 以下示例允许从10.1.8.12 IP地址访问NFS共享。
/shares/webapp 10.1.8.11
- IPv4网络。 以下示例允许从10.1.8.0/24网络访问NFS共享。 您也可以使用10.1.8.0/255.255.255.0 表示法。
/shares/webapp 10.1.8.0/24
/shares/webapp 10.1.8.0/255.255.255.0
- IPv6地址。 以下示例允许具有fde2:6494:1e09:2::20 IPv6地址的客户端系统访问NFS共享。
/shares/webapp fde2:6494:1e09:2::20
- IPv6网络。 以下示例允许fde2:6494:1e09:2::/64 IPv6网络访问NFS共享。
/shares/webapp fde2:6494:1e09:2::/64
- 要与多个客户机系统共享目录,请在目录名称后使用以空格分隔的列表:
/shares/webapp 10.1.8.0/24 client.gcf.cloud *.example.net
默认情况下,目录以只读模式与客户端共享。 在每个客户定义之后,您可以立即在括号中指定导出选项以覆盖默认值。 客户端定义的末尾和左括号之间必须没有空格。
常用的选项:
rw,此选项允许对指定客户端进行读/写访问。 如果没有该选项(或者如果您使用ro代替),则NFS仅授予读取访问权限。 在以下示例中,client.gcf.cloud具有读/写访问权限,而client2.gcf.cloud具有只读访问权限。
/shares/webapp client.gcf.cloud(rw) client2.gcf.cloudno_root_squash,默认情况下,当客户机上的root用户访问NFS导出时,服务器会将其视为nobody用户(在服务器上定义)的访问。 这意味着,如果客户端上的root用户在导出文件上创建了文件,则该文件将归用户nobody所有。 这也意味着,如果客户机上的root用户尝试读取导出文件,而该文件是没人能读取的用户,则访问将失败。 您可以通过添加no_root_squash选项来禁用该安全保护。
以下示例允许client.gcf.cloud系统具有对/shares/webapp导出目录的读/写访问权限和实际root用户访问权限。
/shares/webapp client.gcf.cloud(rw,no_root_squash)
我们使用以下记录:
[root@server ~ 09:33:06]# vim /etc/exports
/shares/webapp 10.1.8.0/24(rw)
每当您在/etc/exports或/etc/exports.d/*.exports中更改导出点时,请对NFS服务运行exportfs -r命令确保更改生效,或者运行systemctl reload nfs-server。
[root@server ~]# exportfs -r
# 或者
[root@server ~]# systemctl reload nfs-server
# 或者
[root@server ~]# exportfs -av
#开启服务。
[root@server ~ 09:39:03]# systemctl enable nfs-server.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
RPC
#当开启NFS服务时,发现rpcbind服务也处于开启状态,是因为NFS服务依赖RPC协议。
[root@server ~ 09:40:16]# systemctl status rpcbind
● rpcbind.service - RPC bind service
Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2025-11-21 09:40:15 CST; 15s ago
Process: 11464 ExecStart=/sbin/rpcbind -w $RPCBIND_ARGS (code=exited, status=0/SUCCESS)
Main PID: 11469 (rpcbind)
CGroup: /system.slice/rpcbind.service
└─11469 /sbin/rpcbind -w
Nov 21 09:40:15 server.gcf.cloud systemd[1]: Starting RPC bind service...
Nov 21 09:40:15 server.gcf.cloud systemd[1]: Started RPC bind service.
#查看端口验证开启服务。
[root@server ~ 09:40:31]# ss -lnt4
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 64 *:38508 *:*
LISTEN 0 128 *:34733 *:*
LISTEN 0 128 *:111 *:*
LISTEN 0 128 *:20048 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 64 *:2049 *:*
[root@server ~ 09:40:52]# ss -lt4
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 64 *:38508 *:*
LISTEN 0 128 *:34733 *:*
LISTEN 0 128 *:sunrpc *:*
LISTEN 0 128 *:mountd *:*
LISTEN 0 128 *:ssh *:*
LISTEN 0 100 127.0.0.1:smtp *:*
LISTEN 0 64 *:nfs *:*
监视 NFS 导出
使用exportfs命令列出NFS服务器当前导出的目录。
[root@server ~ 09:41:10]# exportfs
/shares/webapp 10.1.8.0/24
默认情况下,该命令不显示导出选项。 使用-v选项列出这些选项,包括缺省选项。
[root@server ~ 09:43:29]# exportfs -v
/shares/webapp 10.1.8.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
客户端挂载
# 安装软件包
[root@client ~ 09:46:14]# yum install -y nginx
#查看用户是否跟server端一样。
#是 NFS 权限正常的核心前提(NFS 通过 UID/GID 而非用户名识别用户)。如果 UID 不一致,Client 端的 gcf 用户将无法正常读写 NFS 共享目录.
[root@client ~ 09:30:29]# id gcf
uid=1000(gcf) gid=1000(gcf) groups=1000(gcf),10(wheel)
[root@server ~ 09:43:33]# id gcf
uid=1000(gcf) gid=1000(gcf) groups=1000(gcf),10(wheel)
# 查看Server端的NFS共享列表
[root@client ~ 09:43:46]# showmount -e 10.1.8.10
Export list for 10.1.8.10:
/shares/webapp 10.1.8.0/24
# 挂载
[root@client ~ 09:48:05]# mount -t nfs 10.1.8.10:/shares/webapp /usr/share/nginx/html/
[root@client ~ 09:49:16]# ls /usr/share/nginx/html/
index.html
#查看挂载点。
[root@client ~ 09:49:21]# df /usr/share/nginx/html/
Filesystem 1K-blocks Used Available Use% Mounted on
10.1.8.10:/shares/webapp 52403200 1655808 50747392 4% /usr/share/nginx/html
#部署完成开启服务。
[root@client ~ 09:49:45]# systemctl enable nginx.service --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
访问测试
#server端配置一个欢迎界面。
[root@server ~ 09:45:55]# echo Hello World From NFS > /shares/webapp/index.html
在浏览器上访问10.1.8.11会出现如下界面:

#当想在挂载的目录下去创建文件的时候发现不能创建了。
[root@client ~ 10:22:56]# cd /usr/share/nginx/html/
[root@client html 10:26:22]# touch web01
touch: cannot touch ‘web01’: Permission denied
#原因是:当去实现NFS服务时,会将root用户压缩成一个普通用户:root_squash,在挂载目录下普通用户当然不能创建文件,因为没有权限。
[root@server ~ 10:03:13]# exportfs -v
/shares/webapp 10.1.8.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
#对于普通用户没有w权限,
[root@server ~ 10:31:02]# ll -d /usr/share/nginx/html
drwxr-xr-x 3 root root 148 Nov 21 10:23 /usr/share/nginx/html
#但是这个仅对于在client端挂载目录下,
实施效果:由于 Server 端/shares/webapp的所有者是gcf(UID=1000),Client 端的gcf用户可以直接修改/usr/share/nginx/html/下的文件(如vim /usr/share/nginx/html/index.html),修改会实时同步到 NFS 服务端。
持久化挂载
修改 /etc/fstab,最后添加如下记录:
[root@server ~ 10:33:59]# vim /etc/fstab
10.1.8.10:/shares/webapp /usr/share/nginx/html nfs defaults 0 0
#重新加载配置文件,使命令生效。
[root@server ~ 10:35:43]# exportfs -r
#重启后验证
[root@server ~ 10:36:27]# reboot
[root@server ~ 10:36:56]# df /usr/share/nginx/html/
Filesystem 1K-blocks Used Available Use% Mounted on
10.1.8.10:/shares/webapp 52403200 1654784 50748416 4% /usr/share/nginx/html
浙公网安备 33010602011771号