系列:文件共享与传输
背景
多台 Linux 服务器之间需要共享同一份文件,如果每次都靠 SCP 传来传去,既麻烦又容易版本混乱。在之前的文章中,我已经写过 SCP/SFTP 的远程传输(SCP 和 SFTP 使用指南:远程文件传输基础),也搭建过 Samba 实现 Linux-Windows 共享(Samba 安装与配置指南:Linux 和 Windows 文件共享)和 vsftpd 文件服务器(用 vsftpd 在 Ubuntu 上搭建文件共享服务器)。NFS(Network File System)则是另一种思路:让一台服务器导出目录,其他服务器挂载后像本地磁盘一样读写,特别适合集群环境、共享存储、虚拟机文件交换等纯 Linux 场景。
本文在 Ubuntu 22.04 上搭建 NFS 服务端,配置一台客户端挂载共享目录,并覆盖性能调优和常见故障排查。前置条件:两台 Ubuntu 22.04 服务器,服务端 IP 假设为 192.168.1.10,客户端为 192.168.1.20,彼此网络互通,已配置 SSH 免密登录。
步骤
1. 安装 NFS 服务端
在服务端安装 NFS 内核服务:
sudo apt updatesudo apt install nfs-kernel-server -y安装完成后服务会自动启动,检查状态:
sudo systemctl status nfs-server如果显示 active (exited) 属于正常现象,NFS 服务由内核线程处理,systemd 仅管理启动脚本。更多细节参考 Ubuntu NFS 官方文档。
2. 创建共享目录
在服务端创建一个用于共享的目录:
sudo mkdir -p /srv/nfs-sharesudo chown nobody:nogroup /srv/nfs-sharesudo chmod 755 /srv/nfs-shareNFS 默认会将对客户端 root 的操作映射为 nobody:nogroup,这里将目录属主设为 nobody:nogroup 避免权限混乱。
3. 配置导出
编辑 /etc/exports 文件:
sudo nano /etc/exports添加一行:
/srv/nfs-share 192.168.1.0/24(rw,sync,no_subtree_check)参数说明:
rw:允许读写sync:写操作同步写入磁盘,防止数据丢失(NFSv4 之前默认是async,建议显式声明)no_subtree_check:不检查父目录权限,提高性能
如果允许多个网段,可以写成多行或用通配符。详细参数见 exports 手册页。
保存后重新加载导出配置:
sudo exportfs -ra-r 重新导出所有目录,-a 应用 /etc/exports 的内容。检查当前导出列表:
sudo exportfs -v应该能看到 /srv/nfs-share 及对应选项。
4. 配置防火墙
NFS 涉及多个端口,包括 portmapper(111)、nfs(2049) 以及动态分配的 mountd、lockd 等。最简单的方式是通过固定端口并放行。
编辑 NFS 配置文件固定辅助服务端口:
sudo nano /etc/default/nfs-kernel-server添加或修改以下行:
RPCMOUNTDOPTS="--port 20048"然后为 lockd 和 statd 设置端口,编辑模块配置:
sudo nano /etc/modprobe.d/lockd.conf写入:
options lockd nlm_tcpport=32803 nlm_udpport=32769重启 NFS 服务使配置生效:
sudo systemctl restart nfs-server现在放行这些固定端口:
sudo ufw allow from 192.168.1.0/24 to any port 111,2049,20048,32803,32769 proto tcpsudo ufw allow from 192.168.1.0/24 to any port 111,2049,20048,32769 proto udpNFS 端口规划参考 ArchWiki NFS。
5. 客户端挂载
在客户端安装 NFS 客户端工具:
sudo apt install nfs-common -y创建挂载点并挂载:
sudo mkdir -p /mnt/nfssudo mount 192.168.1.10:/srv/nfs-share /mnt/nfs检查挂载结果:
df -h /mnt/nfs如果显示 NFS 文件系统且大小正确,说明挂载成功。
6. 设置开机自动挂载
编辑 /etc/fstab 添加一行:
192.168.1.10:/srv/nfs-share /mnt/nfs nfs defaults,_netdev 0 0_netdev 选项告诉系统等网络就绪后再挂载,防止开机失败。
测试配置是否正确:
sudo mount -a无报错即表示 fstab 语法无误。然后重启验证。
7. 性能调优(可选)
挂载时可以指定 rsize 和 wsize 提高传输效率:
mount -o rsize=1048576,wsize=1048576 192.168.1.10:/srv/nfs-share /mnt/nfs这两个参数设置读写块大小为 1 MB(默认通常为 1 MB 或更小),在千兆局域网中可提升大文件吞吐。NFS 性能调优建议参考 Red Hat 性能调优指南。
常见问题
1. 客户端挂载提示“access denied by server”
服务端检查是否已重新加载 /etc/exports:
sudo exportfs -ra确认共享目录的所有者和权限。如果目录权限是 700,NFS 客户端可能被拒绝,调整为 755 即可。也可以用 showmount -e 192.168.1.10 从客户端检查可用的导出。
2. 重启后客户端挂载失败
检查 fstab 是否包含 _netdev,如果没有则可能导致挂载时网络尚未就绪。同时确认服务端的 NFS 服务已开启且防火墙规则持久化。客户端可以加上 nofail 选项避免启动卡住(例如 defaults,_netdev,nofail),但这样会跳过错误,需根据需求取舍。
3. 挂载成功但写入文件报错“Permission denied”
可能原因有两个:一是客户端以 root 身份写入,但 NFS 默认开启了 root_squash,将 root 映射为 nobody,而目录又禁止 nobody 写入。若需要允许 root 写入,可在 /etc/exports 中加入 no_root_squash 选项,但会降低安全性。二是目录权限本身不允许 nobody 写入,把目录属主临时改为一个普通用户或调整组权限也可以绕过。
4. 客户端出现 stale file handle
通常是因为服务端重启后没有重新导出,或者原先导出的目录已删除。解决办法:客户端先 umount -l /mnt/nfs 卸载,服务端重新 exportfs -ra,然后再挂载。
总结
NFS 的安装配置整体分为服务端导出和客户端挂载两部分,防火墙端口固定是很多人第一次搭建时忽略的坑。在生产环境中建议进一步配置 Kerberos 认证(sec=krb5)和 NFSv4 专有端口,提高安全性。把它和 Samba、vsftpd 等工具对比,可以更清楚地知道什么场景选哪个方案。