尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

NFS+autofs自动挂载实战:解决服务端重启卡死的坑

NFS+autofs自动挂载实战:解决服务端重启卡死的坑 1. 为什么我把NFS和autofs搭在一起用先说个实际场景。公司测试环境有三台Linux服务器跑的都是CentOS 7.9平时各个项目组都要往上面丢编译产物、共享测试数据。最开始图省事每个人在自己机器上mount一下NFS写进fstab开机自动挂载。结果用了两三个月麻烦事一件接一件有些机器上服务重启之后挂载丢了有些目录根本用不上还得一直挂着占资源最烦的是NFS服务端一重启客户端就卡在挂载点上整个shell操作都像死机一样。后来我把方案改成了NFS服务端固定共享目录客户端用autofs按需触发挂载。这里面的核心思路其实很简单NFS负责把服务器的目录共享出去autofs负责在客户端“按需挂载、空闲卸载”。打个比方NFS是一间仓库autofs就是仓库门口的自动门禁——你刷了卡才开门人走了门自动锁上不会一直开着让冷气跑光。这个组合最适合谁用如果你管着几台到几十台Linux服务器需要共享数据但又不想让客户端长期占用挂载资源或者你被“fstab挂载后重启掉链子”这种问题坑过那这篇文章就是写给你的。下面我从服务端配置、客户端autofs实现、坑点排查三个维度完整走一遍最后附上几个我在生产环境里踩过才会记住的细节。2. 环境准备与整体架构设计2.1 实验环境与版本选型我这边用的服务端和客户端都是CentOS 7.9内核版本3.10NFS版本选用NFSv4。有人会问为什么不用NFSv3这里多说一句NFSv3走的是portmap动态端口客户端要连服务端的多个端口防火墙上需要放开的端口范围比较杂乱而NFSv4固定走2049端口配合rpc.mountd的内部处理防火墙规则简单很多也更安全。如果你的环境还是老旧的NFSv3传统架构我建议尽早迁到v4。操作系统和软件包的对应关系大概是这样系统类型服务端软件包客户端软件包说明CentOS/RHEL 7nfs-utilsnfs-utils服务端和客户端都需要nfs-utilsUbuntu/Debiannfs-kernel-servernfs-common客户端只需要nfs-common其他Linux发行版按各自包管理器同左包名可能有差异原理一致为什么服务端和客户端都要装nfs-utils因为NFS本质上是一套RPC协议客户端需要rpcbind、mount.nfs等命令来发起挂载请求服务端需要rpc.nfsd、rpc.mountd来响应请求这些都包含在nfs-utils这个包里。2.2 挂载方式选型fstab还是autofs一开始我用的传统方式是直接写/etc/fstab格式大概是这样192.168.1.10:/data /mnt/data nfs4 defaults,_netdev 0 0但实际用下来问题很明显。第一fstab里的挂载是开机时就执行的如果NFS服务端当时不可用客户端开机过程会长时间卡住虽然加了_netdev参数有一定缓解但也只是等网络就绪后再挂服务端故障时照样卡顿。第二不管你有没有访问挂载点这个目录始终挂在系统里客户端这边既占inode也占内存里的vfsmount结构。第三fstab只做静态挂载不会因为你没使用这个目录就自动卸载。autofs的思路完全不同。它有一个核心守护进程autofs以及一套映射配置文件。客户端启动时只挂载一个很小的autofs入口目录当有人真正访问某个子目录时autofs才去执行真正的mount动作。空闲时间超过设定阈值默认300秒自动卸载。这等于把“长期占坑”变成了“用的时候才占”。对于服务器数量多、共享目录多、服务端经常维护重启的场景autofs的体验要好太多。3. NFS服务端完整配置步骤3.1 服务端软件安装与基础配置部署之前先把两台机器的hostname和/etc/hosts配好虽然IP直连也能用但NFS导出时建议使用主机名排查日志时一眼能看出是哪台客户端在访问。我在/etc/hosts里加了192.168.1.10 nfs-server 192.168.1.11 nfs-client服务端上先安装nfs-utilsyum install -y nfs-utils安装完成之后先把服务启起来并且设置开机自启。注意CentOS 7里的启动顺序有讲究systemctl enable rpcbind systemctl enable nfs-server systemctl start rpcbind systemctl start nfs-server为什么rpcbind先启用NFSv4虽然固定走2049但rpcbind服务仍然是NFS服务栈的一部分它负责管理NFS服务相关的RPC注册信息。如果你先启动nfs-server再启动rpcbind可能导致NFS服务没有正确完成RPC注册showmount -e时看不到任何共享。这个坑我遇到过好几次所以现在习惯先把rpcbind停掉再一起启动而不是单独重启某一个。3.2 共享目录规划与exports配置服务端上我规划了一个数据目录/data/share下面还有两个子目录给不同的项目组使用。先创建目录结构mkdir -p /data/share/project_a mkdir -p /data/share/project_b然后编辑/etc/exports这是NFS服务端的核心配置文件。我的配置如下/data/share 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)这里逐项拆开解释一下我为什么这么配。rw客户端可读写。sync写入时服务端同步落盘后才返回确认数据可靠性更高虽然牺牲一点性能但在生产环境值得。no_subtree_check关闭子树检查。所谓子树检查就是当共享目录是一个子目录时服务端要额外验证客户端访问的路径是否在导出范围内。关闭后减少服务端开销对于不复杂的目录结构是合理的。no_root_squash允许客户端的root用户以root权限访问共享目录。这里要特别提醒no_root_squash在生产环境有安全隐患只有在你完全信任客户端的情况下才建议开启。如果不加这个参数客户端的root会被映射为nfsnobody权限问题会让人抓狂。我还单独为项目目录做了更细的配置/data/share/project_a 192.168.1.11(rw,sync,no_subtree_check) /data/share/project_b 192.168.1.0/24(ro,sync,no_subtree_check)project_a只允许nfs-client这台机器读写project_b允许整个网段只读。实际配置时注意exports文件里如果同一个目录路径出现了多次以第一次匹配到的规则为准所以越具体的条目越要放在前面。配置写完之后执行exportfs命令让配置生效exportfs -ra-r表示重新导出所有目录-a表示导出所有。这个命令在修改exports后不用重启NFS服务就能生效比systemctl restart nfs-server要稳妥因为restart会短暂断掉正在使用的客户端连接。验证一下导出是否正常exportfs -v输出里能看到每个共享目录对应的客户端列表和权限参数一目了然。3.3 防火墙与常见安全配置CentOS 7默认开着firewalld如果不放行NFS服务客户端永远挂不上。前面说NFSv4只用2049端口实际上还要放行rpcbind的111端口因为客户端启动时需要先通过rpcbind查询NFS服务的RPC信息。firewall-cmd --permanent --add-servicenfs firewall-cmd --permanent --add-servicerpc-bind firewall-cmd --permanent --add-servicemountd firewall-cmd --reload这里有一个生产上常见的坑如果你只放行了nfs和rpc-bind而没有放行mountd客户端mount时会有延迟甚至失败。mountd默认端口是动态分配的在20048附近浮动firewalld的mountd服务规则会自动匹配rpc.mountd当前使用的端口。如果你用了iptables而不是firewalld就得把mountd端口固定下来否则每次重启服务端口都变防火墙规则就废了。固定mountd端口的方法是在/etc/sysconfig/nfs里设置RQUOTAD_PORT875 LOCKD_TCPPORT32803 LOCKD_UDPPORT32769 MOUNTD_PORT892设完之后重启NFS服务然后防火墙里放行这两个端口和2049、111即可。3.4 服务端常见问题检查服务端配置完先自测一下别急着去客户端挂载。在服务端本地查看RPC注册信息rpcinfo -p | grep nfs正常输出里能看到nfs服务在2049端口注册mountd在892端口或默认动态端口。再用showmount看本机导出了什么showmount -e localhost如果这里看不到任何共享说明exports配置或rpcbind有问题去/var/log/messages里搜nfs相关报错。4. 客户端autofs自动挂载实现4.1 客户端安装与基础准备客户端机器上同样需要nfs-utils另外还要安装autofsyum install -y nfs-utils autofs这里有人说客户端只用装autofs不用装nfs-utils这是不对的。autofs本身只是一个触发挂载的框架真正执行mount动作时还是调用mount.nfs这个命令它就在nfs-utils包里。不装的话会出现挂载操作失败但autofs日志又看不出明确报错的情况。安装完成后先不要启动autofs接下来配置好映射文件再启。4.2 autofs核心概念与配置结构autofs的配置架构分三层理解了这三层就理解了autofs的整个工作方式。第一层是主配置文件/etc/auto.master它定义了哪些入口目录交给autofs管理以及每个入口目录对应的映射文件是什么。我的配置如下/mnt/nfs /etc/auto.nfs --timeout300 --ghost这一行的含义是把/mnt/nfs这个目录作为autofs的挂载入口具体的挂载规则写在/etc/auto.nfs里空闲300秒后自动卸载--ghost参数表示即使某个子目录当前没有被挂载也会在/mnt/nfs下显示出来所谓的“幽灵目录”这样用户直接ls /mnt/nfs就能看到有哪些可用挂载点体验更好。第二层是映射文件比如/etc/auto.nfs。它定义了入口目录下的“子目录名”和“实际挂载来源”的对应关系。我的配置project_a -rw,sync 192.168.1.10:/data/share/project_a project_b -ro,sync 192.168.1.10:/data/share/project_b第三层是autofs守护进程本身它读取auto.master和映射文件监听入口目录的访问事件触发挂载。我用了间接映射的方式也就是通过/mnt/nfs/project_a这样的路径去访问。还有一种直接映射的写法auto.master里用/-作为入口配合auto.direct文件里写绝对路径适合那些挂载点分散在不同目录的情况。但间接映射更直观管理也方便所以我这边选了它。4.3 通配符映射与批量配置技巧如果共享目录非常多在映射文件里一个一个写显然低效。autofs支持通配符我后面又加了一行* -rw,sync 192.168.1.10:/data/share/这里的是一个特殊的通配符变量代表客户端访问的子目录名。比如访问/mnt/nfs/project_a时就是project_a自动对应服务端的/data/share/project_a。这种方式适合服务端共享目录和客户端子目录名字一一对应且结构统一的场景。但要注意aliases别名功能不会对通配符做转换所以不要在同一个映射文件里混用通配符和复杂别名规则否则排查问题时会怀疑人生。4.4 启动autofs并验证挂载配置改完之后先检查语法有没有问题automount -m这个命令会打印出当前的自动挂载配置概览如果有语法错误这里能直接看到。启动并设置开机自启systemctl enable autofs systemctl start autofs启动之后别急着直接访问先看一下/mnt/nfs这个入口目录的状态ls /mnt/nfs因为开了--ghost参数正常情况下能看到project_a和project_b两个目录。这时候它们其实还没有真正挂载只是autofs做了“幽灵目录”展示。等真正cd进去触发访问cd /mnt/nfs/project_a df -h .df输出里就能看到这个目录的来源是192.168.1.10:/data/share/project_a挂载类型是nfs4说明autofs已经帮你完成了NFS挂载。空闲超过300秒之后再用df看挂载点已经消失说明autofs自动卸载了。4.5 客户端对autofs的权限验证NFS本身不处理用户认证客户端用户是否拥有权限取决于服务端看到的UID/GID。比如服务端/data/share/project_a目录属主是UID 1001的用户alice客户端上UID 1001的用户whatever也一样能读写因为NFS协议层的权限校验只看UID数字不关心用户名。这就是为什么我建议在/etc/idmapd.conf里配置Domain尤其是在使用NFSv4并启用Kerberos安全机制时。如果不打算上Kerberos直接用AUTH_SYS也就是传统UID/GID校验就够用了但idmapd.conf里的Domain值最好还是设成一致避免某些场景下出现奇怪的映射问题。5. 常见问题与排障技巧5.1 挂载卡死怎么办客户端访问挂载点时卡住不动这是NFS环境里最常见也最让人头疼的问题。一般情况下原因是服务端无响应比如服务端宕机、网络中断、NFS服务假死。解决方法是在映射文件的挂载参数里加上软挂载和超时时间* -rw,sync,soft,timeo50,retrans2 192.168.1.10:/data/share/soft软挂载超时后返回错误而不是一直卡着。timeo50超时时间50个十分之一秒也就是5秒。retrans2超时后重传2次之后放弃。但要注意软挂载适合对数据一致性要求不高的场景。如果你跑的是数据库文件或需要严格同步写入的应用建议用hard挂载服务端恢复后自动继续不会返回错误导致应用数据错乱。这是个权衡数据可靠性优先选hard可用性优先选soft。如果已经卡死了可以尝试umount -f /mnt/nfs/project_a加上-f强制卸载。还不行就umount -l /mnt/nfs/project_a-l是lazy卸载先把挂载点从命名空间里摘除等内核IO完成后再清理资源。5.2 autofs没生效的排查思路先确认autofs进程是否在运行systemctl status autofs然后检查/etc/auto.master里的入口路径是否创建了如果入口目录不存在autofs启动时会自动创建但权限可能不对会导致无法访问。还要注意autofs启动之后如果你手动在入口目录下创建了一个与映射规则同名的普通目录映射会失效。因为autofs发现该目录已存在且不是它管理的挂载点时会直接忽略这个访问事件。所以一定要让autofs全权接管入口目录。排查时看日志最直接。CentOS 7里autofs的日志默认打到/var/log/messages里grep -i autofs /var/log/messages | tail -505.3 服务端修改exports后客户端不生效有时候调整了服务端的共享参数比如从ro改成rw客户端这边访问时发现还是只读。这是因为客户端保留着旧的挂载状态。最简单的方法是触发autofs卸载再重新访问umount /mnt/nfs/project_a ls /mnt/nfs/project_a第二次访问时会重新走挂载流程新的挂载参数就生效了。如果是fstab静态挂载可以用mount -o remount来重置参数。5.4 权限相关坑点汇总权限问题是NFS使用中最多人头疼的部分我把常见的整理成一个表现象原因解决办法客户端root无法写入root_squash默认开启root被映射为nfsnobody服务端exports加no_root_squash注意安全风险客户端普通用户无法写入服务端目录属主和客户端用户UID不一致chown修改服务端目录属主或在客户端用setfacl客户端能看到目录但打不开服务端目录权限不足确认服务端目录权限至少755或针对具体UID开权限创建文件后属主显示nobodyidmapd.conf配置不一致或未启动rpcidmapd统一定Domain重启rpcidmapd和nfs服务最后一条特别常见尤其在Ubuntu和CentOS混用的环境里。两边/etc/idmapd.conf里的Domain必须一致否则NFSv4的name映射会乱掉文件属主就变成nobody。5.5 网络与防火墙问题排查客户端这边遇到挂载超时的“卡脖子”问题第一步先ping服务端IP通了再检查2049端口通不通telnet 192.168.1.10 2049能通就说明基本网络没问题。再用showmount验证RPC层是否正常showmount -e 192.168.1.10如果这里能看到共享列表说明rpcbind和mountd都工作正常问题很可能出在autofs配置上。如果这里就报错查服务端防火墙和rpcbind状态。5.6 性能调优参数参考默认的NFS挂载参数在大多数场景下够用但如果传输大文件或高并发访问建议手动调整* -rw,sync,soft,timeo50,retrans2,rsize1048576,wsize1048576 192.168.1.10:/data/share/rsize和wsize分别代表读和写的数据块大小。CentOS 7的NFSv4默认单次读写最大1MB所以在客户端挂载参数里显式设置为10485761MB可以避免部分场景下默认值偏小的问题。不过如果网络质量差大块传输反而容易超时重传这时候适当调小到262144256KB可能更稳。5.7 生产环境中的独门经验我这边有一个场景是项目组同事会频繁重启自己的开发机如果NFS挂载是fstab静态挂载开机时NFS服务端还没就绪就会卡住至少要等系统超时才能进桌面。换autofs之后开机时根本不会去碰NFS只有真正进入挂载目录时才触发访问体验好了不止一个档次。还有个小细节autofs的--timeout参数单位是秒默认300秒已经比较合适。不要为了省资源把timeout设成60秒否则你刚打开目录里的文件回头再切回来又要重新走一次挂载流程延迟感很明显。我自己调了几台机器最终定在300~600秒之间比较舒服。最后分享一个实用小技巧如果你要临时给某台机器加一个共享目录访问不用改全家桶配置直接在/etc/auto.master里新增一行指向一个新的映射文件然后重启autofs就行。比如/mnt/dbbackup /etc/auto.dbbackup --timeout600 --ghost映射文件里backup -rw,soft,timeo50,retrans2 192.168.1.20:/data/backup这种按需扩容的方式在多服务器环境里维护成本最低。我用这套方案管理了公司十几台服务器的文件共享现在基本不碰fstab挂NFS了。
返回列表