NFS 共享文件系统
NFS(Network File System,网络文件系统)是一种分布式文件系统协议,允许不同计算机系统通过网络共享文件和目录,使客户端能够像访问本地文件一样访问远程服务器上的文件
NFS的基本概念
- 服务器端:提供共享存储的机器,负责导出(export)目录供客户端访问。
- 客户端:访问服务器端共享存储的机器,通过挂载(mount)方式使用共享目录。
- 共享目录:服务器端导出的目录,客户端可以像访问本地文件系统一样访问它
工作原理
mermaid
graph TD
%% 标题
T[NFS挂载图] --> A
%% 服务器节点
A[NFS server\n共享/video目录]
style A fill:#ffffff,stroke:#ff0000,stroke-dasharray: 5 5,stroke-width:2px
%% 客户端节点
B[NFS Client\n挂载NFS Server/video目录到本地/video目录]
C[NFS Client\n挂载NFS Server/video目录到本地/video目录]
style B fill:#ffffff,stroke:#0000ff,stroke-width:2px
style C fill:#ffffff,stroke:#0000ff,stroke-width:2px
%% 连接线
A --> B
A --> C
style T fill:none,stroke:none
linkStyle 0,1 stroke:#000000,stroke-width:1.5pxNFS本身是没有提供信息传输的协议和功能的,而是将自己的端口报备rpcbind服务,rpcbind服务开放111端口,客户端服务端请求发送到111端口上。rpcbind查看nfs服务在rpcbind记录的开放的端口,将用户请求调度到对应的端口上。
NFS 关键守护进程
| 进程名 | 端口 | 功能说明 |
|---|---|---|
| rpc.nfsd | 2049 | 主服务进程,处理文件操作请求 |
| rpc.mountd | 随机 | 验证客户端挂载权限(检查/etc/exports) |
| rpc.statd | 随机 | 提供文件锁定状态管理 |
| rpc.lockd | 随机 | 处理文件锁操作 |
协议依赖关系
| 版本 | RPC依赖 | 端口要求 |
|---|---|---|
| NFSv3 | 必须依赖rpcbind | 111 + 2049 + 随机端口 |
| NFSv4 | 不依赖rpcbind | 仅需2049 |
NFS配置 /etc/exports
配置格式
ini
存储目录 允许的IP(参数)
/data 192.168.1.0/24(rw,sync,all_squash)参数
| 参数名称 | 缩写 | 功能描述 | 风险提示 |
|---|---|---|---|
| Read-write | rw | 可读写权限 | 不当配置可能导致数据被篡改 |
| Read-only | ro | 只读权限 | - |
| 同步写入 | sync | 数据实时写入服务器硬盘后才返回 | 性能较低但数据安全 |
| 异步写入 | async | 数据先写入内存缓冲区,延迟写入磁盘 | 服务器异常关机可能导致数据丢失 |
| 保留root权限 | no_root_squash | root用户保持完整权限 | 高危!可能引发提权攻击 |
| 压缩root权限 | root_squash | 将root用户权限降级为匿名用户 | 增强安全性但可能影响某些服务运行 |
| 强制匿名访问 | all_squash | 所有用户权限压缩为匿名用户 | 适用于完全公开目录 |
| 匿名用户UID | anonuid | 指定共享文件所有者UID(如anonuid=12306) | 需与anongid配合使用 |
| 匿名用户GID | anongid | 指定共享文件所有者GID(如anongid=12306) | 需确保指定ID在服务端存在 |
NFS的配置流程
服务端搭建
安装软件包
bash
# CentOS/RHEL
dnf install -y nfs-utils rpcbind
# Ubuntu/Debian
apt-get install nfs-kernel-server创建共享目录并设置权限
bash
mkdir /data
chmod 755 -R /data
chown -R nobody:nobody /data编辑配置文件(/etc/exports)
bash
/data 192.168.1.0/24(rw,sync,no_root_squash)rw:读写权限。sync:数据同步写入磁盘。no_root_squash:允许客户端root用户保留权限
启动服务
bash
systemctl enable rpcbind nfs --now检测服务暴露端口
bash
showmount -e
# 正常出现
Export list for nfs-server:
/data 192.168.1.0/24客户端搭建
安装软件包
bash
# CentOS/RHEL
dnf install -y nfs-utils
# Ubuntu/Debian
apt-get install nfs-common查看服务端暴露端口
bash
showmount -e 192.168.148.1.100
# 正常出现
Export list for 192.168.148.157:
/data 192.168.1.0/24挂载共享目录
bash
mount -t nfs 192.168.1.100:/data/share /data验证挂载
bash
df -h | grep nfsNFS无敌时间
NFS客户端挂载后,往共享目录写入数据时卡住了。NFS服务端,重启restart服务,客户端如果写入数据卡住了。
解答:
nfs服务端重启之后,共享文件夹进入grace time(无敌时间)
客户端在服务端重启后写入数据大概要等90秒
nfs配置文件:/etc/sysconfig/nfs
inised -n '45,55p' /etc/sysconfig/nfs # When there are no active clients, changing these values # can be done in a single server restart. # #NFSD_V4_GRACE=90 # 无敌时间 #NFSD_V4_LEASE=90 # 无敌时间 #NLM_GRACE_PERIOD=90 # 无敌时间 # # # # Optional arguments passed to rpc.mountd. See rpc.mountd(8) #RPCMOUNTDOPTS="" #说明: #NFSD_V4_GRACE=90 <===>/proc/fs/nfsd/nfsv4gracetime #NFSD_V4_LEASE=90 <===>/proc/fs/nfsd/nfsv4leasetime #NLM_GRACE_PERIOD=90 <===>/proc/fs/nfsd/nfsv4recoverydir #这三条是控制无敌时间的,去掉#直接修改时间即可,改后别忘了重启服务。一旦启用了这三条,/proc临时目录下便会生成对应的临时文件
mount -o 参数
| 参数组 | 参数选项 | 功能描述 | 系统默认值 | 典型应用场景 |
|---|---|---|---|---|
| SUID控制 | suid | 允许执行带有SUID权限的程序 | suid | 需要特殊权限的程序运行 |
| nosuid | 禁用SUID程序功能(增强安全性) | - | 公共挂载目录安全防护 | |
| 读写控制 | rw | 允许读写操作 | rw | 需要修改数据的共享目录 |
| ro | 只读访问 | - | 静态资源分发(如软件仓库) | |
| 设备文件 | dev | 允许访问设备文件特殊功能 | dev | 需要直接访问硬件的场景 |
| nodev | 禁用设备文件功能 | - | 安全防护(如Web目录) | |
| 执行权限 | exec | 允许执行二进制文件 | exec | 共享可执行程序 |
| noexec | 禁止执行文件 | - | 纯数据存储目录(如图片/附件) | |
| 用户操作 | user | 允许普通用户挂载/卸载 | - | 多用户协作环境 |
| nouser | 仅root用户可操作 | nouser | 生产环境安全防护 | |
| 自动挂载 | auto | mount -a时自动挂载 | auto | 需要持久化挂载的分区 |
| noauto | 需手动挂载 | - | 临时性挂载或测试环境 |
生产环境建议组合
bash
mount -t nfs -o rw,nosuid,nodev,noexec 192.168.1.100:/share /mnt
# 或者
mount.nfs -o rw,nosuid,nodev,noexec 192.168.1.100:/share /mntNFS 内核优化
| 参数文件路径 | 参数说明 | 默认值 | 建议值 | 优化目的 |
|---|---|---|---|---|
| /proc/sys/net/core/rmem_default | 接收套接字缓冲区默认大小(字节) | 124928 | 8388608 | 提高 TCP 接收性能 |
| /proc/sys/net/core/rmem_max | 接收套接字缓冲区最大大小(字节) | 124928 | 16777216 | 支持高吞吐量网络连接 |
| /proc/sys/net/core/wmem_default | 发送套接字缓冲区默认大小(字节) | 124928 | 8388608 | 提高 TCP 发送性能 |
| /proc/sys/net/core/wmem_max | 发送套接字缓冲区最大大小(字节) | 124928 | 16777216 | 支持高吞吐量网络连接 |
临时生效
bash
echo 8388608 > /proc/sys/net/core/rmem_default
echo 16777216 > /proc/sys/net/core/rmem_max
echo 8388608 > /proc/sys/net/core/wmem_default
echo 16777216 > /proc/sys/net/core/wmem_max永久生效
bash
cat >> /etc/sysctl.conf <<EOF
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_default = 8388608
net.core.wmem_max = 16777216
EOF
sysctl -p # 立即生效NFS优缺点说明
NFS服务可以让不同的客户端挂载使用同一个共享目录,也就是将其作为共享存储使用,这样可以保证不同节点客户端数据的一致性,在集群架构环境中经常会用到。如果是windows和Linux混合环境的集群系统,可以用samba来实现。
优点
- 配置简单,容易上手,容易掌握
- NFS 文件系统内数据是在文件系统之上的,即数据是能看得见的。
- 支持文件锁。NFSv4+ 内置文件锁机制,避免多客户端同时写入冲突。
- 高性能。适合并发读取(如web静态资源,数据库备份)
局限
- 存在单点故障,如果
NFS Server宕机了,所有客户端都不能访问共享目录。这个需要负载均衡及高可用来弥补 - 在大数据高并发的场合,NFS效率,性能有限(2千万/日以下PV(page view)的网站不是瓶颈,除非网站架构设计太差。)
- 客户端认证是基于IP和主机名的,权限要根据ID识别,安全性一般(用于内网则问题不大)。
- NFS数据是明文的,NFS本身不对数据完整性做验证。
- 多台客户机器挂载一个NFS服务器时,连接管理维护麻烦(耦合度高)。尤其NFS服务端出问题后,所有NFS客户端都处于挂掉状态(测试环境可使用autofs自动挂载解决,正式环境可修复NFS服务或强制卸载)
- 涉及了同步(实时等待)和异步(解耦)的概念,NFS服务端和客户端相对来说就是耦合度有些高。网站程序也是一样,尽量不要耦合度太高,系统及程序架构师的重要职责就是为程序及架构解耦,让网站的扩展性变得更好。
应用建议
大中小型网站(参考点2000万/日PV以下)线上应用,都有用武之地。门户站也会有应用,生产场景应
该多把数据的访问往前推,即尽量把静态存储里的资源通过CDN或缓存服务器提供服务,如果没有缓存
服务或架构不好,存储服务器数量再多也是扛不住压力的,而且用户体验会很差。
