容器云后端存储NFS高可用适配
容器云后端存储NFS高可用适配方案
1. 背景及痛点
经规划数据中心生产环境各大生产业务系统将全部迁移至长沙,为提高数据安全性,在存储架构上首先应该保障高可用,并做备份方案!但是容器云KubeGien本身自带的存储方案 NFS,是不具备高可用性的,这受限于NFS本身的单点架构特点,因此准备做此次适配。
2. 方案选型
| 方案 | 数据同步 | VIP 漂移 | DRBD 主备切换 | 是否自动故障转移 | 风险 |
|---|---|---|---|---|---|
| NFS + DRBD + Keepalived | 自动 | 自动 | 需手动 | 手动干预 | Split-brain 风险低 |
| NFS + DRBD + Pacemaker/Corosync | 自动 | 自动 | 自动 | 全自动 | 如果没配 STONITH,split-brain 风险高 |
| 分布式存储(CephFS/GlusterFS/XSKY) | 自动多副本 | VIP/原生访问 | 无需切换 | 天生高可用 | 成本高,架构复杂 |
目前,已经做了XSKY的适配和测试,但是由于内部环境的一些限制,XSKY暂时还不满足现状,所以选用NFS+DRBD+Pacemaker/Corosync的方案,前期为了低风险,防止出现 Split-Brain(脑裂),暂时不启用Pacemaker/Corosync,选用NFS + DRBD + Keepalived架构方案。
3. 架构概览
3.1 架构原理
- 两台服务器通过 DRBD 做 块级别同步(主从),同步模式选 Protocol C(同步写),保证数据写入安全。
- 两台机器运行 NFS 服务,只有主节点对外提供 NFS(通过 Keepalived 提供 VIP),主节点挂了时 VIP 漂移到备节点并把 DRBD 切换为主,从而继续提供 NFS。
- Kubernetes 指向 VIP 挂载 NFS(StorageClass / PersistentVolume 的 server 使用 VIP)。
优点:实现近实时(同步)数据一致性、主节点故障后自动切换;对现有 NFS 工作负载透明。
- Pacemaker/Corosync: 集群管理软件。负责:
- 监控两台服务器的健康状态(心跳)。
- 管理一个虚拟IP(VIP),客户端只连接这个IP。
- 提升DRBD资源为主(Primary)或降为备(Secondary)。
- 挂载DRBD设备(现在是
/dev/drbd0)到目录(如/nfs_share)。 - 启动和停止NFS服务。
3.2 数据流向
- 客户端通过 VIP 写入数据到 主节点 的NFS服务。
- 主节点的NFS服务将数据写入它挂载的目录
/nfs_share。 /nfs_share对应着块设备/dev/drbd0。- DRBD 立即将写入
/dev/drbd0的块数据,通过网络同步到备节点的/dev/drbd0设备上。 - 至此,数据已经安全地存在了两台服务器的硬盘上。
3.3 故障切换(Failover):
在加入Pacemaker/Corosync集群前,采用人工切换方式,大概1-2分钟,具体切换方案这里不再赘述!
加入Pacemaker/Corosync集群后:
- 主节点宕机后, Pacemaker 会检测到。
- 在备节点上执行以下操作:
a. 将备节点的 DRBD 设备提升为 主(Primary)。
b. 将 DRBD 设备挂载到/nfs_share。
c. 启动 NFS 服务。
d. 将 VIP 绑定到备节点的网卡上。 - 客户端重连 VIP,服务恢复。整个过程数据零丢失(因为是同步复制)。
4. 方案落地
4.1 环境准备
假设我们有两台服务器,保证时钟同步(建议 chrony/ntp):
- nfs-node1: 10.62.107.14
- nfs-node2: 10.62.107.15
- 虚拟IP (VIP): 10.62.107.16
- 共享数据目录:
/nfs_share - DRBD 资源名:
nfs_res - DRBD 使用的磁盘: 两台服务器上各有一块未使用的磁盘
/dev/sdb - 双向网络连通、无防火墙阻挡(drbd 使用 7789、keepalived 使用 VRRP 协议 112;NFS 视版本开放相应端口)
4.2 部署安装
在两台主机上执行(替换 yum -> dnf 若为 Rocky8/centos8):
# 启用 EPEL
sudo yum install -y epel-release
# 安装 drbd-utils/drbd kernel module 以及 nfs + keepalived
sudo yum install -y drbd-utils kmod-drbd nfs-utils keepalived # 如在现有容器云操作nfs已安装则不需要再安装nfs-utils
# 开启并启用必要服务(先手动启动配置)
sudo systemctl enable --now nfs-server
sudo systemctl enable --now keepalived
# drbd module 会随 drbdadm 操作加载
## 验证
drbdadm --version
cat /proc/drbd
------------------------------------------------------------------------------------------------------
# 针对 银河麒麟这样的国产化机器,可能无法加载epel-release,也下载不了drbd-utils 用户态工具,则可以按照下面的方法:
#1. 一般都内置 DRBD 模块,开启即可
modprobe drbd
lsmod | grep drbd
#2 源码安装drbd-utils 和 kmod-drbd
# 2.1 安装编译工具
yum groupinstall -y "Development Tools"
yum install -y gcc gcc-c++ make automake autoconf libtool flex bison kernel-devel-$(uname -r) kernel-headers-$(uname -r)
# 2.2 获取源码
git clone https://github.com/LINBIT/drbd-utils.git
cd drbd-utils
./autogen.sh
./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --without-manual
make
make install
# DRBD 内核模块如果系统没有,需要从 drbd 仓库编译:
git clone https://github.com/LINBIT/drbd.git
cd drbd
make KDIR=/lib/modules/$(uname -r)/build
make install
## 验证
drbdadm --version
cat /proc/drbd
4.3 配置 DRBD (在两台节点上执行)
- 磁盘及分区准备:
# 清理分区表(谨慎)
sudo sgdisk --zap-all /dev/sdb
# 创建一个 single partition covering whole disk (example)
/sbin/parted -s /dev/sdb mklabel gpt mkpart primary 1MiB 100%
# 使用 /dev/sdb1 作为后端,或直接用 /dev/sdb
- 创建 DRBD 配置文件
/etc/drbd.d/nfs_res.res
在两台节点上创建 /etc/drbd.d/nfs_res.res(注意:resource name 与 device/hosts):
cat > /etc/drbd.d/nfs_res.res << EOF
resource nfs_res {
protocol C; # 使用同步协议,确保数据强一致性
# startup {
# become-primary-on both;
# }
# disk {
# on-io-error detach;
# }
# net {
# cram-hmac-alg "sha1";
# shared-secret "my-secret-key"; # 设置一个密钥用于通信验证
# after-sb-0pri discard-zero-changes;
# after-sb-1pri discard-secondary;
# after-sb-2pri disconnect;
# }
on kubegien-arm-02 {
device /dev/drbd0;
disk /dev/vdb1;
address 10.62.107.14:7788;
meta-disk internal;
}
on kubegien-arm-03 {
device /dev/drbd0;
disk /dev/vdb1;
address 10.62.107.15:7788;
meta-disk internal;
}
}
EOF
- 初始化并启动 DRBD (两台主机都执行)
# 创建资源元数据
drbdadm create-md nfs_res
# 启用资源
drbdadm up nfs_res
# 在主节点上强制把数据覆盖到备(首次初始化仅在确认主节点数据为准时使用)
drbdadm -- --overwrite-data-of-peer primary nfs_res
- 在初始节点(nfs-node1)上强制设置为 Primary
# 在 nfs-node1 上执行
drbdadm primary nfs_res --force
- 查看同步状态
watch -n 1 'drbdadm status nfs_res'
# 或
cat /proc/drbd
等待 status 从 Inconsistent 变为 UpToDate,表示初始同步完成。同步速度取决于磁盘大小和网络速度。
注意: 如果配置使用Pacemaker/Corosync集群管理 则不需要执行下面的操作:
- 创建文件系统并挂载(仅在主节点,已做 overwrite 时)
在主节点(当前为 PRIMARY):
# 等 drbd 同步完成(watch cat /proc/drbd 同步状态)
sudo mkfs.xfs -f /dev/drbd0 # 或 ext4: mkfs.ext4 /dev/drbd0
sudo mkdir -p /srv/nfs/share
sudo mount /dev/drbd0 /srv/nfs/share
# 可加入 /etc/fstab 持久挂载(use _netdev? 但 DRBD 管理下慎放)
echo '/dev/drbd0 /srv/nfs/share xfs defaults 0 0' | sudo tee -a /etc/fstab
- 配置 NFS 导出
编辑 /etc/exports:
/srv/nfs/share 10.0.0.0/24(rw,sync,no_subtree_check,no_root_squash)
然后 reload exports:
sudo exportfs -ra
sudo systemctl restart nfs-server
确认 NFS 服务监听 VIP 所在接口(但 VIP 还没配置前是当前主机 IP)。
- Keepalived 配置 VIP(高可用 IP 提供)
在两台机器上分别创建 /etc/keepalived/keepalived.conf,主/备两份配置主要 state 不同,或使用相同并以优先级区分。
8.1 先写一个检测 NFS 服务是否健康的脚本,比如 /usr/local/bin/check_nfs.sh:
#!/bin/bash
# 检查 DRBD + NFS 状态 (CSI NFS 场景)
# 只有 Primary 且内核 nfsd 线程存在时返回 0
# 1. 检查 DRBD 是否是 Primary
if ! grep -q 'ro:Primary' /proc/drbd; then
exit 1
fi
# 2. 检查 NFS 内核线程是否存在
if ! ps -ef | grep -q "[n]fsd"; then
exit 1
fi
# 3. 可选:确认导出目录是否存在
if ! exportfs -v 2>/dev/null | grep -q '/YuanQiNFS'; then
exit 1
fi
exit 0
加权限:
chmod +x /usr/local/bin/check_nfs.sh
8.2 主节点配置 /etc/keepalived/keepalived.conf
重要:把
interface eth0改为实际网卡名。
两台机器的virtual_router_id必须一致(如 51),auth_pass一致。
主节点优先级高(如 150),备节点低(如 100)。
示例(nfs-node1 主机,priority 150):
! Configuration for Keepalived (NFS + DRBD)
global_defs {
router_id NFS_HA
}
vrrp_script chk_nfs {
script "/usr/local/bin/check_nfs.sh"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_NFS {
state MASTER
interface eth0 # 替换为实际网卡名
virtual_router_id 51
priority 150 # 主节点优先级高
advert_int 1
authentication {
auth_type PASS
auth_pass nfsdrbd
}
virtual_ipaddress {
10.62.107.200/24 # 设置 VIP,必须在 NFS 网络段内
}
track_script {
chk_nfs
}
}
8.3 备节点配置 /etc/keepalived/keepalived.conf
在nfs-node2(备)上 state BACKUP,priority 100。virtual_router_id 保持一致。
check_nfs.sh 示例(放 /usr/local/bin/check_nfs.sh,确保可执行):
global_defs {
router_id NFS_HA
}
vrrp_script chk_nfs {
script "/usr/local/bin/check_nfs.sh"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_NFS {
state BACKUP
interface eth0
virtual_router_id 51
priority 100 # 比主节点低
advert_int 1
authentication {
auth_type PASS
auth_pass nfsdrbd
}
virtual_ipaddress {
10.62.107.200/24
}
track_script {
chk_nfs
}
}
启动 Keepalived:
systemctl enable --now keepalived
检查 VIP 是否在主机上(ip addr)并能被其他机器 ping 通。
ip addr show enp1s0 | grep VIP
在主节点应该能看到 VIP
10.62.107.200停止主节点
systemctl stop nfs-server,VIP 应该漂移到备节点恢复主节点
systemctl start nfs-server,VIP 会回切
4.4 首次同步与切换验证
- 主nfs节点创建测试文件:
echo "hello from a" | sudo tee /YuanQiNFS/hello_a.txt
在备机上查看(在备机如果未挂载 /dev/drbd0 为 Secondary,它 不能 直接 mount 为读写。可临时把它切换为 Primary 来检查数据,或使用
drbdadm role查看状态)。但可以使用 drbd-tools 命令查看同步状态。测试 VIP 漂移:
- 模拟主节点失败:
sudo systemctl stop keepalived nfs-server或断网。 - 备机应接管 VIP:
ip addron nfs-b shows VIP. - 在备机上把 DRBD 升为 PRIMARY(如果自动没有切换):
手动操作指南:
# 在备机上 手动操作指南:
sudo drbdadm primary --force nfs_res
sudo mount /dev/drbd0 /YuanQiNFS # 备机现在可以挂载并提供 NFS
sudo systemctl start nfs-server
建议通过 Keepalived 的健康脚本在主故障时自动让备机提升为 Primary。但自动提升有风险(可能导致 split-brain)——务必确保网络隔离场景有明确策略。
5. 容器云集成
Kubernetes 中所有 NFS PersistentVolumes / StorageClass 的 server 字段改为 VIP xxx
6. 扩展--- Pacemaker/Corosync 集群管理
配置 Pacemaker/Corosync 集群
启动并启用 pcsd 服务 (在两台节点上执行)
systemctl start pcsd
systemctl enable pcsd
在其中一个节点上完成集群认证和初始化
# 1. 先设置集群用户密码 (在两台节点上设置相同的密码)
echo 'hacluster:your_secure_password' | chpasswd # 2. 在 nfs-node1 上执行
pcs cluster auth nfs-node1 nfs-node2 -u hacluster -p 'your_secure_password' --force
pcs cluster setup --name nfs_cluster nfs-node1 nfs-node2 --force
pcs cluster start --all
pcs cluster enable --all
禁用无关服务并设置集群属性
pcs property set stonith-enabled=false # 没有STONITH设备先禁用
pcs property set no-quorum-policy=ignore # 两节点集群需要忽略quorum
第四步:创建 Pacemaker 集群资源
非常重要:以下所有 pcs 命令只需在其中一个节点(如 nfs-node1)上执行一次即可。
创建 DRBD 资源
pcs resource create drbd_res ocf:linbit:drbd \
drbd_resource=nfs_res \
op monitor interval=20s \
op start timeout=240s \
op stop timeout=120s
创建 DRBD 主从Promotion约束
pcs resource master drbd_clone drbd_res \
master-max=1 master-node-max=1 \
clone-max=2 clone-node-max=1 \
notify=true
创建文件系统资源(用于格式化并挂载DRBD设备)
pcs resource create nfs_fs ocf:heartbeat:Filesystem \
device="/dev/drbd0" \
directory="/nfs_share" \
fstype="ext4" \
op monitor interval=20s \
op start timeout=60s \
op stop timeout=120s
# 约束:文件系统必须在 DRBD Primary 的节点上启动
pcs constraint colocation add nfs_fs with drbd_clone INFINITY with-rsc-role=Master
pcs constraint order promote drbd_clone then start nfs_fs
创建虚拟IP(VIP)资源
pcs resource create nfs_vip ocf:heartbeat:IPaddr2 \
ip=192.168.1.100 \
cidr_netmask=24 \
op monitor interval=10s
# 约束:VIP 必须在文件系统所在的节点上
pcs constraint colocation add nfs_vip with nfs_fs INFINITY
pcs constraint order nfs_fs then nfs_vip
创建NFS服务资源
# 导出配置(可选,也可手动编辑/etc/exports)
echo "/nfs_share *(rw,sync,no_root_squash,no_subtree_check)" > /etc/exports pcs resource create nfs_server systemd:nfs-server \
op monitor interval=30s \
op start timeout=60s \
op stop timeout=120s
# 约束:NFS服务必须在文件系统和VIP都启动后再启动
pcs constraint colocation add nfs_server with nfs_vip INFINITY
pcs constraint order nfs_vip then nfs_server
第五步:验证和测试
检查集群状态
pcs status
你应该看到所有资源都在一个节点(如 nfs-node1)上正常运行 (
Started)。在客户端挂载测试
在另一台Linux客户端上:mount -t nfs 192.168.1.100:/nfs_share /mnt
cd /mnt
touch test_file
ls -l
模拟故障转移测试 (非常重要!)
方法A:手动切换
pcs resource move drbd_clone nfs-node2
# 查看 pcs status,等待所有资源都切换到 nfs-node2 上
# 在客户端检查文件是否还在,是否可以继续写入
方法B:暴力测试
直接在 nfs-node1 上执行reboot或echo c > /proc/sysrq-trigger(触发内核崩溃)。然后观察集群状态,资源应该会自动转移到 nfs-node2 上。
故障排除常用命令
pcs status- 查看集群整体状态pcs resource debug-start <resource_name>- 尝试手动启动一个资源并输出详细日志drbdadm status <resource_name>- 查看DRBD状态journalctl -xe- 查看系统日志pcs constraint- 查看所有约束mount | grep drbd- 检查DRBD设备是否已挂载
容器云后端存储NFS高可用适配的更多相关文章
- Kubernetes容器集群 - harbor仓库高可用集群部署说明
之前介绍Harbor私有仓库的安装和使用,这里重点说下Harbor高可用集群方案的部署,目前主要有两种主流的Harbor高可用集群方案:1)双主复制:2)多harbor实例共享后端存储. 一.Harb ...
- (转)Heartbeat+DRBD+NFS高可用案例
原文:http://9861015.blog.51cto.com/9851015/1939521--------------------------------Heartbeat+DRBD+NFS高可 ...
- 2 NFS高可用解决方案之NFS的搭建
preface 我们紧接着上一篇博文的基础(drbd+heartbeat的正常工作,http://www.cnblogs.com/liaojiafa/p/6129499.html)来搭建NFS的服务. ...
- 用Kolla在阿里云部署10节点高可用OpenStack
为展现 Kolla 的真正实力,我在阿里云使用 Ansible 自动创建 10 台虚机,部署一套多节点高可用 OpenStack 集群! 前言 上次 Kolla 已经表示了要打 10 个的愿望,这次我 ...
- 1 NFS高可用解决方案之DRBD+heartbeat搭建
preface NFS作为业界常用的共享存储方案,被众多公司采用.我司也不列外,使用NFS作为共享存储,为前端WEB server提供服务,主要存储网页代码以及其他文件. 高可用方案 说道NFS,不得 ...
- NFS-heartbeat-drbd模拟NFS高可用
NFS介绍: NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS ...
- 使用DRBD+KEEPALIVED来实现NFS高可用
目录 一 DRBD介绍 二 DRBD的模式 三 DRBD的同步协议 四 实验环境 五 安装配置 关于脑裂(split-brain)处理 一 DRBD介绍 DRBD(Distributed Replic ...
- 重磅发布!阿里云推PostgreSQL 10 高可用版
摘要: 近日,阿里云重磅发布PostgreSQL 10 高可用本地SSD盘版,相比原 9.4 版本又新增了JSONB.BRIN索引.GROUPING SETS/CUBE/ROLLUP.UPSERT等多 ...
- nfs高可用
一.简介 NFS是单点的,如果一个节点出现问题,那使用它挂载服务的都将出现问题.所以需要高可用,挂掉一台不影响.采用keepalived+rsync+inotify-tools 环境: ubunt ...
- DRBD+Heratbeat+NFS高可用文件共享存储
一.概述 .通过ha-log日志可以看出主释放资源,备接管资源. 来自为知笔记(Wiz)
随机推荐
- Druid监控页面配置
springboot的yml配置文件添加如下配置: spring: # 数据库连接相关配置 datasource: druid: filters: stat,wall stat-view-servle ...
- DataEase 远程代码执行漏洞分析
漏洞描述 DataEase 是一款开源的数据可视化分析工具,旨在帮助用户快速分析数据并洞察业务趋势,从而实现业务的改进与优化. 漏洞影响版本: DataEase < 2.10.10 漏洞详情: ...
- Elastic学习之旅 (4) ES文档CRUD操作
大家好,我是Edison. 上一篇:ES必备基础概念一览 ES文档CRUD介绍 和MongoDB一样,文档的CRUD是我们学习ES的必备操作,下图展示了ES文档的CRUD概要: 从上图可以知道,ES文 ...
- SQL Server 重复记录,查询,筛查,指定保留
Select * From 表 x Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1) Order BY 重复字 ...
- 学习spring cloud记录5-Ribbon负载均衡
前言 在上次记录中,后台调用的http://demo-user/demouser/user/test并不是一个直接可用的地址,Ribbon将其拦截拉取eureka的服务列表,然后选择其中一个地址进行请 ...
- 腾讯云的devops自动化部署代替jenkins
起因 jenkins太耗内存了,经常导致服务器崩. 了解到devOps也是做类似的服务的,遂用之. serverless framework也可以做这个,但是截至目前,只能够打包node项目. dev ...
- 前端开发系列069-JQuery篇之框架动画特效
一.jQuery动画特效说明 jQuery框架中为我们封装了众多的动画和特效方法,只需要调用对应的动画方法传递合适的参数,就能够方便的实现一些炫酷的效果,而且jQuery框架还支持自定义各种动画效果. ...
- Wordpress - 将文章或页面放在不同的Menu里
一般模板都可以自定义Menu.我们并不希望将所有的文章都放在Home里. 而是希望在不通的标签里显示不同的内容,可以是静态页面,也可以是分类的文章. 在Wordpress的后台,添加新的Menu,并将 ...
- SciTech-BigDataAIML-Tensorflow-Writing your own callbacks
Introduction A powerful callback was used to customize the behavior of a Keras model during training ...
- Win11正式版电脑回收站为什么显示灰色的问题
一些雨林木风官网的win11正式版用户发现桌面上的回收站图标显示是灰色,点击无法进行,不能操作.这该如何解决呢?我们可以先尝试删除回收站图标,并在图标设置中添加相同的图标.此外,雨林木风小编再来分享其 ...