前言
毕设整了一堆(烂)活,本文是期间实现NFS服务高可用的笔记。
期间曾试过 rsync
与 sersync
作为NFS服务的同步方案,不过很遗憾,这方案收敛实在是太慢了,而且收敛完成后,客户端还需要重新挂载,这对于一些实时性要求高的服务来说,是个灾难。在多方检索后,基于分布式思想的DRBD
映入眼帘……
服务 |
说明 |
NFS |
高性能的文件共享协议 |
DRBD |
一种通过TCP/IP网络实现块设备数据实时镜像的方案 通过双主模式,实现类似RAID-1的网络高可用共享存储 |
Keepalived |
基于VRRP协议来实现的服务高可用方案 |
规划
使用两台虚拟机分别作为NFS主备服务器,以及一台虚拟机作为NFS客户端以便测试。其中,NFS主备服务器的系统均为 Rocky Linux 9 ,NFS客户端为 CentOS 7.6 ;NFS主备服务器的地址规划如下表所示。
主机名 |
IP地址 |
备注 |
renNFS |
172.24.5.25 |
虚拟负载 |
renNFS-Master |
172.24.5.23 |
主NFS |
renNFS-Slave |
172.24.5.34 |
备用NFS |
部署
提示:如无特殊说明,以下步骤均需要在主备NFS服务器上进行操作。
A.基础环境配置
禁用安全上下文与关闭防火墙
1 2 3 4
| sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config systemctl stop firewalld systemctl disable firewalld setenforce 0
|
添加Hosts
1 2 3 4 5
| cat << EOF >> /etc/hosts 172.24.5.23 renNFS-Master 172.24.5.24 renNFS-Slave 172.24.5.25 renNFS EOF
|
使用fdisk
命令为磁盘分区
B.部署DRBD
1.安装EPEL
源
只因DRBD在此库
1 2
| rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org yum install -y https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm
|
2.安装DRBD
1 2
| yum list all | grep -i drbd yum install -y drbd9x-utils kmod-drbd9x
|
3.加载DRBD
1 2 3 4
| modprobe drbd echo drbd > /etc/modules-load.d/drbd.conf modprobe drbd lsmod |grep drbd
|
加载完成,如下图所示
4.修改配置文件
提示:DRBD配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| mv /etc/drbd.d/global_common.conf /etc/drbd.d/global_common.conf.bak cat << EOF | tee /etc/drbd.d/global_common.conf global { usage-count no; # 是否参加DRBD使用统计,默认为yes } common { protocol C; # 使用DRBD的同步协议,添加这一行 handlers { pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f"; } startup { } options { } disk { on-io-error detach; # 配置I/O错误处理策略为分离 } net { } } } EOF
|
💡提示:工作模式说明
- 协议A:异步复制协议。一旦本地磁盘写入已完成且数据包已在发送队列中,则会被认为是完成的。在一个节点发生故障时可能会丢失,因为被写入到远程节点上的数据可能仍在发送队列中。尽管在故障转移节点上的数据一致,但没有及时更新。通常用于地理上分开的节点(本地写成功后立即返回,数据放在发送buffer中,可能丢失);
- 协议B:内存同步(半同步)复制协议。一旦本地磁盘写入完成且复制数据包达到了对等节点,则认为写在主节点上会被认为是完成的。数据丢失可能发生在参加的两个节点同时故障的情况,因为在传输中的数据可能不会被提交到磁盘(本地写成功并将数据发送到对方后立即返回,如果双机掉电,数据可能丢失;
- 协议C:同步复制协议。只有在本地和远程节点的磁盘均确认了写操作完成时才会被认为完成。没有任何数据丢失!所以这是一个群集节点的流行模式,但I/O吞吐量依赖于网络带宽。一般选用此模式
5.创建资源文件
提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| cat > /etc/drbd.d/nfs.res << EOF # 资源名与文件名要一致(如nfs对应nfs.res),根据实际情况进行修改 resource nfs { protocol C; # 使用协议 disk /dev/md1; # 本地磁盘,根据实际情况进行修改 device /dev/drbd0; # DRBD设备名称,根据实际情况进行修改 meta-disk internal;
# 设置DRBD监听地址与端口[主],名字最好与Host记录一致 on renNFS-Master { address 172.24.5.23:7789; }
# 设置DRBD监听地址与端口[备],名字最好与Host记录一致 on renNFS-Slave { address 172.24.5.24:7789; } } EOF
|
6.启动DRBD
首先,主备NFS服务器均执行
1 2
| drbdadm create-md nfs drbdadm up nfs
|
结果如下图所示
随后,为renNFS-Master
设置为主节点,在主NFS服务器上执行(资源名需要与前面配置的资源文件保持一致)
1
| drbdadm primary nfs --force
|
结果如下图所示
DRBD常用命令
1 2 3 4 5
| >drbdadm cstate nfs >drbdadm dstate nfs >drbdadm role nfs >drbdadm primary nfs >drbdadm secondary nfs
|
7.创建文件系统
💡提示:文件系统只能挂载在主(Primary)节点上,因此在设置好主节点后才可以对DRBD设备进行格式化操作格式化文件系统
Secondary:备用节点为次
在主NFS服务器上执行(即renNFS-Master
)
验证DRBD
为每个服务器创建挂载点(mkdir /share
)
在主NFS服务器上挂载(mount /dev/drbd0 /share
),并写入一些文件(touch /share/file{a,b}
)
随后卸载(umount /share
),切换到备用节点(drbdadm secondary nfs
)
在备用NFS服务器上执行以下命令
1 2 3
| drbdadm primary nfs mount /dev/drbd0 /share ls /share
|
应能看到同步到的文件
8.设置开机自启
1
| systemctl enable --now drbd
|
C.部署NFS
每个NFS服务器都需要部署;这没啥好说的,有手就行。
1 2 3 4
| yum -y install nfs-utils rpcbind echo '/share 172.24.5.0/24(rw,sync,no_root_squash)' >> /etc/exports systemctl enable nfs-server.service --now systemctl enable rpcbind --now
|
D.部署Keepalived
1.安装Keepalived
1 2
| yum install -y keepalived.x86_64 mkdir /etc/keepalived/logs
|
2.主NFS服务器配置
提示:根据实际情况进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak cat << EOF | tee /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id DRBD_HA_MASTER } vrrp_script chk_nfs { script "/etc/keepalived/check_nfs.sh" interval 5 } vrrp_instance VI_1 { state MASTER interface ens160 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 114514 } track_script { chk_nfs } notify_stop /etc/keepalived/notify_stop.sh notify_master /etc/keepalived/notify_master.sh virtual_ipaddress { 172.24.5.25 } }
EOF
|
3.备用NFS服务器配置
提示:根据实际情况进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak cat << EOF | tee /etc/keepalived/keepalived.conf
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id DRBD_HA_BACKUP } vrrp_instance VI_1 { state BACKUP interface ens160 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 114514 } notify_master /etc/keepalived/notify_master.sh notify_backup /etc/keepalived/notify_backup.sh virtual_ipaddress { 172.24.5.25 } } EOF
|
4.配置脚本
提示:虽然Keepalived能实现地址的故障转移,但是DRBD服务的优先级并没有及时降级,需通过脚本完善。
a.在主NFS服务器上
检测NFS可用性脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| cat << EOF | tee /etc/keepalived/chk_nfs.sh #!/bin/bash # 检查NFS服务状态 systemctl status nfs-server &>/dev/null if [ $? -ne 0 ];then # 如果服务状态不正常,先尝试重启服务 systemctl restart nfs-server systemctl status nfs-server &>/dev/null if [ $? -ne 0 ];then # 若重启nfs服务后,仍不正常 # 卸载drbd设备 umount /dev/drbd0 # 将drbd主降级为从设备(最后的nfs根据实际情况进行修改) drbdadm secondary nfs # 关闭keepalived systemctl stop keepalived fi fi
EOF
chmod 0755 /etc/keepalived/check_nfs.sh
|
主节点降级操作脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cat << EOF | tee /etc/keepalived/notify_stop.sh #!/bin/bash # 时间戳 time=`date "+%F %H:%M:%S"` echo -e "$time ------notify_stop------\n" >> /etc/keepalived/logs/notify_stop.log # 停止NFS服务 systemctl stop nfs-server &>> /etc/keepalived/logs/notify_stop.log # 卸载目录 /bin/umount /share &>> /etc/keepalived/logs/notify_stop.log # 降级处理(设为辅助节点) /sbin/drbdadm secondary nfs &>> /etc/keepalived/logs/notify_stop.log echo -e "\n" >> /etc/keepalived/logs/notify_stop.log
EOF
chmod 0755 /etc/keepalived/notify_stop.sh
|
挂载脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cat << EOF | tee /etc/keepalived/notify_master.sh #!/bin/bash # 时间戳 time=`date "+%F %H:%M:%S"` echo -e "$time ------notify_master------\n" >> /etc/keepalived/logs/notify_master.log # 提级处理(设为主节点) /sbin/drbdadm primary nfs &>> /etc/keepalived/logs/notify_master.log # 挂载目录 /bin/mount /dev/drbd0 /share &>> /etc/keepalived/logs/notify_master.log # 重启NFS服务 systemctl restart nfs-server &>> /etc/keepalived/logs/notify_master.log echo -e "\n" >> /etc/keepalived/logs/notify_master.log
EOF
chmod 0755 /etc/keepalived/notify_master.sh
|
b.在备用NFS服务器上
挂载脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cat << EOF | tee /etc/keepalived/notify_master.sh #!/bin/bash # 时间戳 time=`date "+%F %H:%M:%S"` echo -e "$time ------notify_master------\n" >> /etc/keepalived/logs/notify_master.log # 提级处理(设为主节点) /sbin/drbdadm primary nfs &>> /etc/keepalived/logs/notify_master.log # 挂载目录 /bin/mount /dev/drbd0 /share &>> /etc/keepalived/logs/notify_master.log # 重启NFS服务 systemctl restart nfs-server &>> /etc/keepalived/logs/notify_master.log echo -e "\n" >> /etc/keepalived/logs/notify_master.log
EOF
chmod 0755 /etc/keepalived/notify_master.sh
|
从节点降级操作用脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cat << EOF | tee /etc/keepalived/notify_backup.sh #!/bin/bash # 时间戳 time=`date "+%F %H:%M:%S"` echo -e "$time ------notify_backup------\n" >> /etc/keepalived/logs/notify_backup.log # 停止NFS服务 systemctl stop nfs-server &>> /etc/keepalived/logs/notify_backup.log # 卸载目录 /bin/umount /dev/drbd0 &>> /etc/keepalived/logs/notify_backup.log # 降级处理(设为辅助节点) /sbin/drbdadm secondary nfs &>> /etc/keepalived/logs/notify_backup.log echo -e "\n" >> /etc/keepalived/logs/notify_backup.log
EOF
chmod 0755 /etc/keepalived/notify_backup.sh
|
5.设置开机自启
为所有NFS服务器执行以下命令
1
| systemctl enable keepalived --now
|
测试
A.检查Keepalived
当服务正常运行时,在主NFS服务器中,可以看到有虚拟地址172.24.5.25
在备用NFS服务器中,是没有虚拟地址的
B.模拟故障
如视频所示,当主NFS服务器断开连接时,会自动切换到备用NFS服务器;同时NFS客户端无需重新挂载,高可用实现达成。