欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CentOS7.5搭建Heartbeat+DRBD+NFS高可用共享存储

程序员文章站 2022-04-03 22:40:47
...

在一般的网络架构的设计中,如果前端web做了负载均衡,后端存储都会用到共享存储,在并发不大、数据量不大的情况下,nfs是一个不错共享存储方案,但是nfs存在单点故障的问题,要想保证nfs的高可用,就要用到Heartbeat+DRBD,DRBD其实就是网络RAID-1,二台服务器中就算其中的某台因电源或主板损坏而宕机而对数据无任何影响,而真正的热切换可以通过Heartbeat来实现,通过HeartBeat,可以将资源(IP以及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用的服务。在实际的生产应用场景中,heartbeat的功能和另一个高可用的开源软件keepalived有很多的相同之处,在实际生产环境中这两者的应用是有区别的。

CentOS7.5搭建Heartbeat+DRBD+NFS高可用共享存储

配置环境:

CentOS 7.5 x 64

NFS-Master: 192.168.0.2

NFS-Backup: 192.168.0.3  

VIP : 192.168.0.77

#hosts文件配置

cat >> /etc/hosts << EOF
192.168.0.2 nfs02.faresky.com
192.168.0.3 nfs03.faresky.com
EOF

###-------------- 安装配置NFS(两个节点都要执行)----------------###
hostnamectl set-hostname nfs02.faresky.com
hostnamectl set-hostname nfs03.faresky.com
yum -y install rpcbind nfs-utils
#创建共享目录
mkdir -p /data/nfs
echo "/data/nfs 192.168.0.0/24(rw,no_root_squash,sync)" >> /etc/exports
cat >> /etc/sysctl.conf << EOF
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
EOF
sysctl -p
systemctl enable rpcbind
systemct enable nfs
systemct start rpcbind
systemct start nfs
#查看rpcbind是否启动成功
netstat -tunlp|grep rpcbind
###----------------------- 安装DRBD ----------------------------###
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum install drbd84 kmod-drbd84 -y
#格式化磁盘,两台服务器上的分区/dev/sdb1作为drbd的网络mirror分区
fdisk /dev/sdb
mkfs.ext4 /dev/sdb1
#开始配置DRBD
modprobe drbd
lsmod | grep drbd
cat /etc/drbd.conf
include "drbd.d/global_common.conf";
include "drbd.d/*.res";
vim /etc/drbd.d/global_common.conf
global {
        usage-count no; ##是否参加DRBD使用者统计,默认是yes
}
common {
        protocol C;
disk {
on-io-error detach;
}
syncer {
rate 100M;                  ##设置主备节点同步时的网络速率最大值
}
}
resource data {
        on nfs02.faresky.com {                    #主机名称
device /dev/drbd1;           #drbd网络磁盘
disk /dev/sdb1;                  #本地需要挂载的磁盘
address 192.168.0.2:7899;       #主ip地址加drbd端口
meta-disk internal;
}
        on nfs03.faresky.com {
device /dev/drbd1;
disk /dev/sdb1;
address 192.168.0.3:7899;
meta-disk internal;
}
}
#启动DRBD(两个节点都要执行)
dd if=/dev/zero bs=1M count=1 of=/dev/sdb1
sync
drbdadm create-md data
#报错:'data' not defined in your config (for this host).
#在resource data这段中,on后面一定要写完整的hostname
service drbd start
chkconfig drbd on
#查看DRBD状态
cat /proc/drbd
#初始化一个主机(这几步只在主节点上操作)
drbdsetup /dev/drbd1 primary --force
drbdadm primary --force data
drbdadm -- --overwrite-data-of-peer primary data
#主节点查看同步状态
cat /proc/drbd
##查看格式化进度
watch -n1 'cat /proc/drbd'
说明:

cs:两台数据连接状态

ro:两台主机的状态

ds:磁盘状态是“UpToDate/UpToDate”,同步状态。
##文件系统的挂载只能在master节点进行
mkfs.ext4 /dev/drbd1 

mount /dev/drbd1 /data/nfs
cat >> /etc/fstab << EOF
/dev/drbd1    /data/nfs     ext4        defaults      1 2
EOF
#查看挂载情况
df -h
###------------------------ Heartbeat环境搭建 -----------------------###
#centos7下没有heartbeat的yum源,只能编译安装heartbeat
cd /opt
wget http://hg.linux-ha.org/heartbeat-STABLE_3_0/archive/958e11be8686.tar.bz2
wget http://hg.linux-ha.org/glue/archive/0a7add1d9996.tar.bz2
wget https://github.com/ClusterLabs/resource-agents/archive/v3.9.6.tar.gz
#安装相关依赖库
yum -y install gcc gcc-c++ autoconf automake libtool glib2-devel libxml2-devel bzip2 bzip2-devel e2fsprogs-devel libxslt-devel libtool-ltdl-devel asciidoc
#创建组及运行用户
groupadd haclient
useradd -g haclient hacluster -s /sbin/nologin
tar -jxvf  0a7add1d9996.tar.bz2
cd Reusable-Cluster-Components-glue--0a7add1d9996/
./autogen.sh
./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
make && make install
cd /opt
tar -zxvf v3.9.6.tar.gz
cd resource-agents-3.9.6
./autogen.sh 
./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
make && make install
cd /opt
tar -jxvf 958e11be8686.tar.bz2
cd Heartbeat-3-0-958e11be8686/
./bootstrap
#添加环境变量
export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib" 
./configure --prefix=/usr/local/heartbeat --with-daemon-user=hacluster --with-daemon-group=haclient --enable-fatal-warnings=no LIBS='/lib64/libuuid.so.1'
make && make install
cp doc/{ha.cf,haresources,authkeys} /usr/local/heartbeat/etc/ha.d/
chmod 600 /usr/local/heartbeat/etc/ha.d/authkeys
mkdir -pv /usr/local/heartbeat/usr/lib/ocf/lib/heartbeat/
cp /usr/lib/ocf/lib/heartbeat/ocf-* /usr/local/heartbeat/usr/lib/ocf/lib/heartbeat/
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/RAExec/* /usr/local/heartbeat/lib/heartbeat/plugins/RAExec/
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/* /usr/local/heartbeat/lib/heartbeat/plugins/
cd ../
#修改配置文件
cd /usr/local/heartbeat/etc/ha.d
vim authkeys
auth 2  #表示使用id为2的验证 下边需要定义一个2的验证算法
2 sha1 HI!  #口令(HISHA1)随便给 主从配置相同即可
#修改haresources文件
#最底下加入这一行,设置VIP
nfs02.faresky.com IPaddr::192.168.0.77/24/ens33 drbddisk::data Filesystem::/dev/drbd1::/data/nfs::ext4 renfsd
#说明:

nfs02.faresky.com IPaddr::192.168.0.77/24/ens33 #主机名 后跟虚拟IP地址、接口

drbddisk::data #管理drbd资源的名称

Filesystem::/dev/drbd1::/data/nfs::ext4 renfsd #文件系统::挂载的目录及格式::后跟renfsd资源脚本
#编辑nfs脚本文件renfsd,renfsd脚本文件的作用,

#drbd主备切换时,若nfs没有启动,则此脚本会把nfs启动

#drbd主备切换时,若nfs已启动,则此脚本会重启nfs服务,因为NFS服务切换后,必须重新mount一下nfs共享出来的目录,否则会出现stale NFS file handle的错误
echo "killall -9 nfsd; service nfs restart; exit 0" > /usr/local/heartbeat/etc/ha.d/resource.d/renfsd
chmod 755 /usr/local/heartbeat/etc/ha.d/resource.d/renfsd
vim ha.cf
debugfile /var/log/ha-debug #设定debug文件目录
logfile /var/log/ha-log #设定日志文件目录
logfacility local0 #利用系统日志打印日志
keepalive 2 #设定检查时间间隔为1s
deadtime 30 #设定在10s内没有心跳信号,则立即切换服务
warntime 10 #设定告警时间为5s(5s内没有收到对方的回应就报警)
initdead 120 #设定初始化时间为60s
udpport 694 #设定集群节点间的通信协议及端口为udp694监听端口(该端口可以修改)
ucast ens33 192.168.0.3 #设定心跳方式使用单播方式,并且是在eth0接口上进行单播,ip地址为对方的IP(网卡名称要一致性的IP)从机要改成主机的IP
auto_failback off #当主节点恢复后,是否自动切回,一般都设为off
node nfs02.faresky.com nfs03.faresky.com #指定两个节点
ping 192.168.0.1 #两个IP的网关
respawn hacluster /usr/local/heartbeat/libexec/heartbeat/ipfail #使用这个脚本去侦听对方是否还活着(使用的是ICMP报文检测)
#此处是一个大坑,源码安装Heartbeat,不会在/usr/local/heartbeat/etc/ha.d/resource.d/创建drbddisk脚本,而且也无法在安装后从本地其他路径找到该文件。

#通过查看/var/log/ha-log日志,找到一行ERROR: Cannot locate resource script drbddisk,然后进而到/etc/ha.d/resource.d/路径下发现竟然没有drbddisk脚本
cp /etc/ha.d/resource.d/drbddisk /usr/local/heartbeat/etc/ha.d/resource.d/
chmod +x /usr/local/heartbeat/etc/ha.d/resource.d/drbddisk
#将配置文件拷贝到从节点
scp  /usr/local/heartbeat/etc/ha.d/* aaa@qq.com:/usr/local/heartbeat/etc/ha.d/
#把backup节点上ha.cf配置文件中ucast ens33 192.168.0.3改为ucast ens33 192.168.0.2
#把backup节点上haresources文件中的nfs03.faresky.com改为nfs02.faresky.com
#启动Heartbeat(先主后从)
service heartbeat start
chkconfig --add heartbeat
chkconfig heartbeat on
netstat -tunlp|grep heart
ps -ef | grep heartbeat
#查看主的IP是否有VIP地址出现
ip a | grep ens33
#查看主节点上的nfs是否启动
ps -ef |grep nfs
#查drbd挂载
df -h
#客户端安装nfs
yum -y install rpcbind nfs-utils
showmount -e 192.168.0.77
#挂载
mkdir -p /nfs
mount -t nfs 192.168.0.77:/data/nfs /nfs
df -h
cat >> /etc/fstab << EOF
192.168.0.77:/data/nfs       /nfs           ext4     defaults 1 2
EOF
#把主节点的nfs服务stop掉后,发现VIP并没有切换到备用节点上,且客户端也不能正常挂载了
#出现这种情况,我们就需要手动写一个脚本来监控nfs服务(主备两个节点都运行此脚本)
vi /root/monitor_nfs.sh
#!/bin/bash
#监控nfs服务的运行情况
while true
do
    drbdstatus=`cat /proc/drbd 2> /dev/null  | grep ro | tail -n1 | awk -F':' '{print $4}' | awk -F'/' '{print $1}'`   #判断drbd的状态
    nfsstatus=`systemctl status nfs |grep inactive | grep -c exited`    #判断nfs是否运行
    if [ -z  $drbdstatus ];then
        sleep 10
        continue
    elif [ $drbdstatus == 'Primary' ];then     #若drbd是Primary状态
        if [ $nfsstatus -eq 0 ];then           #若nfs未运行
            systemctl start nfs &> /dev/null   #启动nfs服务
            systemctl start nfs &> /dev/null
            newnfsstatus=`systemctl status nfs |grep inactive | grep -c exited`     #再次判断nfs是否成功启动
            if [ $newnfsstatus -eq 0 ];then         #若nfs未运行,也就是无法启动
                /etc/init.d/heartbeat  stop &> /dev/null        #将heartbeat服务stop掉,目的是自动切换到另一台备用机
                /etc/init.d/heartbeat  stop &> /dev/null
            fi
        fi
    fi
    sleep 5
done
#添加执行权限
chmod +x /root/monitor_nfs.sh
nohup /root/monitor_nfs.sh &
#设置开机自启动 
echo "nohup /root/monitor_nfs.sh &" >> /etc/rc.local
chmod +x /etc/rc.d/rc.local
#此脚本的用途就是监控nfs服务,如果nfs服务挂掉,先尝试启动nfs服务,如果启动不了,就停掉heartbeat服务,让VIP漂移到备用节点
Heartbeat裂脑

什么是裂脑?

由于两台高可用服务器之间在指定的时间内,无法互相检测到对方心跳而各自启动故障转移功能,取得了资源以及服务的所有权,而此时的两台高可用服务器对都还活着并作正常运行,这样就会导致同一个IP湖综合服务在两端同时启动而发生冲突的严重问题,最严重的就是两台主机同时占用一个VIP的地址,当用户写入数据的时候可能会分别写入到两端,这样可能会导致服务器两端的数据不一致或造成数据的丢失,这种情况就本成为裂脑,也有的人称之为分区集群或者大脑垂直分隔。



导致裂脑发生的原因:

一般来说,裂脑的发生,主要是由以下的几个原因导致的:

1)高可用服务器对之间心跳线路故障,导致无法正常的通信。原因比如:

1--心跳线本身就坏了(包括断了,老化);

2--网卡以及相关驱动坏了,IP配置及冲突问题;

3--心跳线间连接的设备故障(交换机的故障或者是网卡的故障);

4--仲裁的服务器出现问题。

2)高可用服务器对上开启了防火墙阻挡了心跳消息的传输;

3)高可用服务器对上的心跳网卡地址等信息配置的不正确,导致发送心跳失败;

4)其他服务配置不当等原因,如心跳的方式不同,心跳广播冲突,软件出现了BUG等。



防止脑裂发生的方法:

发生脑裂的时候,对业务的影响是及其严重的,有的时候甚至是致命的。比如:两台高可用的服务器对之间发生脑裂,导致互相竞争同一个IP资源,就如同我们局域网内常见的IP地址冲突一样,两个机器就会有一个或者两个不正常,影响用户正常访问服务器。如果是应用在数据库或者是存储服务这种极重要的高可用上,那就导致用户发布的数据间断的写在两台服务器上的恶果,最终数据恢复及困难或者是难已恢复。



实际的生产环境中,我们可以从以下几个方面来防止裂脑的发生:

1)同时使用串行电缆和以太网电缆连接,同时用两条心跳线路,这样一条线路坏了,另一个线路还是好的,依然能传送消息(推荐的)

2)检测到裂脑的时候强行的关闭一个心跳节点(需要特殊的节点支持,如stonith,fence),相当于程序上备节点发现心跳线故障,发送关机命令到主节点。

3)做好对裂脑的监控报警(如邮件以及手机短信等),在问题发生的时候能够人为的介入到仲裁,降低损失。当然,在实施高可用方案的时候,要根据业务的实际需求确定是否能够容忍这样的损失。对于一般的网站业务,这个损失是可控的(公司使用)

4)启用磁盘锁。正在服务一方锁住共享磁盘,脑裂发生的时候,让对方完全抢不走共享的磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的乙方不主动解锁,另一方就永远得不到共享磁盘。现实中介入服务节点突然死机或者崩溃,另一方就永远不可能执行解锁命令。后备节点也就截关不了共享的资源和应用服务。于是有人在HA中涉及了“智能”锁,正在服务的一方只在发现心跳线全部断开时才启用磁盘锁,平时就不上锁了

5)报警报在服务器接管之前,给人员处理留足够的时间就是1分钟内报警了,但是服务器不接管,而是5分钟之后接管,接管的时间较长。数据不会丢失,但就是会导致用户无法写数据。

6)报警后,不直接自动服务器接管,而是由人员接管。

7)增加仲裁的机制,确定谁该获得资源,这里面有几个参考的思路:

1--增加一个仲裁机制。例如设置参考的IP,当心跳完全断开的时候,2个节点各自都ping一下参考的IP,不同则表明断点就出现在本段,这样就主动放弃竞争,让能够ping通参考IP的一端去接管服务。

2--通过第三方软件仲裁谁该获得资源,这个在阿里有类似的软件应用
##手动修复

#备用节点:
drbdadm secondary data
drbdadm disconnect all
drbdadm -- --discard-my-data connect data
#主节点:
drbdadm disconnect all
drbdadm connect data
drbdsetup /dev/drbd1 primary
mount /dev/drbd1 /data/nfs
##注意:在解决脑裂时,把上面所有步骤都操作完后,有时候客户端会挂载正常,有时候则挂载不正常;若不正常,可以尝试把主节点的heartbeat服务重启一下
相关标签: 存储