部署基于gluster 分布式存储系统的 NFS-ganesha 高可用集群

这里介绍如何部署基于gluster 分布式存储系统的 NFS-ganesha 高可用集群。

gluster分布式存储系统的部署可以参考官网:Installing GlusterFS - a Quick Start Guide,虽然这里以glusterfs 为例里,但是其他分布式文件系统如cephfs,luster 的部署方式基本一致。

这是使用高可用集群管理组件为pacemaker,这是红帽等公司新版本主流使用的方式。

同时这里使用的Linux发行版本ubuntu信息如下:

复制代码
# cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

详细部署流程如下

前置条件:

安装并部署glusterfs 文件系统,部署可以参考官网:Installing GlusterFS - a Quick Start Guide

复制代码
root@ubuntu129226:~# 
root@ubuntu129226:~# gluster volume  info 
Volume Name: gluster_shared_storage
Type: Replicate
Volume ID: 33742d5a-38c3-48e3-b6ce-d2217d95a5c6
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: ubuntu129226:/var/lib/glusterd/ss_brick
Brick2: ubuntu129169:/var/lib/glusterd/ss_brick
Brick3: ubuntu129168:/var/lib/glusterd/ss_brick
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
cluster.enable-shared-storage: enable
Volume Name: gv1

Type: Replicate
Volume ID: 6ce76ff5-2261-4d52-93a9-9c0ce03032f4
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: ubuntu129226:/mnt/brick1/gv1
Brick2: ubuntu129168:/mnt/brick1/gv1
Brick3: ubuntu129169:/mnt/brick1/gv1
Options Reconfigured:
performance.client-io-threads: off
nfs.disable: on
transport.address-family: inet
storage.fips-mode-rchecksum: on
cluster.granular-entry-heal: on

一 安装要使用的软件包

复制代码
apt install pacemaker 
apt install resource-agents
// 我这里是自己编译的nfs-ganesha, 安装本地这些包
# ls nfs
libntirpc6.3_6.5-7_amd64.deb   nfs-ganesha-gluster_6.5-7_amd64.deb
libntirpc-dev_6.5-7_amd64.deb  nfs-ganesha-vfs_6.5-7_amd64.deb
nfs-ganesha_6.5-7_amd64.deb    python3-nfs-ganesha_6.5-7_all.deb
nfs-ganesha-doc_6.5-7_all.deb
apt install ./*

二 配置nsf-ganesha

部署gluster 分布式系统后,就可以通过nfs-ganesha 导出文件系统,只不过这里没有只是一个单节点的服务,无法避免单点故障,肯定不满足企业级业务的要求。

复制代码
# cat /etc/ganesha/ganesha.conf
NFS_CORE_PARAM
{
    Enable_NLM = false;
    Enable_RQUOTA = false;
    Protocols = 4;
    MNT_Port = 2067;
    NLM_Port = 2068;
    RQUOTA_Port = 2069;
    Unique_Server_Id = 1;
}

NFSv4
{
    RecoveryBackend = fs;
    Minor_Versions =  1,2;
}

LOG
{
    Facility
    {
        name = FILE;
        destination =  /var/log/ganesha/ganesha.log;
        enable = active;
    }
     COMPONENTS {
         ALL = FULL_DEBUG;
     }

}


EXPORT
{
    Export_ID = 1;
    Protocols = 4;
    Disable_ACL = TRUE;
    Transports = TCP;
    Path = /gv1;
    Pseudo = "/share";
    Attr_Expiration_Time = 0;
    CLIENT
    {
        Clients = *;
        Squash = No_Root_Squash;
        Access_Type = RW;
        Anonymous_Uid = 4294967294;
        Anonymous_Gid = 4294967294;
    }

    FSAL
    {
        #Name = vfs;
        Name = GLUSTER;
        hostname = "localhost";
        volume = "gv1";
    }

}

systemctl restart nfs-ganesha 拉起nfs ganesha 服务即可实现 nfs 协议导出glusterfs 文件系统。

现在nfs-ganesha的数据都保持在本地。nfs-ganesha高可用集群将数据报错在glusterfs文件系统上。所以这里要创建需要用到的gluster volume并挂载到系统。

复制代码
// 创建volume命令
gluster volume create gv-name  replica 3  host1:/mnt/brick1/gv1  host2:/mnt/brick1/gv1  host3:/mnt/brick1/gv1 
// 在每个网关节点挂载glsuterfs 
mount -t glusterfs localhost:/gv-name   /run/gluster/shared_storage

二 创建pacemaker集群

复制代码
对两个节点进行认证:
pcs host auth ubuntu129226 ubuntu129168 -u hacluster -p passwd

# 创建集群
pcs cluster setup HA-NFS ubuntu129226 ubuntu129168
# 启动集群
pcs cluster start --all
//把新节点添加进集群
pcs cluster node add ubuntu129168
pcs status
pcs cluster status

如果已经创建了集群,或者创建的集群有问题,可以清理脏的集群。

复制代码
# 清理集群
pcs cluster destroy
pcs cluster stop --force

三 创建pacemaker集群资源

复制代码
在 Ubuntu 上,请确保安装了 resource-agents 包(sudo apt install resource-agents),并检查该路径下是否存在 NFS 相关的代理脚本。
# ls /usr/lib/ocf/resource.d/heartbeat/ganesh*
/usr/lib/ocf/resource.d/heartbeat/ganesha_grace  /usr/lib/ocf/resource.d/heartbeat/ganesha_nfsd
/usr/lib/ocf/resource.d/heartbeat/ganesha_mon

# 创建 Ganesha 进程资源
pcs resource create nfsd_res ocf:heartbeat:ganesha_nfsd \
  op monitor interval=10s timeout=30s

# 创建哨兵监控资源
pcs resource create ganesha_mon_res ocf:heartbeat:ganesha_mon \
  op monitor interval=10s timeout=10s

# 将它们设为 Clone 资源(意味着集群内的每个节点都会常驻运行这两个进程)
pcs resource clone nfsd_res
pcs resource clone ganesha_mon_res

# 1. 创建基础的 grace 资源
pcs resource create ganesha_grace_res ocf:heartbeat:ganesha_grace \
  op monitor interval=5s timeout=20s

# 2. 将其克隆,并强制开启集群通知机制(非常重要)
pcs resource clone ganesha_grace_res clone-max=2 clone-node-max=1 notify=true

pcs resource create ganesha-vip ocf:heartbeat:IPaddr2 \
  ip="192.168.115.168" cidr_netmask=24 \
  op monitor interval=10s

这些资源并不是相关孤立的,ganesha-vip 必须运行在 nfs-ganesha 正常的节点上,所以要创建资源约束

ganesha_mon 负责监控nfs-ganesha 进程是否正常,并将集群属性值ganesha-active 设置为1,这里约束ganesha-active为1时才能创建浮动IP 资源

复制代码
pcs constraint location ganesha-vip rule score=INFINITY ganesha-active eq 1

这种约束在所有节点的nfs-ganesha 都不正常时,会随机选择一个节点创建浮动IP 服务。也可以要求nfs-ganesha 不正常都允许创建浮动IP资源服务。

复制代码
pcs constraint location delete ganesha-vip
pcs constraint location ganesha-vip rule score=-INFINITY ganesha-active ne 1

四 启动nfs-ganesha 并调试

在每个节点启动 systemctl restart nfs-ganesha

nfs-ganesha启动之后pacemaker集群并不会自动更新,

复制代码
root@ubuntu129226:/var/run/gluster/shared_storage/nfs-ganesha# attrd_updater --query --name=ganesha-active
name="ganesha-active" host="host1" value=""
name="ganesha-active" host="host2" value=""
root@ubuntu129226:/var/run/gluster/shared_storage/nfs-ganesha# attrd_updater --query --name=grace-active
name="grace-active" host="host1" value=""
name="grace-active" host="host2" value="1"

需要执行命令更新

复制代码
# pcs resource cleanup
Cleaned up all resources on all nodes
Waiting for 1 reply from the controller
... got reply (done)
# pcs resource cleanup
Cleaned up all resources on all nodes
Waiting for 1 reply from the controller
... got reply (done)

高可用集群恢复正常

复制代码
# pcs status
Cluster name: HA-NFS
Cluster Summary:
  * Stack: corosync
  * Current DC: ubuntu129226 (version 2.1.2-ada5c3b36e2) - partition with quorum
  * Last updated: Wed Oct 21 16:53:55 2026
  * Last change:  Wed Oct 21 15:57:22 2026 by hacluster via crmd on host1
  * 2 nodes configured
  * 7 resource instances configured

Node List:
  * Online: [ host1 host2 ]

Full List of Resources:
  * Clone Set: nfsd_res-clone [nfsd_res]:
    * Started: [ host1 host2]
  * Clone Set: ganesha_mon_res-clone [ganesha_mon_res]:
    * Started: [ host1 host2 ]
  * Clone Set: ganesha_grace_res-clone [ganesha_grace_res]:
    * Started: [ host1  host2]
  * ganesha-vip (ocf:heartbeat:IPaddr2):         Started host2

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

我们可以看到nfs-ganesha的数据已经保持到glusterfs 文件系统上

复制代码
# ls /var/lib/nfs  -lh
lrwxrwxrwx 1 root root 56 Oct 21 11:53 /var/lib/nfs -> /run/gluster/shared_storage/nfs-ganesha/host1/nfs

在客户端使用nfs协议挂载共享目录

复制代码
# mount -t nfs -o vers=4,noresvport 192.168.115.168:/share  /mnt/share
# ls /mnt/nas/
testfile

五 高可用集群原理分析

GlusterFS 官方利用高可用组件Pacemaker, 实现 Active-Active(双活)NFS-Ganesha 集群 NAS

ganesha_nfsd 资源代理:

职责:创建和监控 Ganesha 的状态目录指向共享存储。

目的:对于 NFSv4,如果主节点故障,备节点接管时必须能读取到主节点留下的状态信息(State)才能保证无损切换。

ganesha_mon 资源代理:

职责:监控本地 Ganesha 的 PID 文件状态(即监控nfs-ganesha),动态更新 Pacemaker 集群的节点属性。

目的:NFS-Ganesha 进程与 Pacemaker 集群之间的"通信桥梁"。

ganesha_grace 资源代理:

职责:

监控ganesha_mon设置的集群属性,如果属性值异常则执行以下操作

1 通过集群所有节点,执行D-Bus命令,让本地 Ganesha 进程进入宽限期

2 等待5秒后,触发VIP 漂移的条件(只是设置一个属性值)。

目的:通过 Pacemaker 的通知(Notify)机制和集群属性(Attribute),确保集群中所有节点在 VIP 漂移时能够同步进入宽限期(Grace Period)。

pacemaker 集群管理:

1 NFSv4 共享状态路径规划:

共享存储中为每个节点创建独立的恢复目录,并交叉建立节点间的软链接。确保在vip 漂移时能够读取原节点上的NFSv4状态信息。

2 VIP 约束和故障转移节点

如果节点ganesha_mon 监控的nfs-ganesha 服务故障使得集群节点属性异常,则触发IP漂移。

通过节点权重循环累加,为VIP 分配漂移优先顺序。

3 高可用核心流程编排

首先创建 ${node}-nfs_block 资源,当 VIP 准备漂移到一个新节点时,首先在该节点堵塞 2049 端口。

顺序约束:广播事件执行完(通知其他节点进入宽限期),才能执行 VIP 漂移:

故障转移场景的分析

当上面的命令全部执行完后,你的集群就拥有了智能的 NFSv4 状态保护链:

  1. 正常状态下:
    两台机器都跑着 nfsd。host1 上的 ganesha_mon 检查健康,向集群宣告本地的 ganesha-active=1。Pacemaker 看到这个属性,便把 ganesha-vip 和 ganesha_grace 调度到 host1 上运行。
  2. 发生异常时:
    host1 上的 Ganesha 挂掉 ganesha_mon 优先捕捉到,它并不会直接让 VIP 切换,而是调用脚本先删除当前节点的 grace-active 标签 (\rightarrow ) 触发其余在线节点的 ganesha_grace 立刻进入锁保护宽限期 强制 sleep 5(等待 5 秒锁环境就绪)最终删除 ganesha-active 属性。
  3. VIP 漂移:
    Pacemaker 感知到 host1 的 ganesha-active 变为无效,便根据第三步与第四步的规则,自动将 ganesha-vip 和 ganesha-grace 平滑地转移至健康的 host2 上。此时客户端的 NFSv4 连接只会有几秒短暂的 IO 停顿,随后通过宽限期安全收回旧锁,彻底避免挂载点卡死
相关推荐
极小狐2 天前
极狐GitLab双机热备搭建指南,主机备机部署与切换实操
gitlab·高可用·极狐gitlab
zzu123zsw2 天前
业务拆分后的治理深水区:解构企业级微服务六大核心设计模式与高可用落真实践
微服务·设计模式·架构·高可用·微服务架构设计
Sayai4 天前
Neo4j 社区版高可用实战:DRBD 块级复制 + Keepalived 虚拟 IP 冷备切换(附启停 SOP 与脑裂防范)
运维·neo4j·keepalived·高可用·drbd
我不会起名字3226 天前
Redis 从 0 到 1(九):主库宕机 30 秒自动切主——1 主 2 从 3 哨兵 + Go 客户端
redis·docker·sentinel·高可用·哨兵
熊出没11 天前
高并发高可用系统设计:限流、熔断、降级与多级缓存实战指南
缓存·高并发·架构设计·高可用
光依旧12 天前
发版就掉请求?Spring Boot优雅停机的四步
运维·spring boot·nginx·高可用·优雅停机·mcp server
骑着蜗牛撵大象32713 天前
服务下线不再炸:分层关闭、TCP 存活探测与负载均衡排水的落地套路
android·tcp/ip·负载均衡·tcp·高可用·健康检查·优雅关闭
.冰块.14 天前
MySQL下篇 运维实战:备份恢复 + 主从复制 + MHA 高可用,含完整拓扑
运维·mysql·读写分离·高可用·主从复制·mha
螺蛳粉 螺蛳粉14 天前
第五篇:Keepalived + LVS 四层负载均衡高可用实战:DR 模式全流程
运维·负载均衡·lvs·keepalived·高可用