nfs-ganesha 本身不提供高可用,因其为单进程用户态服务,无内置集群或自动故障转移能力;高可用必须依赖外部编排(如 pacemaker+corosync)、共享存储(drbd/cephfs)和客户端合理挂载参数协同实现。

为什么 NFS-Ganesha 本身不提供高可用
NFS-Ganesha 是个用户态 NFS 服务器,它自己没有内置集群或故障自动转移能力。你启动一个 nfs-ganesha 进程,它就只跑在一台机器上;进程挂了,NFS 服务就断了;机器宕了,客户端直接收到 Stale file handle 或长时间卡在 ls。真正的高可用得靠外部机制兜底。
常见错误是以为配好 ganesha.conf、启了服务就“高可用”了——其实只是单点更稳一点,离 HA 还差一层编排。
- 必须搭配集群管理器(如 Pacemaker + Corosync)做资源接管
- 共享存储(如 DRBD、SAN LUN、或同一套后端 CephFS/GPFS)要能被两个节点同时看到,且锁机制兼容
- 虚拟 IP(VIP)必须漂移,否则客户端 DNS 或 /etc/hosts 指向的还是旧地址
用 Pacemaker 配置 NFS-Ganesha 资源组的关键步骤
Pacemaker 是目前最成熟、生产验证过的 NFS-Ganesha HA 方案。它不依赖 Ganesha 内部功能,而是把 nfs-ganesha 当作一个可启停、可监控的普通服务来管理。
典型资源组结构:IPaddr2(VIP)→ Filesystem(挂载后端存储)→ nfsganesha(Ganesha 服务),三者强顺序依赖。
-
nfsganesha资源代理脚本必须存在:检查/usr/lib/ocf/resource.d/heartbeat/nfsganesha,CentOS/RHEL 8+ 自带,Ubuntu 需手动装resource-agents包 - 确保
ganesha.conf中禁用 PID 文件竞争:Pid_File = /var/run/ganesha.pid改成Pid_File = /var/run/ganesha-<em>$(hostname)</em>.pid,避免脑裂时双写冲突 - 监控间隔不能太长:建议
op monitor interval="30s" timeout="30s",否则故障发现延迟高,客户端重试窗口拉太长
客户端挂载时容易忽略的超时与重传参数
即使服务端做了 Pacemaker 切换,客户端如果还卡在旧节点上,会等很久才重连。这不是服务端问题,而是 mount 默认行为太“固执”。
现象:主节点宕机后,客户端 ls /mnt/nfs 卡住 90 秒以上,甚至报 Connection timed out 而不是立刻失败。
- 必须加
timeo=10(单位为 0.1 秒,即 1 秒超时)和retrans=3,避免默认的 60 秒重传等待 - 推荐完整挂载选项:
mount -t nfs -o rw,hard,intr,timeo=10,retrans=3,nfsvers=4.2,proto=tcp <em>vip:/export</em> /mnt/nfs - 不要用
soft:虽然不卡,但会静默丢数据,违反 NFS 语义;hard+ 合理timeo才是可靠组合
DRBD 和 CephFS 做后端时的锁与一致性差异
后端存储类型直接影响 Ganesha 高可用的可靠性边界。不是所有“共享存储”都适合。
DRBD(主从模式):切换时需确保 Pacemaker 先 demote DRBD 主节点,再 stop Ganesha,否则新主节点读到脏页;Ganesha 的 cache_invalidation 必须开,否则元数据缓存不同步。
CephFS(原生多活):更简单,但要注意 ceph auth 密钥必须在两节点一致,且 Ganesha 的 cephx 认证配置里不能写死 keyring 路径,要用绝对路径并确保权限为 600,否则 Pacemaker 切换后因权限问题无法读密钥。
- DRBD 场景下,
ganesha.conf中Cache_Invalidation = true是强制项,否则 stat/mtime 可能返回旧值 - CephFS 场景下,禁用 Ganesha 的
export_block内部锁(设为false),靠 Ceph 自身分布式锁即可,否则反而引发死锁 - 无论哪种后端,
ganesha.conf中的Export_Id必须全局唯一且固定,Pacemaker 切换前后不能变,否则客户端会认为是全新文件系统











