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

架构.JPG

现在就利用Heartbeat+DRBD搭建一个高可用的NFS共享存储


配置环境:

CentOS 7.5 x 64

NFS-Master: 192.168.5.75   

NFS-Backup: 192.168.5.76   

VIP : 192.168.5.77


#hosts文件配置

cat >> /etc/hosts << EOF
192.168.5.75 nfs75.blufly.com nfs75
192.168.5.76 nfs76.blufly.com nfs76
EOF

###-------------- 安装配置NFS(两个节点都要执行)----------------###

yum -y install rpcbind nfs-utils


#创建共享目录

mkdir -p /data/nfs
echo "/data/nfs 192.168.5.0/24(rw,no_root_squash,sync)" >> /etc/exports
[root@nfs75 /]# service rpcbind start;chkconfig rpcbind off
#NFS不需要启动,也不需要设置成开机启动,这些都将由后面的Heartbeat来完成
[root@nfs75 /]# service nfs start;chkconfig nfs off
[root@nfs76 /]# service rpcbind start;chkconfig rpcbind off
#NFS不需要启动,也不需要设置成开机启动,这些都将由后面的Heartbeat来完成
[root@nfs76 /]# service nfs start;chkconfig nfs off

#查看rpcbind是否启动成功

netstat -tunlp|grep rpcbind

101.JPG

###----------------------- 安装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";

102.JPG

vi /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 nfs75.blufly.com {                    #主机名称
device /dev/drbd1;           #drbd网络磁盘
disk /dev/sdb1;                  #本地需要挂载的磁盘
address 192.168.5.75:7899;       #主ip地址加drbd端口
meta-disk internal;
}
        on nfs76.blufly.com {
device /dev/drbd1;
disk /dev/sdb1;
address 192.168.5.76: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状态
[root@nfs75 ~]# cat /proc/drbd
version: 8.4.11-1 (api:1/proto:86-101)
GIT-hash: 66145a308421e9c124ec391a7848ac20203bb03c build by mockbuild@, 2018-04-26 12:10:42
 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
    ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:52426140

#初始化一个主机(这几步只在主节点上操作)

[root@nfs75 ~]# drbdsetup /dev/drbd1 primary 
[root@nfs75 ~]# drbdadm primary --force data
[root@nfs75 ~]# drbdadm -- --overwrite-data-of-peer primary data

#主节点查看同步状态

[root@nfs75 ~]# cat /proc/drbd
version: 8.4.11-1 (api:1/proto:86-101)
GIT-hash: 66145a308421e9c124ec391a7848ac20203bb03c build by mockbuild@, 2018-04-26 12:10:42
 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:208664 nr:0 dw:0 dr:210784 al:8 bm:0 lo:0 pe:69 ua:0 ap:0 ep:1 wo:f oos:52224924
        [>....................] sync'ed:  0.4% (51000/51196)M
        finish: 3:16:07 speed: 4,436 (4,468) K/sec

##查看格式化进度

[root@nfs75 ~]# watch -n1 'cat /proc/drbd'

说明:

cs:两台数据连接状态

ro:两台主机的状态

ds:磁盘状态是“UpToDate/UpToDate”,同步状态。


##文件系统的挂载只能在master节点进行

mkfs.ext4 /dev/drbd1 

mount /dev/drbd1 /data/nfs


#查看挂载情况

[root@nfs75 ~]# df -h
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   50G  1.9G   49G    4% /
devtmpfs                 908M     0  908M    0% /dev
tmpfs                    920M     0  920M    0% /dev/shm
tmpfs                    920M  8.6M  911M    1% /run
tmpfs                    920M     0  920M    0% /sys/fs/cgroup
/dev/sda1               1014M  184M  831M   19% /boot
/dev/mapper/centos-home   46G   33M   46G    1% /home
tmpfs                    184M     0  184M    0% /run/user/0
/dev/drbd1                50G   53M   47G    1% /data/nfs


###------------------------ 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
vi authkeys
auth 2  #表示使用id为2的验证 下边需要定义一个2的验证算法
2 sha1 HI!  #口令(HISHA1)随便给 主从配置相同即可

#修改haresources文件

vi haresources

#最底下加入这一行,设置VIP

nfs75.blufly.com IPaddr::192.168.5.77/24/eth0 drbddisk::data Filesystem::/dev/drbd1::/data/nfs::ext4 renfsd

#说明:

nfs75.blufly.com IPaddr::192.168.5.77/24/eth0 #主机名 后跟虚拟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

#修改ha.cf文件(两边配置文件要一致)

vi 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 eth0 192.168.5.76 #设定心跳方式使用单播方式,并且是在eth0接口上进行单播,ip地址为对方的IP(网卡名称要一致性的IP)从机要改成主机的IP
auto_failback off #当主节点恢复后,是否自动切回,一般都设为off
node nfs75.blufly.com nfs76.blufly.com #指定两个节点
ping 192.168.5.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 -P 65535 /usr/local/heartbeat/etc/ha.d/* root@192.168.5.76:/usr/local/heartbeat/etc/ha.d/

#把backup节点上ha.cf配置文件中ucast eth0 192.168.5.76改为ucast eth0 192.168.5.75

#把backup节点上haresources文件中的nfs75.blufly.com改为nfs76.blufly.com


#启动Heartbeat(先主后从)

service heartbeat start
chkconfig --add heartbeat
chkconfig heartbeat on
netstat -tunlp|grep heart

[root@nfs75 ~]# ps -ef | grep heartbeat
root     10921     1  0 11:06 ?        00:00:00 heartbeat: master control process
root     10923 10921  0 11:06 ?        00:00:00 heartbeat: FIFO reader
root     10924 10921  0 11:06 ?        00:00:00 heartbeat: write: ucast eth0
root     10925 10921  0 11:06 ?        00:00:00 heartbeat: read: ucast eth0
root     10926 10921  0 11:06 ?        00:00:00 heartbeat: write: ping 192.168.5.1
root     10927 10921  0 11:06 ?        00:00:00 heartbeat: read: ping 192.168.5.1
haclust+ 10952 10921  0 11:06 ?        00:00:00 /usr/local/heartbeat/libexec/heartbeat/ipfail
root     12742  7086  0 11:08 pts/0    00:00:00 grep --color=auto heartbeat


#查看主的IP是否有VIP地址出现

[root@nfs75 ~]# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.5.75/24 brd 192.168.5.255 scope global noprefixroute eth0
    inet 192.168.5.77/24 brd 192.168.5.255 scope global secondary eth0:0

#查看主节点上的nfs是否启动

[root@nfs75 nfs]# ps -ef |grep nfs
root     12651     2  0 11:07 ?        00:00:00 [nfsd4_callbacks]
root     12657     2  0 11:07 ?        00:00:00 [nfsd]
root     12658     2  0 11:07 ?        00:00:00 [nfsd]
root     12659     2  0 11:07 ?        00:00:00 [nfsd]
root     12660     2  0 11:07 ?        00:00:00 [nfsd]
root     12661     2  0 11:07 ?        00:00:00 [nfsd]
root     12662     2  0 11:07 ?        00:00:00 [nfsd]
root     12663     2  0 11:07 ?        00:00:00 [nfsd]
root     12664     2  0 11:07 ?        00:00:00 [nfsd]
root     27239  7086  0 16:03 pts/0    00:00:00 grep --color=auto nfs

#查drbd挂载

df -h


###--------------------- 客户端挂载 -----------------------###

#客户端安装nfs

[root@web32 ~]# yum -y install rpcbind nfs-utils

#查看可挂载的目录

[root@web32 ~]# showmount -e 192.168.5.77
Export list for 192.168.5.77:
/data/nfs 192.168.5.0/24

#挂载

mkdir -p /nfs
mount -t nfs 192.168.5.77:/data/nfs /nfs
[root@web32 /]# df -h
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   36G  3.7G   32G   11% /
devtmpfs                 1.9G     0  1.9G    0% /dev
tmpfs                    1.9G     0  1.9G    0% /dev/shm
tmpfs                    1.9G   49M  1.9G    3% /run
tmpfs                    1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/sda1                497M  166M  332M   34% /boot
tmpfs                    380M     0  380M    0% /run/user/0
192.168.5.77:/data/nfs    50G   52M   47G    1% /nfs

#去除客户端挂载

umount -l /data

#nfs自动挂载设置

#自动挂载用到的软件包automount

yum install autofs

#创建挂载目录

mkdir -p /nfs

#编辑配置文件

vi /etc/auto.master
/nfs /etc/auto.nfs --timeout=60

#-timeout=60 :指NFS客户端在多久没有向NFS服务器请求数据时断开挂载连接。(如果一个NFS服务器上有许多的客户端一直连接的话,NFS服务器会承受很大的带宽压力,这对NFS服务器的正常使用会造成很大的影响,因此,为了解决这一弊端,我可以设定超时时间:让NFS客户端在获取数据时与NFS服务器进行连接,而在没有获取数据的时间内,自动的断开与NFS服务器之间的连接,这就是NFS的自动挂载技术)  

#最后一行添加(左边目录是指需要挂载的目录,右边目录是指关联到所需自动挂载路径


#设置的自动挂载路径

echo "share -rw,sync 192.168.5.77:/data/nfs" >> /etc/auto.nfs

#左边代表自动挂载目录(cd share 会自动挂载),中间权限,sync 代表同步,右边代表所需挂载的文件路径

#注:只有cd  /nfs/share 进去, 触发一下,才能自动挂载,另外share目录,不能提前创建,自动挂载时,系统自动创建share目录。


#重置自动挂载map

service autofs reload

###-------------------- NFS主备切换测试 ----------------------###

##先停止master上面的heartbeat服务

[root@nfs75 nfs]# /etc/init.d/heartbeat stop
Stopping heartbeat (via systemctl):  已终止
[root@nfs75 ~]# ps -ef | grep heartbeat
root     28831 28715  0 16:26 pts/0    00:00:00 grep --color=auto heartbeat

#看看备用节点VIP有没有漂移过来

[root@nfs76 ~]# ip addr|grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.5.76/24 brd 192.168.5.255 scope global noprefixroute eth0
    inet 192.168.5.77/24 brd 192.168.5.255 scope global secondary eth0:0

#备用节点上nfs服务启动正常

[root@nfs76 ~]# ps -ef |grep nfs
root      6145     2  0 16:24 ?        00:00:00 [nfsd4_callbacks]
root      6151     2  0 16:24 ?        00:00:00 [nfsd]
root      6152     2  0 16:24 ?        00:00:00 [nfsd]
root      6153     2  0 16:24 ?        00:00:00 [nfsd]
root      6154     2  0 16:24 ?        00:00:00 [nfsd]
root      6155     2  0 16:24 ?        00:00:00 [nfsd]
root      6156     2  0 16:24 ?        00:00:00 [nfsd]
root      6157     2  0 16:24 ?        00:00:00 [nfsd]
root      6158     2  0 16:24 ?        00:00:00 [nfsd]
root      6478 18947  0 16:30 pts/0    00:00:00 grep --color=auto nfs

#看看客户端NFS连接是否正常

[root@web32 nfs]# showmount -e 192.168.5.77
Export list for 192.168.5.77:
/data/nfs 192.168.5.0/24
[root@web32 nfs]# df -h
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   36G  3.7G   32G   11% /
devtmpfs                 1.9G     0  1.9G    0% /dev
tmpfs                    1.9G     0  1.9G    0% /dev/shm
tmpfs                    1.9G   49M  1.9G    3% /run
tmpfs                    1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/sda1                497M  166M  332M   34% /boot
tmpfs                    380M     0  380M    0% /run/user/0
192.168.5.77:/data/nfs    50G   52M   47G    1% /nfs
[root@web32 nfs]# cd /nfs/
[root@web32 nfs]# ls
32.txt  33.txt  lost+found
[root@web32 nfs]# echo "nfs主从切换" > 44.txt
[root@web32 nfs]# ls
32.txt  33.txt  44.txt  lost+found
[root@web32 nfs]# cat 44.txt 
nfs主从切换

##启动master节点上的heartbeat服务

[root@nfs75 ~]# /etc/init.d/heartbeat start
Starting heartbeat (via systemctl):                        [  OK  ]
[root@nfs75 ~]# ps -ef | grep heartbeat
root     29107     1  0 16:31 ?        00:00:00 heartbeat: master control process
root     29109 29107  0 16:31 ?        00:00:00 heartbeat: FIFO reader
root     29110 29107  0 16:31 ?        00:00:00 heartbeat: write: ucast eth0
root     29111 29107  0 16:31 ?        00:00:00 heartbeat: read: ucast eth0
root     29112 29107  0 16:31 ?        00:00:00 heartbeat: write: ping 192.168.5.1
root     29113 29107  0 16:31 ?        00:00:00 heartbeat: read: ping 192.168.5.1
haclust+ 29135 29107  0 16:31 ?        00:00:00 /usr/local/heartbeat/libexec/heartbeat/ipfail
root     29149 28715  0 16:31 pts/0    00:00:00 grep --color=auto heartbeat

#VIP已漂移到主节点
[root@nfs75 ~]# ip addr|grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.5.75/24 brd 192.168.5.255 scope global noprefixroute eth0
    inet 192.168.5.77/24 brd 192.168.5.255 scope global secondary eth0:0
#NFS服务正常
[root@web33 nfs]# ls
32.txt  33.txt  44.txt  lost+found
[root@web33 nfs]# echo "nfs主节点恢复" > 55.txt
[root@web33 nfs]# ls
32.txt  33.txt  44.txt  55.txt  lost+found
[root@web33 nfs]# cat 55.txt
nfs主节点恢复

##关于主节点nfs服务挂掉的主从切换

[root@nfs75 ~]# service nfs stop
Redirecting to /bin/systemctl stop nfs.service
[root@nfs75 ~]# ps -ef | grep nfs
root     31528 28715  0 16:58 pts/0    00:00:00 grep --color=auto nfs
[root@nfs75 ~]# ip addr|grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.5.75/24 brd 192.168.5.255 scope global noprefixroute eth0
    inet 192.168.5.77/24 brd 192.168.5.255 scope global secondary eth0:0

#把主节点的nfs服务stop掉后,发现VIP并没有切换到备用节点上,且客户端也不能正常挂载了


#出现这种情况,我们就需要手动写一个脚本来监控nfs服务(主备两个节点都运行此脚本)

[root@nfs75 ~]# 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=`service nfs status |grep active | grep -c exited`    #判断nfs是否运行
    if [ -z  $drbdstatus ];then
        sleep 10
        continue
    elif [ $drbdstatus == 'Primary' ];then     #若drbd是Primary状态
        if [ $nfsstatus -eq 0 ];then           #若nfs未运行
            service nfs start &> /dev/null   #启动nfs服务
            service nfs start &> /dev/null
            newnfsstatus=`service nfs status |grep active | 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

#添加执行权限

[root@nfs75 ~]# chmod +x /root/monitor_nfs.sh
[root@nfs75 ~]# nohup /root/monitor_nfs.sh &

#设置开机自启动

[root@nfs75 ~]# echo "nohup /root/monitor_nfs.sh &" >> /etc/rc.local
[root@nfs76 ~]# echo "nohup /root/monitor_nfs.sh &" >> /etc/rc.local

#此脚本的用途就是监控nfs服务,如果nfs服务挂掉,先尝试启动nfs服务,如果启动不了,就停掉heartbeat服务,让VIP漂移到备用节点

#运行了monitor_nfs.sh脚本看,主节点上的nfs服务器启动了起来

[root@nfs75 ~]# ps -ef |grep nfs
root     32190 28715  0 17:11 pts/0    00:00:00 bash /root/monitor_nfs.sh
root     32238     2  0 17:11 ?        00:00:00 [nfsd4_callbacks]
root     32242     2  0 17:11 ?        00:00:00 [nfsd]
root     32243     2  0 17:11 ?        00:00:00 [nfsd]
root     32244     2  0 17:11 ?        00:00:00 [nfsd]
root     32245     2  0 17:11 ?        00:00:00 [nfsd]
root     32246     2  0 17:11 ?        00:00:00 [nfsd]
root     32247     2  0 17:11 ?        00:00:00 [nfsd]
root     32248     2  0 17:11 ?        00:00:00 [nfsd]
root     32249     2  0 17:11 ?        00:00:00 [nfsd]
root     32361 28715  0 17:11 pts/0    00:00:00 grep --color=auto nfs

#客户端连接正常

[root@web32 /]# cd /nfs/
[root@web32 nfs]# ls
32.txt  33.txt  44.txt  55.txt  lost+found
[root@web33 /]# cd /nfs/
[root@web33 nfs]# ls
32.txt  33.txt  44.txt  55.txt  lost+found

###------------------------ heartbeat脑裂 ------------------------###

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--通过第三方软件仲裁谁该获得资源,这个在阿里有类似的软件应用


##手动修复

#备用节点:

[root@nfs76 ~]# drbdadm secondary data
[root@nfs76 ~]# drbdadm disconnect all
[root@nfs76 ~]# drbdadm -- --discard-my-data connect data

#主节点:

[root@nfs75 ~]# drbdadm disconnect all
[root@nfs75 ~]# drbdadm connect data
[root@nfs75 ~]# drbdsetup /dev/drbd1 primary
[root@nfs75 ~]# mount /dev/drbd1 /data/nfs

##注意:在解决脑裂时,把上面所有步骤都操作完后,有时候客户端会挂载正常,有时候则挂载不正常;若不正常,可以尝试把主节点的heartbeat服务重启一下