NFS共享磁盘:原理、安装与使用完全指南
NFS共享磁盘:原理、安装与使用完全指南
1. 什么是NFS?为什么你需要它?
想象一下这个场景:你有三台服务器,每台都存着网站用户上传的图片。用户修改头像后,访问A服务器能看到新头像,访问B服务器却还是旧的。这种数据不一致的问题,在多台服务器组成集群时尤为突出。
NFS(Network File System,网络文件系统) 就是为了解决这个问题而生的。它允许你将一台服务器上的目录通过网络“共享”给其他服务器。客户端(挂载方)访问这个共享目录时,感觉就像在操作本地磁盘一样——可以读、写、创建文件,而这些操作实际上都发生在远程服务器上。
NFS的核心价值在于:
- 数据集中化:所有共享数据存放在一台服务器上,多台客户端统一访问,保证数据一致性
- 透明访问:客户端用户无需感知文件存储在哪里,操作体验与本地文件无异
- 部署简单:配置和维护相对容易,在中小规模场景中非常实用
NFS诞生于1984年,由Sun公司开发,经过多年迭代,目前主流版本是NFSv3和NFSv4。NFSv4相比旧版本,将通信集中到单一的TCP端口(2049),安全性更高,防火墙配置也更简单。
NFS并非没有缺点:最明显的是单点故障问题——NFS服务器宕机后,所有客户端都无法访问共享目录;同时在高并发场景下,单台NFS服务器可能成为性能瓶颈。但在中小规模集群、开发测试环境等场景中,NFS凭借其简洁高效,依然是许多团队的首选方案。
2. NFS是如何工作的?核心原理浅析
要真正用好NFS,有必要了解它背后的工作机制。
2.1 RPC:NFS的“通讯兵”
NFS本身并不直接处理网络通信的细节,而是依赖一个名为 RPC(Remote Procedure Call,远程过程调用) 的机制来传递请求和响应。可以把RPC理解成一个“通讯兵”,负责在客户端和服务器之间传递消息。
NFS的各类功能(文件读写、目录操作、挂载请求等)由不同的守护进程(daemon)提供。当NFS服务器启动时,这些守护进程会动态分配端口,然后向一个名为 rpcbind(旧称portmap) 的服务注册——报告自己“叫什么名字、监听着哪个端口”。
rpcbind服务本身使用固定的111端口,像个“总机台”一样等待客户端的查询。
2.2 一次完整的NFS访问流程
当客户端想访问NFS共享目录时,大致流程如下:
- 客户端查询:客户端向服务端的rpcbind(端口111)发出请求:“NFS服务在哪个端口?”
- 服务端反馈:rpcbind查询注册信息,将NFS对应的端口号(默认2049)告知客户端
- 直接通信:客户端获得端口后,直接与NFS服务进程建立连接,开始真正的文件读写操作
客户端 rpcbind (111端口) NFS服务 (2049端口)
| | |
|--- 1. "NFS服务在哪个端口?"-->| |
| | |
|<-- 2. "在2049端口" ----------| |
| | |
|--- 3. 建立连接,读写文件 --------------------------------->|
小贴士:NFSv4及以上版本将功能整合,默认只使用TCP 2049端口,不再依赖rpcbind动态分配端口,防火墙配置更为简便。如果你使用NFSv3,则需要开放rpcbind(111端口)以及rpc.mountd等动态分配的多个端口。
2.3 关键配置文件与守护进程
- /etc/exports:服务端最重要的配置文件,定义了“共享哪个目录、允许谁访问、权限如何”
- rpc.nfsd:核心守护进程,处理客户端的文件访问请求
- rpc.mountd:负责处理客户端的挂载请求,检查/etc/exports验证权限
3. 动手实践:从零搭建一个NFS共享环境
下面我们用两台Ubuntu 22.04/24.04服务器,一步步搭建NFS服务,实现文件共享。假设环境如下:
| 角色 | 主机名 | IP地址 |
|---|---|---|
| NFS服务端 | nfs-server | 192.168.1.100 |
| NFS客户端 | nfs-client | 192.168.1.101 |
注意:如果你的系统是CentOS/RHEL,软件包安装命令使用
yum install nfs-utils即可,其余步骤基本相同。
3.1 第一步:在服务端安装NFS服务
在NFS服务端(192.168.1.100)操作:
# 更新软件包索引
sudo apt update
# 安装NFS服务端软件
sudo apt install nfs-kernel-server -y
安装完成后,NFS服务会自动启动。你可以检查状态确认:
sudo systemctl status nfs-server
3.2 第二步:创建共享目录并配置/etc/exports
继续在服务端操作。我们创建一个/srv/nfs_share目录作为共享目标:
# 创建共享目录
sudo mkdir -p /srv/nfs_share
# 设置权限(此处为演示方便,开放所有权限,生产环境请按需收紧)
sudo chown nobody:nogroup /srv/nfs_share
sudo chmod 777 /srv/nfs_share
为什么设置nobody:nogroup? 出于安全考虑,NFS默认会将客户端root用户映射为nobody用户,防止客户端root在服务端拥有过高权限。设置目录属主为nobody:nogroup可让这个映射工作更顺畅。
接下来编辑NFS配置文件/etc/exports:
sudo nano /etc/exports
添加以下内容(请将192.168.1.0/24替换为你的客户端所在网段或具体IP):
/srv/nfs_share 192.168.1.0/24(rw,sync,no_subtree_check)
参数解释:
- /srv/nfs_share:要共享的目录路径
- 192.168.1.0/24:允许访问的客户端网段,也可以写成具体IP如
192.168.1.101 - rw:客户端拥有读写权限(若只需只读可改为
ro) - sync:同步写入,数据真正落盘后才响应,更可靠但性能略低
- no_subtree_check:禁用子树检查,可提升性能,大多数场景推荐使用
保存文件后,应用配置并重启服务:
# 重新加载exports配置
sudo exportfs -ra
# 重启NFS服务(确保生效)
sudo systemctl restart nfs-server
# 查看共享状态
sudo exportfs -v
3.3 第三步:配置服务端防火墙
NFSv4默认使用TCP 2049端口。如果服务端防火墙(UFW)已启用,需要放行该端口:
# 允许来自客户端网段的2049端口访问(推荐限制来源)
sudo ufw allow from 192.168.1.0/24 to any port 2049
# 或者简单开放2049(不限制来源,安全性较低)
# sudo ufw allow 2049
# 查看防火墙状态确认
sudo ufw status
3.4 第四步:在客户端安装并挂载NFS
切换到NFS客户端(192.168.1.101)操作:
# 安装NFS客户端工具
sudo apt update
sudo apt install nfs-common -y
创建本地挂载点并执行挂载:
# 创建挂载目录
sudo mkdir -p /mnt/nfs_data
# 挂载NFS共享(请替换IP为服务端实际IP)
sudo mount -t nfs 192.168.1.100:/srv/nfs_share /mnt/nfs_data
验证挂载是否成功:
# 查看挂载状态
df -h | grep nfs
# 应该能看到类似输出:
# 192.168.1.100:/srv/nfs_share XXG XXG XXG X% /mnt/nfs_data
# 测试读写
echo "Hello NFS" | sudo tee /mnt/nfs_data/test.txt
ls -la /mnt/nfs_data/
如果能在客户端看到test.txt文件,说明NFS共享已成功搭建!
3.5 第五步:配置开机自动挂载(可选)
如果你希望客户端重启后NFS目录能自动挂载,可以编辑/etc/fstab文件:
sudo nano /etc/fstab
在文件末尾添加一行(IP和路径请替换为实际值):
192.168.1.100:/srv/nfs_share /mnt/nfs_data nfs defaults,_netdev 0 0
- defaults:使用默认挂载选项
- _netdev:告诉系统这个挂载依赖网络,启动时等网络就绪后再挂载,避免系统卡住
保存后,执行以下命令测试fstab配置是否正确:
sudo umount /mnt/nfs_data # 先卸载手动挂载
sudo mount -a # 尝试挂载所有fstab中的条目
df -h | grep nfs # 再次验证
如果配置无误,重启客户端后NFS目录也会自动挂载。
3.6 一个最小可用例子的总结
回顾一下,我们完成了一个“最小可用”的NFS共享环境:
- 服务端:安装了
nfs-kernel-server,创建了/srv/nfs_share目录,在/etc/exports中配置共享规则,防火墙开放2049端口 - 客户端:安装了
nfs-common,创建挂载点,通过mount命令挂载服务端共享目录 - 验证:客户端成功读写服务端的文件,数据保持一致
这就是NFS最基本的使用方式。在实际生产环境中,你可能还需要关注性能调优(如调整rsize/wsize参数)、高可用方案(配合rsync或DRBD做备份)、以及更精细的权限控制(如使用all_squash、anonuid等参数映射用户身份)。但万变不离其宗,理解和掌握这个最小可用例子,就是你踏上NFS实战之路的第一步。