使用DRBD+KEEPALIVED来实现NFS高可用
- 一 DRBD介绍
- 二 DRBD的模式
- 三 DRBD的同步协议
- 四 实验环境
- 五 安装配置
- 1 安装drbd及配置
- 1.1 安装drbd
- 1.2 配置文件(分别在两台机器上配置)
- 1.3 在两台机器上添加DRBD磁盘
- 1.4 在两台机器上分别创建DRBD设备并激活r0资源(下面操作在两台机器上都要执行)
- 1.5 启动drbd服务(注意:需要主从共同启动方能生效)
- 1.6 查看状态(两台机器上都执行查看)
- 1.7 将Primary主机配置为DRBD的主节点
- 1.8 挂载DRBD
- 1.9 测试主节点宕机手动切换节点
- 下面是在Secondary 备份节点上操作记录,先进行提权操作,即将Secondary手动升级为DRBD的主节点
- 在Secondary节点上继续写入数据,然后模拟Secondary节点故障,Primary节点再提权升级为DRBD主节点
- 主节点操作
- 到此,DRBD的主从环境的部署工作已经完成。不过上面是记录的是主备手动切换,至于保证DRBD主从结构的智能切换,实现高可用,还需里用到Keepalived。
- 2 安装nfs及配置
- 3 安装keepalived及配置
- 1 安装drbd及配置
- 关于脑裂(split-brain)处理
一 DRBD介绍
DRBD(Distributed ReplicatedBlock Device)是一种基于软件的,无共享,分布式块设备复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等)进行镜像。
也就是说当某一个应用程序完成写操作后,它提交的数据不仅仅会保存在本地块设备上,DRBD也会将这份数据复制一份,通过网络传输到另一个节点的块设备上,这样,两个节点上的块设备上的数据将会保存一致,这就是镜像功能。
DRBD是由内核模块和相关脚本而构成,用以构建高可用性的集群,其实现方式是通过网络来镜像整个设备。它允许用户在远程机器上建立一个本地块设备的实时镜像,与心跳连接结合使用,可以把它看作是一种网络RAID,它允许用户在远程机器上建立一个本地块设备的实时镜像。
DRBD工作在内核当中,类似于一种驱动模块。DRBD工作的位置在文件系统的buffer cache和磁盘调度器之间,通过tcp/ip发给另外一台主机到对方的tcp/ip最终发送给对方的drbd,再由对方的drbd存储在本地对应磁盘 上,类似于一个网络RAID-1功能。在高可用(HA)中使用DRBD功能,可以代替使用一个共享盘阵。本地(主节点)与远程主机(备节点)的数据可以保 证实时同步。当本地系统出现故障时,远程主机上还会保留有一份相同的数据,可以继续使用。
1 DRBD底层设备支持
DRBD需要构建在底层设备之上,然后构建出一个块设备出来。对于用户来说,一个DRBD设备,就像是一块物理的磁盘,可以在上面内创建文件系统。
DRBD所支持的底层设备有以下这些类:
1)一个磁盘,或者是磁盘的某一个分区;
2)一个soft raid 设备;
3)一个LVM的逻辑卷;
4)一个EVMS(Enterprise Volume Management System,企业卷管理系统)的卷;
5)其他任何的块设备。
2 DRBD工作原理
DRBD是一种块设备,可以被用于高可用(HA)之中,它类似于一个网络RAID-1功能,当你将数据写入本地 文件系统时,数据还将会被发送到网络中另一台主机上,以相同的形式记录在一个文件系统中。 本地(主节点)与远程主机(备节点)的数据可以保证实时同步.当本地系统出现故障时,远程主机上还会 保留有一份相同的数据,可以继续使用.在高可用(HA)中使用DRBD功能,可以代替使用一个共享盘阵.因为数据同时存在于本地主机和远程主机上,切换时,远程主机只要使用它上面的那份备份数据,就可以继续进行服务了。
3 DRBD工作机制
DRBD Primary负责接收数据,把数据写到本地磁盘并发送给另一台主机DRBD Secondary,另一个主机再将数据存到自己的磁盘中。
目前,DRBD每次只允许对一个节点进行读写访问,但这对于通常的故障切换高可用集群来说已经足够用了,以后的版本将支持两个节点进行读写存取。
DRBD协议说明:
1)数据一旦写入磁盘并发送到网络中就认为完成了写入操作。
2)收到接收确认就认为完成了写入操作。
3)收到写入确认就认为完成了写入操作。
二 DRBD的模式
DRBD有2中模式,一种是DRBD的主从模式,另一种是DRBD的双主模式:
1 DRBD的主从模式
这种模式下,其中一个节点作为主节点,另一个节点作为从节点。其中主节点可以执行读、写操作;从节点不可以挂载文件系统,因此,也不可以执行读写操作。
在这种模式下,资源在任何时间只能存储在主节点上。这种模式可用在任何的文件系统上(EXT3、EXT4、XFS等等)。默认这种模式下,一旦主节点发生故障,从节点需要手工将资源进行转移,且主节点变成从节点和从节点变成主节点需要手动进行切换。不能自动进行转移,因此比较麻烦。
为了解决手动将资源和节点进行转移,可以将DRBD做成高可用集群的资源代理(RA),这样一旦其中的一个节点宕机,资源会自动转移到另一个节点,从而保证服务的连续性。
2 DRBD的双主模式
这是DRBD8.0之后的新特性,在双主模式下,任何资源在任何特定的时间都存在两个主节点。这种模式需要一个共享的集群文件系统,利用分布式的锁机制进行管理,如GFS和OCFS2。
部署双主模式时,DRBD可以是负载均衡的集群,这就需要从两个并发的主节点中选取一个首选的访问数据。这种模式默认是禁用的,如果要是用的话必须在配置文件中进行声明。
三 DRBD的同步协议
DRBD的复制功能就是将应用程序提交的数据一份保存在本地节点,一份复制传输保存在另一个节点上。但是DRBD需要对传输的数据进行确认以便保证另一个节点的写操作完成,就需要用到DRBD的同步协议,DRBD同步协议有三种:
1 协议A:异步复制协议
一旦本地磁盘写入已经完成,数据包已在发送队列中,则写被认为是完成的。在一个节点发生故障时,可能发生数据丢失,因为被写入到远程节点上的数据可能仍在发送队列。尽管,在故障转移节点上的数据是一致的,但没有及时更新。这通常是用于地理上分开的节点。
数据在本地完成写操作且数据已经发送到TCP/IP协议栈的队列中,则认为写操作完成。如果本地节点的写操作完成,此时本地节点发生故障,而数据还处在TCP/IP队列中,则数据不会发送到对端节点上。因此,两个节点的数据将不会保持一致。这种协议虽然高效,但是并不能保证数据的可靠性。
2 协议B:内存同步(半同步)复制协议
一旦本地磁盘写入已完成且复制数据包达到了对等节点则认为写在主节点上被认为是完成的。数据丢失可能发生在参加的两个节点同时故障的情况下,因为在传输中的数据
可能不会被提交到磁盘数据在本地完成写操作且数据已到达对端节点则认为写操作完成。如果两个节点同时发生故障,即使数据到达对端节点,这种方式同样也会导致在对端节点和本地节点的数据不一致现象,也不具有可靠性。
3 协议C:同步复制协议
只有在本地和远程节点的磁盘已经确认了写操作完成,写才被认为完成。没有任何数据丢失,所以这是一个群集节点的流行模式,但I / O吞吐量依赖于网络带宽。
只有当本地节点的磁盘和对端节点的磁盘都完成了写操作,才认为写操作完成。这是集群流行的一种方式,应用也是最多的,这种方式虽然不高效,但是最可靠。
以上三种协议中,一般使用协议C,但选择C协议将影响流量,从而影响网络时延。为了数据可靠性,在生产环境使用时须慎重选项使用哪一种协议。
四 实验环境
[root@primary ~]# systemctl stop firewalld
[root@primary ~]# systemctl disable firewalld
[root@primary ~]# sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
[root@primary ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@primary ~]# cat <<EOF | tee -a /etc/hosts
192.168.1.1 primary
192.168.1.2 secondary
[root@secondary ~]# systemctl stop firewalld
[root@secondary ~]# systemctl disable firewalld
[root@secondary ~]# sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
[root@secondary ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@secondary ~]# cat <<EOF | tee -a /etc/hosts
192.168.1.1 primary
192.168.1.2 secondary
五 安装配置
1 安装drbd及配置
1.1 安装drbd
[root@primary ~]# yum install kernel-devel kernel kernel-headers -y
[root@primary ~]# reboot
[root@primary ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
[root@primary ~]# yum install drbd84-utils kmod-drbd84 -y
[root@primary ~]# modprobe drbd #加载模块
[root@primary ~]# lsmod | grep drbd
drbd 397041 0
libcrc32c 12644 2 xfs,drbd
[root@secondary ~]# yum install kernel-devel kernel kernel-headers -y
[root@secondary ~]# reboot
[root@secondary ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
[root@secondary ~]# yum install drbd84-utils kmod-drbd84 -y
[root@secondary ~]# modprobe drbd
[root@secondary ~]# lsmod | grep drbd
drbd 397041 0
libcrc32c 12644 2 xfs,drbd
1.2 配置文件(分别在两台机器上配置)
[root@primary ~]# cat /etc/drbd.conf
# You can find an example in /usr/share/doc/drbd.../drbd.conf.example
include "drbd.d/global_common.conf";
include "drbd.d/*.res";
[root@primary ~]# cp /etc/drbd.d/global_common.conf /etc/drbd.d/global_common.conf.bak
[root@primary ~]# vim /etc/drbd.d/global_common.conf
global {
usage-count no;#不让linbit公司收集目前drbd的使用情况
# minor-count dialog-refresh disable-ip-verification
}
common {
protocol C; #A/B/C复制模式,默认C,数据可靠性高
handlers {#信息处理的一些策略
# These are EXAMPLE handlers only.
# They may have severe implications,
# like hard resetting the node under certain circumstances.
# Be careful when chosing your poison.
# 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";
# fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
# split-brain "/usr/lib/drbd/notify-split-brain.sh root";
# out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";
# before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";
# after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;
}
startup {
wfc-timeout 240;
degr-wfc-timeout 240;
outdated-wfc-timeout 240;
}
disk {
on-io-error detach; ###同步IO错误的做法:分离该磁盘
}
net {
cram-hmac-alg md5; ##设置加密算法md5
shared-secret "testdrbd"; ##加密密码
}
syncer {
rate 30M; ##传输速率
}
}
[root@primary ~]# vim /etc/drbd.d/r0.res
resource r0 {
on primary {
device /dev/drbd0; //这是Primary机器上的DRBD虚拟块设备,事先不要格式化
disk /dev/sdb1;
address 192.168.1.1:7898;
meta-disk internal;
}
on secondary {
device /dev/drbd0; //这是Secondary机器上的DRBD虚拟块设备,事先不要格式化
disk /dev/sdb1;
address 192.168.1.2:7898; //DRBD监听的地址和端口。端口可以自己定义
meta-disk internal;
}
}
1.3 在两台机器上添加DRBD磁盘
在Primary机器上添加一块20G的硬盘作为DRBD,分区为/dev/sdb1,不做格式化,并在本地系统创建/data目录,不做挂载操作
[root@primary ~]# fdisk /dev/sdb
依次输入"n->p->1->回车->回车->w"
在Secondary机器上添加一块20G的硬盘作为DRBD,分区为/dev/sdb1,不做格式化,并在本地系统创建/data目录,不做挂载操作
[root@secondary ~]# fdisk /dev/sdb
依次输入"n->p->1->回车->回车->w"
1.4 在两台机器上分别创建DRBD设备并激活r0资源(下面操作在两台机器上都要执行)
[root@primary ~]# mknod /dev/drbd0 b 147 0
[root@primary ~]# drbdadm create-md r0
initializing activity log
initializing bitmap (640 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
success
[root@primary ~]# drbdadm create-md r0
You want me to create a v08 style flexible-size internal meta data block.
There appears to be a v08 flexible-size internal meta data block
already in place on /dev/sdb1 at byte offset 21473783808
Do you really want to overwrite the existing meta-data?
[need to type 'yes' to confirm] yes //此处输入yes
initializing activity log
initializing bitmap (640 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
[root@secondary ~]# mknod /dev/drbd0 b 147 0
[root@secondary ~]# drbdadm create-md r0
initializing activity log
initializing bitmap (640 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
success
[root@secondary ~]# drbdadm create-md r0
You want me to create a v08 style flexible-size internal meta data block.
There appears to be a v08 flexible-size internal meta data block
already in place on /dev/sdb1 at byte offset 21473783808
Do you really want to overwrite the existing meta-data?
[need to type 'yes' to confirm] yes //此处输入yes
initializing activity log
initializing bitmap (640 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
1.5 启动drbd服务(注意:需要主从共同启动方能生效)
[root@primary ~]# systemctl start drbd
[root@primary ~]# systemctl enable drbd
[root@secondary ~]# systemctl start drbd
[root@secondary ~]# systemctl enable drbd
1.6 查看状态(两台机器上都执行查看)
[root@primary ~]# 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
0: 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:20969820
[root@secondary ~]# 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
0: 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:20969820
1.7 将Primary主机配置为DRBD的主节点
[root@primary ~]# drbdsetup /dev/drbd0 primary --force
1.8 挂载DRBD
[root@primary ~]# mkfs.ext4 /dev/drbd0
[root@primary ~]# mkdir /data
[root@primary ~]# mount /dev/drbd0 /data
1.9 测试主节点宕机手动切换节点
[root@primary ~]# cd /data/
[root@primary data]# touch haha
[root@primary data]# cd ..
[root@primary /]# umount /data/
[root@primary /]# drbdsetup /dev/drbd0 secondary
下面是在Secondary 备份节点上操作记录,先进行提权操作,即将Secondary手动升级为DRBD的主节点
[root@secondary ~]# drbdsetup /dev/drbd0 primary
[root@secondary ~]# mkdir /data
[root@secondary ~]# mount /dev/drbd0 /data
[root@secondary ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 48G 1.7G 47G 4% /
devtmpfs 476M 0 476M 0% /dev
tmpfs 488M 0 488M 0% /dev/shm
tmpfs 488M 6.7M 481M 2% /run
tmpfs 488M 0 488M 0% /sys/fs/cgroup
/dev/sda1 197M 132M 65M 67% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/drbd0 20G 45M 19G 1% /data
[root@secondary ~]# cd /data/
[root@secondary data]# ls
haha
在Secondary节点上继续写入数据,然后模拟Secondary节点故障,Primary节点再提权升级为DRBD主节点
[root@secondary data]# touch heihei
[root@secondary data]# ls
haha heihei
[root@secondary data]# cd ..
[root@secondary /]# umount /data/
[root@secondary /]# drbdsetup /dev/drbd0 secondary
主节点操作
[root@primary /]# drbdsetup /dev/drbd0 primary
[root@primary /]# mount /dev/drbd0 /data
[root@primary /]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 48G 1.7G 47G 4% /
devtmpfs 476M 0 476M 0% /dev
tmpfs 488M 0 488M 0% /dev/shm
tmpfs 488M 6.7M 481M 2% /run
tmpfs 488M 0 488M 0% /sys/fs/cgroup
/dev/sda1 197M 132M 66M 67% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/drbd0 20G 45M 19G 1% /data
[root@primary /]# cd data/
[root@primary data]# ls
haha heihei
到此,DRBD的主从环境的部署工作已经完成。不过上面是记录的是主备手动切换,至于保证DRBD主从结构的智能切换,实现高可用,还需里用到Keepalived。
2 安装nfs及配置
[root@primary ~]# yum install rpcbind nfs-utils -y
[root@primary ~]# vim /etc/exports
/data 192.168.1.0/24(rw,sync,no_root_squash)
[root@primary ~]# systemctl start rpcbind
[root@primary ~]# systemctl start nfs
[root@primary ~]# systemctl enable rpcbind
[root@primary ~]# systemctl enable nfs
[root@secondary ~]# yum install rpcbind nfs-utils -y
[root@secondary ~]# vim /etc/exports
/data 192.168.1.0/24(rw,sync,no_root_squash)
[root@secondary ~]# systemctl start rpcbind
[root@secondary ~]# systemctl start nfs
[root@secondary ~]# systemctl enable rpcbind
[root@secondary ~]# systemctl enable nfs
3 安装keepalived及配置
3.1 安装keepalived
[root@primary ~]# yum install keepalived -y
[root@secondary ~]# yum install keepalived -y
3.2 配置文件
primary
[root@primary ~]# vim /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 eth1
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nfs
}
notify_stop /etc/keepalived/notify_stop.sh
notify_master /etc/keepalived/notify_master.sh
virtual_ipaddress {
192.168.1.20
}
}
secondary
[root@secondary ~]# vim /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 eth1
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
notify_master /etc/keepalived/notify_master.sh
notify_backup /etc/keepalived/notify_backup.sh
virtual_ipaddress {
192.168.1.20
}
}
3.3 检测监本
此脚本只在Primary机器上配置
[root@primary ~]# vim /etc/keepalived/check_nfs.sh
#!/bin/bash
# 检查nfs可用性:进程和是否能够挂载
systemctl status nfs &>/dev/null
if [ $? -ne 0 ];then
# 如果服务状态不正常,先尝试重启服务
systemctl restart nfs
systemctl status nfs &>/dev/null
if [ $? -ne 0 ];then
# 若重启nfs服务后,仍不正常
# 卸载drbd设备
umount /dev/drbd0
# 将drbd主降级为备
drbdadm secondary r0
# 关闭keepalived
systemctl stop keepalived
fi
fi
[root@primary ~]# chmod 0755 /etc/keepalived/check_nfs.sh
此脚本只在Primary机器上配置
[root@primary ~]# mkdir /etc/keepalived/logs
[root@primary ~]# vim /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
systemctl stop nfs &>> /etc/keepalived/logs/notify_stop.log
/bin/umount /data &>> /etc/keepalived/logs/notify_stop.log
/sbin/drbdadm secondary r0 &>> /etc/keepalived/logs/notify_stop.log
echo -e "\n" >> /etc/keepalived/logs/notify_stop.log
[root@primary ~]# chmod 0755 /etc/keepalived/notify_stop.sh
此脚本在两台机器上都要配置
[root@primary ~]# vim /etc/keepalived/notify_master.sh
[root@secondary ~]# vim /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 r0 &>> /etc/keepalived/logs/notify_master.log
/bin/mount /dev/drbd0 /data &>> /etc/keepalived/logs/notify_master.log
systemctl restart nfs &>> /etc/keepalived/logs/notify_master.log
echo -e "\n" >> /etc/keepalived/logs/notify_master.log
[root@primary ~]# chmod 0755 /etc/keepalived/notify_master.sh
[root@secondary ~]# chmod 0755 /etc/keepalived/notify_master.sh
此脚本只在Secondary机器上配置
[root@secondary ~]# mkdir /etc/keepalived/logs
[root@secondary ~]# vim /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
systemctl stop nfs &>> /etc/keepalived/logs/notify_backup.log
/bin/umount /dev/drbd0 &>> /etc/keepalived/logs/notify_backup.log
/sbin/drbdadm secondary r0 &>> /etc/keepalived/logs/notify_backup.log
echo -e "\n" >> /etc/keepalived/logs/notify_backup.log
[root@secondary ~]# chmod 0755 /etc/keepalived/notify_backup.sh
3.4 启动keepalived
[root@primary ~]# systemctl start keepalived
[root@primary ~]# systemctl enable keepalived
[root@secondary ~]# systemctl start keepalived
[root@secondary ~]# systemctl enable keepalived
3.5 在远程客户机上挂载NFS
[root@emm ~]# yum install rpcbind nfs-utils -y
[root@emm ~]# systemctl start rpcbind
[root@emm ~]# mount -t nfs 192.168.1.20:/data /data
[root@emm ~]# vim /etc/fstab
192.168.1.20:/data /data nfs defaults 0 0
安装过程使用的部分命令
ansible backup -m shell -a "hostnamectl set-host backup"
ansible backup -m shell -a "hostnamectl set-hostname backup"
vim /etc/hosts
ansible all -m copy -a "src=/etc/hosts dest=/etc/hosts"
ansible all -m shell -a "hostname -i"
vim ifcfg-eth1.j2
vim setip.yml
ansible-playbook setip.yml
vim setip.yml
ansible-playbook setip.yml
ip l s mtu 1450 dev eth1
ip a a 192.168.1.100/16 brd 192.168.255.255 dev eth1
ifup eth1
ip l set up dev eth1
ansible all -m service -a "name=firewalld state=stopped enabled=false"
ansible all -m yum -a "name=kernel-devel,kernel,kernel-headers"
ansible all -m shell -a "sed -i s/=enforcing/=disabled/g /etc/selinux/config"
ansible all -m shell -a "reboot"
ssh root@192.168.1.1 "dhclient eth0"
ansible -m ping
ansible all -m ping
ansible all -m shell -a "rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm"
echo "安装drdb模块"
ansible all -m yum -a "name=drbd84-utils,kmod-drbd84"
echo "加载drdb模块"
ansible all -m shell -a "modprobe drbd"
vim hosts
ansible all -m ping
ansible all -m shell -a "dhclient eth0"
ansible all -m shell -a "reboot"
ansible all -m shell -a "dhclient eth0"
ansible all -m shell -a "modprobe drbd"
ansible all -m service -a "name=drbd stated=started"
ansible all -m service -a "name=drbd state=started"
ansible all -m shell -a "cat /proc/drbd "
ansible all -m yum -a "name=rpcbind,nfs-utils"
ansible all -m service -a "name=rpcbind state=started enabled=true"
ansible all -m service -a "name=nfs state=started enabled=true"
ansible all -m yum -a "name=keepalived state=installed"
ansible all -m service -a "name=keepalived state=started enabled=true"
yum install rpcbind nfs-utils -y
systemctl start rpcbind
mount -t nfs 192.168.1.20:/data /data
mkdir /data
mount -t nfs 192.168.1.20:/data /data
ansible all -m shell -a "echo '/data 192.168.1.0/16(rw,sync,no_root_squash)' >>/etc/exports"
ansible all -m service -a "name=nfs state=restarted"
mount -t nfs 192.168.1.20:/data /data
[root@manage mansible]# ls
ansible.cfg hosts ifcfg-eth1.j2 setip.yml testnfsalive.sh
[root@manage mansible]# cat *
ansible.cfg
[defaults]
inventory=hosts
host_key_checking=False
hosts
[master]
192.168.1.1
[backup]
192.168.1.2
[nfs:children]
master
backup
[nfs:vars]
ansible_ssh_user=root
ansible_ssh_pass=Abcabc123
ifcfg-eth1.j2
DEVICE=eth1
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR={{ipinfo['stdout']}}
NETMASK=255.255.0.0
IPV6INIT=no
MTU=1450
setip.yml
---
- hosts: all
remote_user: root
tasks:
- name: register ip
shell: hostname -i
register: ipinfo
- name: cpIpconf
template: src=ifcfg-eth1.j2 dest=/etc/sysconfig/network-scripts/ifcfg-eth1
# notify:
# # - up eth1
# #
# # handlers:
# # - name: up eth1
# # shell: /usr/sbin/ifup eth1
# #
- name: up eth1
shell: ifup eth1
testnfsalive.sh
#!/bin/bash
while [ 1 -eq 1 ]
do
echo `date`
echo `date` >>/data/date
sleep 1
done
关于脑裂(split-brain)处理
实际上是指在某种情况下,造成drbd的两个节点断开了连接,都以primary的身份来运行。当drbd某primary节点连接对方节点准备发送信息的时候如果发现对方也是primary状态,那么会会立刻自行断开连接,并认定当前已经发生split brain了,这时候他会在系统日志中记录以下信息:“Split-Brain detected,dropping connection!”
当发生split brain之后,如果查看连接状态,其中至少会有一个是StandAlone状态,另外一个可能也是StandAlone(如果是同时发现split brain状态),也有可能是WFConnection的状态。 drbdmon 查看状态
drbdadmin status
处理
查看日志发现脑裂
tail -n 12 /var/log/messages
Sep 21 11:19:53 lab4 kernel: block drbd0: Split-Brain detected but unresolved, dropping connection!
Sep 21 11:19:53 lab4 kernel: block drbd0: helper command: /sbin/drbdadm split-brain minor-0
Sep 21 11:19:53 lab4 kernel: block drbd0: helper command: /sbin/drbdadm split-brain minor-0 exit code 0 (0x0)
Sep 21 11:19:53 lab4 kernel: block drbd0: conn( WFReportParams -> Disconnecting )
Sep 21 11:19:53 lab4 kernel: block drbd0: error receiving ReportState, l: 4!
Sep 21 11:19:53 lab4 kernel: block drbd0: meta connection shut down by peer.
Sep 21 11:19:53 lab4 kernel: block drbd0: asender terminated
Sep 21 11:19:53 lab4 kernel: block drbd0: Terminating drbd0_asender
Sep 21 11:19:53 lab4 kernel: block drbd0: Connection closed
Sep 21 11:19:53 lab4 kernel: block drbd0: conn( Disconnecting -> StandAlone )
Sep 21 11:19:53 lab4 kernel: block drbd0: receiver terminated
Sep 21 11:19:53 lab4 kernel: block drbd0: Terminating drbd0_receiver
保留主节点数据,丢弃从节点数据.
主节点执行:
#设置主节点
drbdadm primary r0
mount /dev/drbd0 /data
ls -lh /data
查看文件情况
从节点执行:
#设置自己为从节点
drbdadm secondary r0
drbdadm -- --discard-my-data connect r0
#丢弃自己数据
drbdadm connect r0
手动连接主资源节点
经过测试 故障切换大概10s左右不可用时间.
该内容来自大神博客:https://www.mrlapulga.com/?p=365
参考
https://blog.csdn.net/sfdst/article/details/77879684
https://blog.csdn.net/tjiyu/article/details/52723125
使用DRBD+KEEPALIVED来实现NFS高可用的更多相关文章
- Mfs+drbd+keepalived实现mfs系统高可用
http://blog.sina.com.cn/s/blog_53c654720102wo1k.html Moosefs分布式文件系统是一个易用的系统,但其只有在Pro版中提供了master的高可用方 ...
- (转)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的服务. ...
- (转)基于keepalived搭建MySQL的高可用集群
基于keepalived搭建MySQL的高可用集群 原文:http://www.cnblogs.com/ivictor/p/5522383.html MySQL的高可用方案一般有如下几种: keep ...
- Linux集群介绍、keepalived介绍及配置高可用集群
7月3日任务 18.1 集群介绍18.2 keepalived介绍18.3/18.4/18.5 用keepalived配置高可用集群扩展heartbeat和keepalived比较http://blo ...
- 基于keepalived对redis做高可用配置---转载
关于keepalived的详细介绍,请移步本人相关博客:http://wangfeng7399.blog.51cto.com/3518031/1405785 功能 ip地址 安装软件 主redis 1 ...
- 搭建 Keepalived + Nginx + Tomcat 的高可用负载均衡架构
1 概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最简单的部署方式,但是随着业务的不断扩大,系统的访问量逐渐的上升,单机部署的模式已无法承载现有的业务量 ...
- Keepalived+Nginx搭建主从高可用并带nginx检测
应用环境:部分时候,WEB访问量一般,或者测试使用,利用Keepalived给Nginx做高可用即可满足要求. 测试环境: 搭建步骤: 1. 安装软件 在Nginx-A和Nginx-B上: ~]# ...
- Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建
Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建 Nginx 是一个高性能的 HTTP反向代理服务器 Keepalived 是一个基于VRRP协议来实现的LVS服务高可 ...
随机推荐
- shellexecute的使用和X64判断
bool RunConsoleAsAdmin(std::string appPath, std::string param, bool wait) { LOG_INFO << " ...
- 【转】使用Scanner输入字符串时next()和nextLine()区别
在实现字符窗口的输入时,很多人更喜欢选择使用扫描器Scanner,它操作起来比较简单.在编程的过程中,我发现用Scanner实现字符串的输入有两种方法,一种是next(),一种nextLine(),但 ...
- py map reduce filter 总结
array=[1,3,4,71,2] ret=[] for i in array: ret.append(i**2) print(ret) #如果我们有一万个列表,那么你只能把上面的逻辑定义成函数 d ...
- java一些基本算法
本文主要介绍一些常用的算法: 冒泡排序:两两相互之间进行比较,如果符合条件就相互兑换. //冒泡排序升序 public static int[] bubblingSortAsc(int[] array ...
- unittest 运行slenium(三)---通过数据驱动形式运行用例
一: 获取数据 获取用例所在位置,通过OpenExcelPandas来读取用例里面的全部数据.通过某个列名来创建新的序号. 并将结果转换成list类型,将其作为ddt数据的来源. 1. 在test文 ...
- Set的交集、差集踩坑记录
项目中我用到了Set的retainAll和removeAll两个方法取差集和交集. 用法网上都有,我也不展示了. 但是因为我是急着用,直接就照着写了,没想到出大问题了. 因为我的set是一个map的k ...
- 【kernel】Centos 云上升级内核失败 如何处理【笔记记录转】
Centos7选定默认启动的内核版本 vim /etc/grub2.cfg 修改timeout =5 修改成30天 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附 ...
- STL的sort函数是使用什么排序算法的?
先占坑,大概就是主要快速排序+插入排序+堆排序的合体
- ES6中let、const和var的区别
一.let 1.基本用法 ES6 新增了let命令,用来声明变量. let 的用法类似于 var,但所声明的变量只在 let 命令所在的代码块内有效(一个“{}”相当于一个代码块) { let a = ...
- Mongoose初使用总结
连接mongoose mongoose连接数据库有两种方式 第一种: 'use strict'; const mongoose = require('mongoose'); mongoose.conn ...