文章摘要
GPT 4
此内容根据文章生成,仅用于文章内容的解释与总结。

前言

毕设整了一堆(烂)活,本文是期间实现NFS服务高可用的笔记。

期间曾试过 rsyncsersync作为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. 禁用安全上下文与关闭防火墙

    1
    2
    3
    4
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
  2. 添加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
  3. 使用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

加载完成,如下图所示

DRBD-1 DRBD-2

4.修改配置文件

提示:DRBD配置文件

  • 主配置文件 :/etc/drbd.conf

  • 全局配置文件:/etc/drbd.d/global_common.conf

  • 说明:/etc/drbd.conf

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.创建资源文件

提示

  • 本文配置了软件RAID-1,故本地磁盘设置为 /dev/md1,可根据实际情况进行修改;

  • 资源名与资源文件的名字需保持一致

    如本文要建立的资源为nfs,故资源文件应该为nfs.res

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
  • 结果如下图所示

    DRBD-3

    DRBD-4

随后,为renNFS-Master设置为主节点,在主NFS服务器上执行(资源名需要与前面配置的资源文件保持一致)

1
drbdadm primary nfs --force
  • 结果如下图所示

    DRBD-5

    DRBD常用命令

    1
    2
    3
    4
    5
    >drbdadm cstate nfs		#连接状态
    >drbdadm dstate nfs #磁盘状态
    >drbdadm role nfs #资源角色
    >drbdadm primary nfs #提升资源
    >drbdadm secondary nfs #降级资源

7.创建文件系统

💡提示:文件系统只能挂载在主(Primary)节点上,因此在设置好主节点后才可以对DRBD设备进行格式化操作格式化文件系统

  • 可以使用 drbdadm role data 命令查看情况

  • Primary:当前节点为主,在前面为当前节点

Secondary:备用节点为次

在主NFS服务器上执行(即renNFS-Master

1
mkfs.ext4 /dev/drbd0

DRBD-6

  1. 验证DRBD

    • 为每个服务器创建挂载点(mkdir /share

    • 主NFS服务器上挂载(mount /dev/drbd0 /share),并写入一些文件(touch /share/file{a,b}

      DRBD-7

    • 随后卸载(umount /share),切换到备用节点(drbdadm secondary nfs

      DRBD-8

    • 备用NFS服务器上执行以下命令

      1
      2
      3
      drbdadm primary nfs
      mount /dev/drbd0 /share
      ls /share

      应能看到同步到的文件

      DRBD-9

      DRBD-10

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

DRBD-11

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

DRBD-12

在备用NFS服务器中,是没有虚拟地址的

DRBD-13

B.模拟故障

如视频所示,当主NFS服务器断开连接时,会自动切换到备用NFS服务器;同时NFS客户端无需重新挂载,高可用实现达成。

Keepalive_DRBD_NFS_HA