主题
NFS 高可用存储部署指南
方案概述
- 架构:GlusterFS 3 副本复制卷 + NFS-Ganesha + Keepalived VIP
- 节点数:3 台(推荐奇数,便于仲裁)
- 后端存储:各节点本地磁盘,无需 SAN/iSCSI
- 客户端:普通 Linux 服务器 + Kubernetes 集群
- 部署方式:手动步骤
- 不加密:按默认配置部署
架构图
┌─────────────────┐
│ Keepalived │
│ VIP: 10.0.0.100│
└────────┬────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ node1 │ │ node2 │ │ node3 │
│ NFS-Ganesha│ │ NFS-Ganesha│ │ NFS-Ganesha│
│ GlusterFS │◄─►│ GlusterFS │◄─►│ GlusterFS │
│ /dev/sdb │ │ /dev/sdb │ │ /dev/sdb │
└─────────────┘ └─────────────┘ └─────────────┘
▲ ▲ ▲
│ │ │
└─────────────────┴─────────────────┘
3 副本复制卷
│
┌──────────────┴──────────────┐
▼ ▼
Linux 客户端 mount K8s NFS Provisioner环境规划
| 节点 | IP | 角色 | 数据盘 |
|---|---|---|---|
| node1 | 10.0.0.11 | GlusterFS + Ganesha + Keepalived | /dev/sdb |
| node2 | 10.0.0.12 | GlusterFS + Ganesha + Keepalived | /dev/sdb |
| node3 | 10.0.0.13 | GlusterFS + Ganesha + Keepalived | /dev/sdb |
| VIP | 10.0.0.100 | 浮动 IP,客户端统一入口 | - |
请根据实际网络替换 IP 和网卡名称。
前置准备(所有节点执行)
1. 设置主机名
bash
# node1
hostnamectl set-hostname node1
# node2
hostnamectl set-hostname node2
# node3
hostnamectl set-hostname node32. 配置 /etc/hosts
bash
cat <<EOF >> /etc/hosts
10.0.0.11 node1
10.0.0.12 node2
10.0.0.13 node3
EOF3. 关闭防火墙或放行端口
bash
# Ubuntu
ufw disable
# RHEL/CentOS/Rocky
systemctl stop firewalld
systemctl disable firewalld如需放行,GlusterFS 主要端口:
- 24007-24008(GlusterFS 守护进程)
- 49152+(brick 端口,每个卷一个)
- 2049(NFS,Ganesha 使用)
- 111(rpcbind,可选)
4. 时间同步
bash
# Ubuntu
apt install -y chrony
systemctl enable --now chronyd
# RHEL/CentOS/Rocky
dnf install -y chrony
systemctl enable --now chronyd5. 格式化并挂载数据盘
bash
# 确认磁盘路径,以下以 /dev/sdb 为例
mkfs.xfs -f -i size=512 /dev/sdb
mkdir -p /data/brick1
mount /dev/sdb /data/brick1
echo '/dev/sdb /data/brick1 xfs defaults 0 0' >> /etc/fstab安装 GlusterFS(所有节点执行)
Ubuntu 22.04
bash
apt update
apt install -y software-properties-common
add-apt-repository ppa:gluster/glusterfs-11 -y
apt update
apt install -y glusterfs-server
systemctl enable --now glusterdRHEL/CentOS/Rocky 9
bash
dnf install -y centos-release-gluster11
dnf install -y glusterfs-server
systemctl enable --now glusterd验证服务
bash
systemctl status glusterd组建 GlusterFS 集群(在 node1 执行)
bash
gluster peer probe node2
gluster peer probe node3
# 查看集群状态
gluster peer status应看到 2 个 peers in cluster。
创建 3 副本复制卷(在 node1 执行)
bash
gluster volume create gv0 replica 3 \
node1:/data/brick1/gv0 \
node2:/data/brick1/gv0 \
node3:/data/brick1/gv0 force
gluster volume start gv0
# 查看卷状态
gluster volume info gv0
gluster volume status gv0启用常用优化
bash
gluster volume set gv0 storage.fips-mode-rchecksum on
gluster volume set gv0 performance.cache-size 256MB
gluster volume set gv0 performance.io-thread-count 16
gluster volume set gv0 network.ping-timeout 5安装 NFS-Ganesha(所有节点执行)
Ubuntu 22.04
bash
apt install -y nfs-ganesha nfs-ganesha-glusterRHEL/CentOS/Rocky 9
bash
dnf install -y nfs-ganesha nfs-ganesha-gluster配置 NFS-Ganesha(所有节点执行)
编辑 /etc/ganesha/ganesha.conf:
bash
cat > /etc/ganesha/ganesha.conf <<'EOF'
EXPORT {
Export_Id = 1;
Path = "/gv0";
Pseudo = "/gv0";
Protocols = 3, 4;
Access_Type = RW;
Squash = No_Root_Squash;
FSAL {
Name = GLUSTER;
Hostname = localhost;
Volume = "gv0";
}
}
LOG {
Default_Log_Level = INFO;
}
EOF
Hostname = localhost表示 Ganesha 通过本地 GlusterFS 客户端访问卷,每个节点独立工作。
启动服务:
bash
systemctl enable --now nfs-ganesha
systemctl status nfs-ganesha验证导出:
bash
showmount -e localhost应输出:
Export list for localhost:
/gv0 *安装并配置 Keepalived(所有节点执行)
安装
bash
# Ubuntu
apt install -y keepalived
# RHEL/CentOS/Rocky
dnf install -y keepalivednode1 配置
创建 /etc/keepalived/keepalived.conf:
bash
cat > /etc/keepalived/keepalived.conf <<'EOF'
vrrp_script check_ganesha {
script "/usr/bin/systemctl is-active nfs-ganesha"
interval 2
weight -50
fall 2
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
check_ganesha
}
}
EOF将
eth0替换为实际网卡名。
node2 配置
bash
cat > /etc/keepalived/keepalived.conf <<'EOF'
vrrp_script check_ganesha {
script "/usr/bin/systemctl is-active nfs-ganesha"
interval 2
weight -50
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
check_ganesha
}
}
EOFnode3 配置
bash
cat > /etc/keepalived/keepalived.conf <<'EOF'
vrrp_script check_ganesha {
script "/usr/bin/systemctl is-active nfs-ganesha"
interval 2
weight -50
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
check_ganesha
}
}
EOF启动 Keepalived
bash
systemctl enable --now keepalived
systemctl status keepalived查看 VIP 当前所在节点:
bash
ip addr show eth0客户端挂载
Linux 客户端
bash
# 安装 NFS 客户端
# Ubuntu
apt install -y nfs-common
# RHEL/CentOS/Rocky
dnf install -y nfs-utils
# 创建挂载点
mkdir -p /mnt/nfs-ha
# 临时挂载
mount -t nfs -o vers=4.1,hard,intr,timeo=600,retrans=3 10.0.0.100:/gv0 /mnt/nfs-ha
# 永久挂载(写入 /etc/fstab)
echo '10.0.0.100:/gv0 /mnt/nfs-ha nfs4 defaults,_netdev,hard,intr,timeo=600,retrans=3 0 0' >> /etc/fstabKubernetes 客户端
使用 nfs-subdir-external-provisioner 动态供给 PVC。
1. 添加 Helm 仓库
bash
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update2. 安装 Provisioner
bash
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=10.0.0.100 \
--set nfs.path=/gv0 \
--set storageClass.defaultClass=true3. 创建测试 PVC
yaml
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
EOF验证与故障测试
1. 检查 NFS 导出
在任意客户端:
bash
showmount -e 10.0.0.1002. 写数据测试
bash
dd if=/dev/zero of=/mnt/nfs-ha/testfile bs=1M count=100
ls -lh /mnt/nfs-ha/testfile3. 单节点故障测试
bash
# 1. 找到当前持有 VIP 的节点
ip addr show eth0 | grep 10.0.0.100
# 2. 在该节点停止 Ganesha
systemctl stop nfs-ganesha
# 3. 观察 VIP 是否漂移到其他节点
ip addr show eth0 | grep 10.0.0.100
# 4. 在客户端验证挂载仍然可用
touch /mnt/nfs-ha/failover-test
ls -l /mnt/nfs-ha/failover-test预期:VIP 在数秒内漂移到健康节点,客户端 IO 短暂停顿后恢复。
4. GlusterFS 自愈验证
当某个节点离线后又恢复,GlusterFS 会自动同步期间变更的数据:
bash
gluster volume heal gv0 info如看到 Number of entries: 0,说明无需修复。
日常运维命令
bash
# 查看 GlusterFS 集群节点
gluster peer status
# 查看卷信息
gluster volume info gv0
# 查看卷状态
gluster volume status gv0
# 查看 Ganesha 导出
cat /var/run/ganesha/export-1
# 查看 Keepalived 日志
journalctl -u keepalived -f
# 查看 Ganesha 日志
journalctl -u nfs-ganesha -f
# 触发 GlusterFS 修复
gluster volume heal gv0
# 查看存储使用情况
df -h /data/brick1注意事项
- 网络稳定性:GlusterFS 对网络延迟敏感,节点间建议千兆及以上,延迟越低越好。
- 脑裂防护:3 副本复制卷天然有仲裁能力,单节点故障不会脑裂;请勿在生产环境中使用 2 副本。
- 备份策略:高可用不等于备份,建议定期将关键数据异地备份。
- 性能调优:如遇到性能瓶颈,可调整
performance.*参数或增加 brick 数量。 - 防火墙:如果必须开启防火墙,请放行 GlusterFS、NFS-Ganesha、Keepalived(VRRP 协议 112)所需端口。
附录:卸载与清理
如需彻底清理环境:
bash
# 停止并删除卷(在 node1 执行)
gluster volume stop gv0
gluster volume delete gv0
# 断开 peer 关系(在 node1 执行)
gluster peer detach node2
gluster peer detach node3
# 停止服务(所有节点)
systemctl stop nfs-ganesha keepalived glusterd
systemctl disable nfs-ganesha keepalived glusterd
# 卸载数据盘
umount /data/brick1
rm -rf /data/brick1文档版本:v1.0
适用系统:Ubuntu 22.04 / RHEL 9 / Rocky Linux 9