一、简单介绍

    Distributed Replicated Block Device(DRBD)是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。其核心功能通过Linux的内核实现,比文件系统更加靠近操作系统内核及IO栈。DRBD是由内核模块和相关脚本而构成,用以构建高可用性的集群。可以理解为网络RAID1.

复制原理

    每个设备(drbd 提供了不止一个设备)都有一个状态,可能是‘主’状态或‘从’状态。在主节点上,应用程序应能运行和访问drbd设备(/dev/drbd*)。每次写入都会发往本地磁盘设备和从节点设备中。从节点只能简单地把数据写入它的磁盘设备上。 读取数据通常在本地进行。 如果主节点发生故障,心跳(heartbeatcorosync)将会把从节点转换到主状态,并启动其上的应用程序。(如果您将它和无日志FS 一起使用,则需要运行fsck)。如果发生故障的节点恢复工作,它就会成为新的从节点,而且必须使自己的内容与主节点的内容保持同步。当然,这些操作不会干扰到后台的服务

 

1、复制方式

单主模式 任何特定时间范围内,集群只存在一个主节点,可用于任何文件系统上,包括ext3ext4

双主模式 任何特定时间范围内,集群存在两个主节点,不过这种模式需要借助一个共享的文件系统,如GFSMFS

2、复制协议

协议A:异步复制协议。本地写成功后立即返回,数据放在发送buffer中,可能丢失。

协议B:内存同步(半同步)复制协议。本地写成功并将数据发送到对方后立即返回,如果双机掉电,数据可能丢失。

协议C:同步复制协议。本地和对方写成功确认后返回。如果双机掉电或磁盘同时损坏,则数据可能丢失。对网络依赖比较大。 

配置工具

drbdadm:高级管理工具,管理/etc/drbd.conf,向drbdsetupdrbdmeta发送指令。

drbdsetup:配置装载进kernelDRBD模块,平时很少直接用。

drbdmeta:管理META数据结构,平时很少直接用。

配置文件

    DRBD的主配置文件为/etc/drbd.conf;为了管理的便捷性,目前通常会将些配置文件分成多个部分,且都保存至/etc/drbd.d目录中,主配置文件中仅使用"include"指令将这些配置文件片断整合起来。通常,/etc/drbd.d目录中的配置文件为global_common.conf和所有以.res结尾的文件。其中global_common.conf中主要定义global段和common段,而每一个.res的文件用于定义一个资源。

在配置文件中,global段仅能出现一次,且如果所有的配置信息都保存至同一个配置文件中而不分开为多个文件的话,global段必须位于配置文件的最开始处。目前global段中可以定义的参数仅有minor-count, dialog-refresh, disable-ip-verificationusage-count

    common段则用于定义被每一个资源默认继承的参数,可以在资源定义中使用的参数都可以在common段中定义。实际应用中,common段并非必须,但建议将多个资源共享的参数定义为common段中的参数以降低配置文件的复杂度。

    resource段则用于定义drbd资源,每个资源通常定义在一个单独的位于/etc/drbd.d目录中的以.res结尾的文件中。资源在定义时必须为其命名,名字可以由非空白的ASCII字符组成。每一个资源段的定义中至少要包含两个host子段,以定义此资源关联至的节点,其它参数均可以从common段或drbd的默认中进行继承而无须定义。各个对等节点之间需要进行数据通信,所以需要配置主机互信机制。

    资源角色有primarysecondary两种。primary可以进行不受限制的读和写操作,可用来创建和挂载文件系统、初始化I/O的块设备。secondary接收所有来自对等节点的更新,不能被应用也不能被读写访问。主要目的是保持缓冲及数据一致性。

人工干预和管理程序的自动聚类算法都可以改变资源的角色。资源可以由被变换为主,以及主到备。

 

脑裂通知和自动恢复

    split brain实际上是指在某种情况下,造成drbd的两个节点断开连接,都以primary的身份来运行。当drbdprimary节点连接对方节点准备发送信息的时候如果发现对方也是primary状态,那么会立刻自行断开连接,并认定当前已经发生split brain了,这时候他会在系统日志中记录以下信息:“Split-Brain detected,dropping connection!”当发生split brain之后,如果查看连接状态,其中至少会有一个是StandAlone状态,另外一个可能也是StandAlone(如果是同时发现split brain状态),也有可能是WFConnection的状态。

 

drbd 脑裂主要在 net 配置,有以下关键字:

after-sb-0pri:裂脑已经被探测到,但是现在没有节点处于主角色,对于这个选项, drbd 有以下关键字:

    disconnect:

        不需要自动恢复,仅仅是调用裂脑处理程序的脚本(如果配置了),断开连接并出在断开模式。

    discard-younger-primary:

        放弃和回滚最后成为主的上面所做的修改。

    discard-least-changes:

        放弃和回滚,变动比较少的主机上的修改。

    discard-zero-changes:

        如果任何节点都没有发生任何变化,仅仅申请在一个节点上做出继续修改即可。

 

    after-sb-1pri:裂脑已经被探测到,现有有一个节点处于主角色,对于这个选项, drbd 有以下关键字:

    disconnect: after-sb-0pri 一样, 调用裂脑处理程序的脚本(如果配置了),断开连接并出在断开模式。

    consensus: after-sb-0pri 中同样的修复策略。 如果利用这些策略裂脑危害能选择,那就能自动解决。 否则,同样断开指定的动作。

    call-pri-lost-after-sb: after-sb-0pri 中同样的修复策略。如果利用这些策略裂脑危害能选择,就在受危害的节点上调用

    pri-lost-after-sb 程序。这个程序必须确认在 handlers 中配置,并考虑到从集群中移除该节点。

    discard-secondary:不管哪个主机只要处于次角色,都是裂脑的危害者。

    after-sb-2pri:在两个节点都处于主角色时,裂脑被发现。次选项使用和after-sb-1pri同样的关键字,丢弃次节点并达成共识。

二、配置过程

1修改主机名

[root@MidApp ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.221.161 MidApp
192.168.221.160 DB

2配置两台机器的互信机制

[root@MidApp ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
0c:39:e2:6d:cf:02:b9:94:7b:1f:b7:6f:b1:49:3d:a1 root@MidApp
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|       .         |
|    . +          |
|   . = +      .  |
|    * o S    o . |
|   . = o    E o  |
|    o o + .. + . |
|     . o o .+    |
|        . .o.    |
+-----------------+
[root@MidApp pgsql]# ssh-copy-id 192.168.221.160
root@192.168.221.160's password: 
Now try logging into the machine, with "ssh '192.168.221.160'", and check in:
 
  .ssh/authorized_keys
 
to make sure we haven't added extra keys that you weren't expecting.
 
[root@MidApp pgsql]# ssh DB
The authenticity of host 'db (192.168.221.160)' can't be established.
RSA key fingerprint is 3c:83:03:dc:63:6e:f3:e1:db:db:43:fc:c3:03:19:c2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'db' (RSA) to the list of known hosts.
Last login: Mon Dec  4 20:00:47 2017 from 172.30.25.29

3设置时钟同步

[root@MidApp ~]# crontab -l
*/5 * * * * ntpdate cn.pool.ntp.org

4安装DRBD程序包

yum install -y glibc 
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 
rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
yum install -y kmod-drbd84 drbd84-utils

若遇到下面问题,要安装nss

[root@MidApp ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
curl: (35) SSL connect error
error: https://www.elrepo.org/RPM-GPG-KEY-elrepo.org: import read failed(2).
[root@MidApp pgsql]# yum update nss

:前4步,两个节点做相同操作

5修改全局配置文件

[root@MidApp ~]# cat /etc/drbd.d/global_common.conf 
 
global {
usage-count no;
}
 
common {
protocol C;
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";
split-brain "/usr/lib/drbd/notify-split-brain.sh root";
}
 
startup {
# wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb
}
 
options {
# cpu-mask on-no-data-accessible
}
 
disk {
on-io-error detach; #配置I/O错误处理策略为分离
}
 
net {
after-sb-0pri discard-zero-changes;#如果任何节点都没有发生任何变化,仅仅申请在一个节点上做出继续修改即可
after-sb-1pri discard-secondary;
after-sb-2pri disconnect;
}
syncer {
        rate 1024M;    #设置主备节点同步时的网络速率
    }
}


6创建资源配置文件

[root@MidApp ~]# cat /etc/drbd.d/mysql.res 
resource mysql {
protocol C;
meta-disk internal;
device /dev/drbd1;#相关的块设备需命名为/dev/drbdm,其中m是设备的次要号码
syncer {
verify-alg sha1;#支持复制传输数据完整性验证(MD5、SHA-1、CRC-32C)
}
net {
allow-two-primaries;
}
on MidApp {
disk /dev/sdb1; #在node1创建的分区
address 192.168.221.161:7789;
}
on DB {
disk /dev/sdb1; #在node2创建的分区
address 192.168.221.160:7789;
}
}

7把配置文件拷贝到另一台机器

scp -rp  /etc/drbd.d/* DB:/etc/drbd.d/


8提前添加一块硬盘,创建分区

[root@MidApp ~]# fdisk /dev/sdb 
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xa2f4da2f.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
 
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
 
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').
 
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-261, default 1): 
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-261, default 261): 
Using default value 261
Command (m for help): p
 
Disk /dev/sdb: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xa2f4da2f
 
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         261     2096451   83  Linux
 
Command (m for help): w
The partition table has been altered!
 
Calling ioctl() to re-read partition table.
Syncing disks.
You have new mail in /var/spool/mail/root


9161机器上启动DRBD

[root@MidApp ~]# drbdadm create-md mysql
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.


10内核加载DRBD模块

[root@MidApp ~]# modprobe drbd
[root@MidApp ~]# drbdadm up mysql
[root@MidApp ~]#  lsmod | grep drbd
drbd                  374888  2 
libcrc32c               1246  1 drbd


11161机器为primary节点

[root@MidApp ~]# drbdadm -- --force primary mysql


12160机器同样操作

[root@DB ~]# drbdadm create-md mysql
[root@DB ~]# modprobe drbd
[root@DB ~]# drbdadm up mysql

 

13创建一个/mydata目录

mkdir -p /mydata

14格式化设备并挂载

[root@MidApp ~]# mkfs.ext4 /dev/drbd1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524087 blocks
26204 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
32768, 98304, 163840, 229376, 294912
 
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
 
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
You have new mail in /var/spool/mail/root
[root@MidApp ~]# mount /dev/drbd1 /mydata
[root@MidApp ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        18G   12G  4.6G  73% /
tmpfs           491M   72K  491M   1% /dev/shm
/dev/sda1       283M   59M  209M  23% /boot
/dev/drbd1      2.0G  3.0M  1.9G   1% /mydata


15查看状态

[root@MidApp ~]# drbd-overview 
 1:mysql/0  Connected Primary/Secondary UpToDate/UpToDate /mydata ext4 2.0G 3.0M 1.9G 1%

 也可以通过下面方式查看

[root@MidApp ~]# cat /proc/drbd 
version: 8.4.9-1 (api:1/proto:86-101)
GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15
 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:2162724 nr:120 dw:66496 dr:2098842 al:25 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


16写入测试数据

[root@MidApp ~]# echo "123" > /mydata/test.txt 
[root@MidApp ~]# cat /mydata/test.txt 
123


17161机器解除挂载,并降级为secondary

[root@MidApp ~]# umount /mydata
[root@MidApp ~]# drbdadm secondary mysql 
[root@MidApp ~]# drbd-overview 
 1:mysql/0  Connected Secondary/Secondary UpToDate/UpToDate

:在单主模式下的DRBD,两个节点同时处于连接状态,任何一个节点都可以在特定的时间内变成主;但两个节点中只能一为主,如果已经有一个主,需先降级才可能升级

 

18160节点升为primary节点,并挂载

[root@DB ~]# drbdadm primary mysql
[root@DB ~]# mount /dev/drbd1 /mydata/

19查看状态

[root@DB ~]# drbd-overview
 1:mysql/0  Connected Primary/Secondary UpToDate/UpToDate /mydata ext4 2.0G 3.0M 1.9G 1% 
[root@DB ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        36G   22G   12G  66% /
tmpfs           774M   72K  774M   1% /dev/shm
/dev/sda1       283M   69M  200M  26% /boot
/dev/drbd1      2.0G  3.0M  1.9G   1% /mydata


20验证数据

[root@DB ~]# cat /mydata/test.txt 
123

至此,DRBD环境搭建完成!