利用DRBD+heartbeat实现NFS文件共享服务高可用[原创]
DRBD由PhilippReisner and LarsEllenberg 开发维护, 它是基于Linux系统下的块复制分发设备.
它可以让你把本地磁盘镜像复制到远程主机上. 把它加上心跳(heartbeat,HB)功能, 就可以构建Linux下的高可用(HA)集群环境. DRBD也可以成为网络RAID-1, 当数据写入本地文件系统时, 数据还将会发送到网络中另一台主机上, 以相同的形式记录在该主机的文件系统中.
本地(主节点,primary)与远程主机(备节点,secondary)的数据可以保证实时同步. 当本地系统出现故障时, 远程主机上还会保留有一份相同的数据, 可以继续使用. 其实DRBD就类似MySQL里的复制(replication), 一主一从, 主负责读写数据, 从只能读数据;在主发生故障时, 从切换成主, 继续读写数据.
在高可用(HA)中使用DRBD功能, 可以代替使用一个共享盘阵. 因为数据同时存在于本地主机和远程主机上, 切换时, 远程主机只要使用它上面的那份备份数据, 就可以继续进行服务了.
DRBD的工作原理如下图:
+————+
| 文件系统 |
+————+
|
V
+—————+
| 块设备层 |
| (/dev/drbd0) |
+—————+
| |
| |
V V
+————-+ +————–+
| 本地硬盘 | | 远程主机硬盘 |
| (/dev/sdb1) | | (/dev/sdb1) |
+————-+ +————–+
两台DRBD之间使用Heartbeat实现自动切换.
heartbeat的工作原理:heartbeat最核心的包括两个部分: 心跳监测部分和资源接管部分.
心跳监测可以通过网络链路和串口进行, 而且支持冗余链路, 它们之间相互发送报文来告诉对方自己当前的状态,
如果在指定的时间内未受到对方发送的报文, 那么就认为对方失效, 这时需启动资源接管模块来接管运行在对方
主机上的资源或者服务.
#——————————————————————-
准备工作:
一. 硬件: 两台相同的服务器.
DRBD使用的硬盘分区:
需要为主服务器和备份服务器, 指定一个DRBD使用的硬盘分区.
注意: 这两个分区的大小必须相同, 不要格式化也不要mount.
如: 两个主机都预留一个空白分区: 如/dev/sdb1 作为DRBD的使用的分区, 不要创建任何文件系统.
主服务器(primary) eth0: 10.1.2.44 eth1: 1.1.1.1(心跳检测)
备份服务器(secondary) eth0: 10.1.2.45 eth1: 1.1.1.2(心跳检测)
使用虚拟IP(VIP): 10.1.2.46对外提供服务.
在primary和secondary主机上设置相应的hosts文件.
vim /etc/hosts
127.0.0.1 localhost.localdomain localhost
10.1.2.44 centos1.ritto.cn centos1
10.1.2.45 centos2.ritto.cn centos2
平常对数据读写都在 10.1.2.44 上实现, 当10.1.2.44 down掉后可以启动10.1.2.45,
实现数据的热备份, 真正的热切换才需要用HA来实现.
#——————————————————————-
二.DRBD的安装和配置.
DRBD官方网站:http://www.linux-ha.org/DRBD
源码下载地址: http://oss.linbit.com/drbd
FAQ: http://www.linux-ha.org/DRBD/FAQ
目前流行的Linux中只有Centos有预编译好的安装包和对应内核.
如果不想用Centos可以选择从源码安装.
DRBD有两种安装模式:直接编译进内核 或 作为一个可加载的内核模块编译.
以下使用的是CentOS 5.2 i386 系统安装与测试:
1. 安装依赖库.
yum install gcc gcc-c++ make glibc flex
2. 在primary和secondary上都使用相同的安装方法:
tar zxvf drbd-8.0.6.tar.gz
cd drbd-8.0.6
make
//make KDIR=/usr/src/linux *内核所在的位置*, 如果没有更改内核可
//直接运行make, 软件会直接到/lib/module里边去寻找系统环境,
//如果是新的内核需要对内核进行编译安装, 否则make时候会错误中断掉.
make install
3. 安装完主要生成命令: “drbdsetup”, “drbdadmin”
和配置文件: /etc/drbd.conf
启动文件: /etc/init.d/drbd
模块文件: drbd.ko (在编译好的安装包目录下的drbd下可以找到)
ls /lib/modules/2.6.18-128.el5/kernel/drivers/block/
cpqarray.ko drbd.ko nbd.ko sx8.ko
所有命令和配置文件都可以在源码包编译成功的目录下面找到.
./scripts/drbd.conf是最原始的配置文件, 当/etc/drbd.conf被破坏, 可以直接拷贝覆盖掉.
4. drbd采用的是模块控制的方式, 所以先要加载drbd.ko 模块.
modprobe drbd
查看drbd模块是否已经加载到内核中了:
lsmod | grep drbd
drbd 226352 2 //有的话表示加载模块成功.
5. 先确认两台要镜像的机器是否正常, 之间的网络是否通畅, 需要加载的硬盘是否处于umount状态.
6. 在两台主机上都创建硬件设备drbd.
mknod /dev/drbd0 b 147 0
//mknod /dev/drbd1 b 147 1
//mknod /dev/drbd2 b 147 2 如需多个drbd设备则依次去创建.
7. 二台机器将/dev/sdb1互为镜相(两台机器配置相同).
yum -y install portmap
yum -y install nfs
mkdir /d //创建共享目录.
vim /etc/exports
/d 10.1.2.0/255.255.252.0(rw,no_root_squash,no_all_squash,sync)
/etc/init.d/portmap start
chkconfig –level 3 portmap on
chkconfig –level 3 nfs off
//nfs不需要启动, 也不需要设置成开机自动运行, 这些都将由后面的heartbeat来完成.
8. 配置drbd.
DRBD运行时,会读取一个配置文件/etc/drbd.conf.
这个文件里描述了DRBD设备与硬盘分区的映射关系, 和DRBD的一些配置参数.
[root@centos1 /]# vim /etc/drbd.conf
global {
usage-count yes;
}
common {
syncer { rate 30M; } //设置主备节点同步时的网络速率最大值, 单位是字节.
}
# DRBD 协议说明.
# A 数据一旦写入磁盘并发送到网络中就认为完成了写入操作.
# B 收到接收确认就认为完成了写入操作.
# C 收到写入确认就认为完成了写入操作.
# 您还可以选择其它参数来将数据传输给磁盘和网络选项. 更多详情, 请参见drbdsetup 手册页.
resource r0 { //创建一个资源,名字叫r0
protocol C; //使用协议C,表示收到远程主机的写入确认后,则认为写入完成.
startup {
wfc-timeout 0;
degr-wfc-timeout 120;
}
disk {
on-io-error detach;
# no-disk-flushes;
# no-md-flushes
# size 10G;
}
net {
}
//每个主机的说明以"on"开头, 分别是各自的主机名, 再后面的{}中为这个主机的配置.
on centos1.ritto.cn {
device /dev/drbd0; //设定资源设备/dev/drbd0指向实际的物理分区/dev/sdb1.
disk /dev/sdb1;
address 10.1.2.44:7789; //设置drbd的监听端口,用于与另外一台主机通信.
meta-disk internal; //设定元数据保存试: 可以用internal(即保存在同一个物理分区下)
} //也可以保存在其它分工上.
on centos2.ritto.cn {
device /dev/drbd0;
disk /dev/sdb1;
address 10.1.2.45:7789;
meta-disk internal;
}
}
# syncer { rate 30M; } 大小的设定:
//当不一致的block发生后, drbd就需要有re-synchronization动作, 而syncer里面设置的rate项
主要就是用于re-synchronization的时候, 因为如果有大量不一致的数据的时候, 我们不可能
将所有带宽都分配给drbd做re-synchronization, 这样会影响对外提提供服务.
rate的设置和还需要考虑IO能力的影响. 如果我们会有一个千兆网络出口, 但是我们的磁盘
IO能力每秒只有50M, 那么实际的处理能力就只有50M, 一般来说, 设置网络IO能力和磁盘IO
能力中最小者的30%的带宽给re-synchronization是比较合适的(官方说明).
另外, drbd还提供了一个临时的rate更改命令, 可以临时性的更改syncer的rate值:
drbdsetup /dev/drbd0 syncer -r 100M.
这样就临时的设置了re-synchronization的速度为100M.
不过在re-synchronization结束之后, 你需要通过drbdadm adjust resource_name
来让drbd按照配置中的rate来工作.
另外一台主机的配置同上, 内容一样
scp /etc/drbd.conf 10.1.2.45:/etc/
9.drbd的启动, 激活前面配置的drbd资源 “r0″. (两个节点都要执行)
在启动DRBD之前,你需要分别在两台主机的hdb1分区上, 创建供DRBD记录信息的数据块.
分别在两台主机上执行:
[root@centos1 /]# drbdadm create-md r0 //创建r0的资源, r0是我们在drbd.conf里定义的资源名称.
[root@centos2 /]# drbdadm create-md r0
现在可以启动drbd了, 分别在两台主机上执行.
[root@centos1 /]# /etc/init.d/drbd start
[root@centos2 /]# /etc/init.d/drbd start
设置drbd开机自动启动.
[root@centos1 /]# chkconfig –level 3 drbd on
[root@centos2 /]# chkconfig –level 3 drbd on
现在可以查看drbd当前的状态, 然后在centos1上执行:
[root@centos1 /]# cat /proc/drbd
version: 8.0.0 (api:86/proto:86)
SVN Revision: 2713 build by root@centos1, 2008-06-27 14:07:14
1: cs:Connected st:Secondary/Secondary ds:Inconsistent/Inconsistent C r—
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0
resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0
act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0
第一行的’st’表示两台主机的状态,都是”备机”状态.
‘ds’是磁盘状态,都是”不一致”状态.
这是由于,DRBD无法判断哪一方为主机,以哪一方的磁盘数据作为标准数据.
所以,我们需要初始化一个主机, 那么需要在centos1上执行.
10.初始化centos1(这步只要在主节点上操作)
[root@centos1 /]# drbdsetup /dev/drbd0 primary -o //定义为主节点.
# drbdadm primary r0
第一次设置主节点时用 drbdadm 命令会失败, 所以先用drbdsetup 来做, 以后就可以用drbdadm了.
再次查看drbd当前的状态.
[root@centos1 ~]# cat /proc/drbd
version: 8.0.0 (api:86/proto:86)
SVN Revision: 2713 build by root@centos1, 2008-06-27 14:07:14
1: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r—
ns:18528 nr:0 dw:0 dr:18528 al:0 bm:1 lo:0 pe:0 ua:0 ap:0
[>...................] sync’ed: 0.3% (8170/8189)M
finish: 6:46:43 speed: 336 (324) K/sec
resync: used:0/31 hits:1156 misses:2 starving:0 dirty:0 changed:2
act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0
现在主备机状态分别是’主/备’, 主机磁盘状态是’实时’, 备机状态是’不一致’.
在第3行, 可以看到数据正在同步中, 即主机正在将磁盘上的数据, 传递到备机上.
现在的进度是0.3%.
设置完之后的第一次同步耗时比较长, 因为需要把整个分区的数据全部同步一遍.
第一次同步完成之后, 就可以对drbd的设备创建文件系统了:
稍等一段时间, 在数据同步完后, 再查看一下两台机器的DRBD状态:
[root@centos1 ~]# cat /proc/drbd
SVN Revision: 3048 build by root@centos1.ritto.cn, 2010-01-20 06:09:12
0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r—
[root@centos2 ~]# service drbd status
SVN Revision: 3048 build by root@centos2.ritto.cn, 2010-01-20 06:09:02
0: cs:Connected st:Secondary/Primary ds:UpToDate/UpToDate C r—
现在磁盘状态都是’实时’, 表示数据同步完成了.
11.drbd的使用.
现在可以把主机上的DRBD设备挂载到一个目录上进行使用.
备机的DRBD设备无法被挂载, 因为它是用来接收主机数据的, 由DRBD负责操作.
在centos1主服务器上执行:
[root@centos1 /]# mkfs.ext3 /dev/drbd0
[root@centos1 mnt]# mount /dev/drbd0 /d //只要在主节点上操作
现在, 就可以对 /d 分区进行读写操作了.
注意: secondary节点上不允许对drbd设备进行任何操作, 包括只读.
所有的读写操作只能在primary节点上进行.
只有当primary节点挂掉之后, secondary节点才能提升成为primary节点, 继续进行读写操作.
12. drbd的相关测试.
(1). DRBD常规测试:
来演示一下主节点挂掉, 然后重新恢复连接的情况.
这里已经设定好centos1为primary节点了.
拔掉centos1的网线或ifdown eth0
[root@centos1 /]# cat /proc/drbd 或drbdadm state r0
st: Primary/Unknow
可以看到, 在primary节点上找不到secondary节点了.
再来看看此时secondary节点上的状态显示:
[root@centos2 /]# cat /proc/drbd
st: Secondary/Unknow
[root@centos2 /]# drbdadm state r0
Secondary/Unknow
在secondary节点上也找不到primary了.
现在插上primary节点的网线或让primary节点的网卡启动ifup eth0:
[root@centos1 /]# cat /proc/drbd
st: Primary/Unknow //还是显示未连接状态.
在刚才关闭网卡的primary节点上执行如下命令:
[root@centos1 /]# drbdadm connect r0 //意思是让drbd主动去连接另一个节点.
[root@centos1 /]# cat /proc/drbd
st: Primary/Secondary
可以看到, 已经呈连接状态了.
# 记住: 如果是secondary节点挂掉了, 它恢复正常后, 想要再次连接primary节点
的话, 考虑到可能会有数据丢失, 可以采用以下方式来连接:
[root@centos2 /]# drbdadm — –discard-my-data connect r0
它告诉drbd, secondary节点上的数据可能是不正确的, 要以primary节点上的为准.
这个命令只能在secondary节点上使用, 毕竟数据是以primary节点为准的, 而非secondry节点.
# 不过, 如果是primary节点挂掉了, 这个时候就应该把原来的secondary节点提升为primary的角色,
等原来的primary恢复之后, 只能先降级成为secondary节点了, 否则是无法再次正确连接另一个节点的.
(2). DRBD主从切换测试:
如果需要将drbd的主备机互换一下, 可以执行下面的操作.
在primaty主机上,先要卸载掉DRBD设备.
[root@centos1 /]# umount /d
将主机降级为”备机”.
[root@centos1 /]# drbdadm secondary r0
[root@centos1 /]# cat /proc/drbd
1: cs:Connected st:Secondary/Secondary ds:UpToDate/UpToDate C r—
现在,两台主机都是”备机”.
在备机centos2上, 将它升级为”主机”.
[root@centos2 /]# drbdadm primary r0
[root@centos2 /]# cat /proc/drbd
1: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r—
现在centos2成为主机了.
(3). Split-Brain脑裂的解决方法:
假设此时把primary的 eth0 给ifdown了, 然后直接在secondary上进行主的提升,
并也给mount了, 发现在primary上测试拷入的文件确实同步过来了.
之后把primary的 eth0 恢复后, 发现没有自动恢复主从关系, 经过支持查询,
发现出现了drbd检测出现了Split-Brain 的状况, 两个节点各自都standalone了.
以下手动恢复Split-Brain状况:
i. 在secondary上:
drbdadmin secondary r0
drbdadmin — –discard-my-data connect r0
ii.在primary上:
drbdadmin connect r0
(4). DRBD文件写入测试:
如先在primary节点上写入数据:
[root@centos1 /]# cp mysql-5.1.38.tar.gz /d
[root@centos1 ~]# ls /d
lost+found mysql-5.1.38.tar.gz
然后, 再把primary降级成secondary, 把secondary提升成primary.
在primary降级前, 一定要先umount设备才行.
[root@centos1 ~]# umount /d
[root@centos1 ~]# drbdadm secondary r0
然后再提升secondary:
[root@centos2 ~]# drbdadm primary r0
[root@centos1 ~]# mount /dev/drbd0 /d
[root@centos1 ~]# ls /d
lost+found mysql-5.1.38.tar.gz
可以看到, 数据已经同步过去了.
(5). 其它测试项目:
i. 拔掉网线,测试在primary节点的网络断开后的切换情况。
ii. 重新启动 primary 主机, 测试主从切换情况。
iii.primary node 掉电测试。
测试结果:
i. 向主节点上写入数据,当拔掉主节点网线的时候,
出现”Split-Brain detected, dropping connection!”, 由于drbd.conf配
置里面没有配置自动处理脑裂的情况,这个时候需要手动处理.
ii. 当向主节点里面写入数据, 重新启动主节点, 查询数据数据没有丢失, 2节点数据一致.
iii.当向主节点里面写入数据, 拔掉主节点的电源线, 当主节点起来的时候, 查询数据没有丢失, 2节点数据一致.
小结:
从测试的结果来看,基本上能满足项目的需求, 就是在拔掉网线的时候, 出现脑裂,
数据出现不一致的情况, 这点有点问题, 官方推荐还是手动解决比较好.
(6). 几点注意的地方:
i. mount drbd设备以前必须把设备切换到primary状态。
ii. 两个节点中,同一时刻只能有一台处于primary状态,另一台处于secondary状态。
iii. 处于secondary状态的服务器上不能加载drbd设备。
iv. 主备服务器同步的两个分区大小最好相同,这样不至于浪费磁盘空间,因为drbd磁盘镜像相当于raid 1.
#——————————————————————-
HeartBeat.
HeartBeat用于搭建双机热备环境, 可以通过专门的心跳线来连接双机, 也可以通过普通的网线来连接.
官方网站:http://www.linux-ha.org/HeartBeat
1. 安装, 在两台主机都同样的安装.
yum -y install heartbeat
其中Heartbeat配置共涉及3个文件.
/etc/ha.d/ha.cf
/etc/ha.d/haresources
/etc/ha.d/authkeys
2. 二个节的配置的配置文件都是一样, 文件内容如下
[root@centos1 /]# vim /etc/ha.d/ha.cf
# ha的日志文件记录位置. 如没有该目录, 则需要手动添加 #debugfile /var/log/ha-debug.log logfile /var/log/ha-log logfacility local0 keepalive 2 //设定心跳(监测)时间时间为2秒 warntime 5 deadtime 20 initdead 120 #hopfudge 1 udpport 694 //使用udp端口694 进行心跳监测 auto_failback off //这个选项就是如果主服务器正常后由主服务器接管资源, //另一台服务器应该放弃资源的. #baud 19200 bcast eth1 //使用eth0做心跳监测 #ucast eth0 10.1.2.44 #watchdog /dev/watchdog #crm on node centos1.ritto.cn //节点1,必须要与 uname -n 指令得到的结果一致. node centos2.ritto.cn //节点2. ping 192.168.10.1 //通过ping网关检测心跳是否正常. #ping 10.1.2.44 10.1.2.45 10.1.2.46 #deadping 5 #ping_group lbgroup 1.1.1.1 1.1.1.2 //串口线直连或交叉线连接, Heartbeat. #ping_group lbgroup 10.1.2.44 10.1.2.45 //指定和heartbeat一起启动、关闭的进程 respawn hacluster /usr/lib/heartbeat/ipfail apiauth ipfail gid=haclient uid=hacluster
//从heartbeat的官方文档来看, 目前的ping节点还没什么实际用途, 只是用于检测节点
//的连通性, 并不作为节点切换的真正依据. 在将来的新版本中也许会这么做.
2. 编辑双机互联验证文件: authkeys
[root@centos1 ha.d]# vim /etc/ha.d/authkeys
auth 1 1 crc
//需要将 /etc/ha.d/authkeys设为600的权限.
[root@centos1 ha.d]# chmod 600 /etc/ha.d/authkeys
[root@centos2 ha.d]# chmod 600 /etc/ha.d/authkeys
3. 编辑集群资源文件: haresources
[root@centos1 ha.d]# vim /etc/ha.d/haresources
centos1.ritto.cn IPaddr::10.1.2.46/22/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/d::ext3 nfs
#[root@centos1 ha.d]# vim /etc/ha.d/resource.d/killnfsd
#killall -9 nfsd; /etc/init.d/nfs restart; exit 0
#[root@centos1 ha.d]# chmod 755 /etc/ha.d/resource.d/killnfsd
4. 在二个节点启动Heartbeat即可,先在主节点启动
[root@centos1 /]# /etc/init.d/heartbeat start
[root@centos2 /]# /etc/init.d/heartbeat start
# 确定需要由heartbeat切换的服务, 开机不自启动(由heartbeat来启用相关的服务)
5. 测试使用
将10.1.2.46:/d挂到本地/test
[root@test /]# mount 10.1.2.46:/d /mnt/test
将主节点的heartbeat服务停止, 则备节点node2接管服务
/etc/init.d/heartbeat stop
# 在这里, 可以像第一种方式那样, 指定优先节点为 centos1, 如果ha发现优先节点当掉了,
则另一个节点会自动把ip改成 10.1.2.46, 并且启动资源 drbd, 即用以下方式启动:
/etc/ha.d/resource.d/drbd start
当ha发现优先节点恢复正常后, 就会通知另一个节点, 关闭资源, 切换回优先节点.
这个时候节点2上会先执行以下命令关闭资源:
/usr/local/etc/ha.d/resource.d/drbd stop
然后, 优先节点上执行以下命令重新启动资源:
/usr/local/etc/ha.d/resource.d/drbd start
其中haresources里指定的资源,可以是多个, 启动时按照从左到右的顺序, 关闭时则按照从右到左的顺序.
6. 测试
可以通过几种方式来模拟节点当掉:
如关闭网卡, iptables防火墙, 当然了, 也可以直接关机.
由于ha.cf中指定是用bcast的方式来检测节点是否连通, 因此采用iptables防火墙时, 还需要把广播包给禁用了.
iptables -A input -m pkttype –pkt-type broadcast -j DROP
辛苦博主啦,感谢分享