一 DRBD
drbd(Distributed Replicated Block Device,分布式复制块设备),实现用网络来镜像的备份整个设备(一般是存储设备)
drbd接受到数据后,把数据写到本地的磁盘中,同时再发送一份到另外一台主机,另外一台主机把数据再存入本地的磁盘内。
在整个传输的过程中,根据数据到达的地方,可以将drdb的复制模式分成3种:
协议A:异步复制协议。本地写成功后立即返回,数据放在发送buffer中,可能丢失。
协议B:内存同步(半同步)复制协议。本地写成功并将数据发送到对方后立即返回。
协议C:同步复制协议。本地和对方写成功确认后返回
drbd用在高可用集群中,为共享存储设备提供冗余,比如:为nfs,smaba,还有mysql的数据目录都可以做分布式存储来提高冗余或者高可用。
drbd的资源规则:
drbd一般情况下,只支持一主一从,这已经足够满足服务的冗余了、
主节点:可读写
从节点:只能被动接受主机传来的数据信息,不能读写,连挂载都不被允许。
drbd做为分布式复制块设备,通常都可以用哪些硬件充当呢:
1、硬盘,或者硬盘中的一个分区
2、RAID设备
3、LVM逻辑卷
drbd有两种实现方法:
1、直接将drdb打补丁进内核中
2、通过用户空间软件实现内核级别的功能(如:netfilter的实现是用用户空间iptables命令实现的)
二 配置drbd概述
DRBD 配置工具
drbdadm:高级管理工具,管理/etc/drbd.conf,向drbdsetup和drbdmeta发送指令。
drbdsetup:配置装载进kernel的DRBD模块
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-verification和usage-count。
common段则用于定义被每一个资源默认继承的参数,可以在资源定义中使用的参数都可以在common段中定义。实际应用中,common段并非必须,但建议将多个资源共享的参数定义为common段中的参数以降低配置文件的复杂度。
resource段则用于定义drbd资源,每个资源通常定义在一个单独的位于/etc/drbd.d目录中的以.res结尾的文件中。资源在定义时必须为其命名,名字可以由非空白的ASCII字符组成。每一个资源段的定义中至少要包含两个host子段,以定义此资源关联至的节点,其它参数均可以从common段或drbd的默认中进行继承而无须定义。
DRBD 资源
Resource name:可以是除了空白字符的任意的ACSII码字符
DRBD device:在双方节点上,此DRBD设备的设备文件;一般为/dev/drbdN,其主设备号147
Disk configuration:在双方节点上,各自提供的存储设备
Nerwork configuration:双方数据同步时所使用的网络属性
来说说整体是怎么配置的,给个配置步骤,就能看起来逻辑上清晰一点:
1、安装drdb
drbd-8.4.3-33.el6.x86_64 drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64
安装drbd时,要看自己的内核版本,一定要安装和自己内核一样版本的软件包。
2、配置资源文件
需要在/etc/drbd.d/global_common.conf中做修改
将自己建立的磁盘设备加入资源中,命名以 .res结尾(例如:mystore.res)
当然在配置资源的时候,你应该提前创建好设备。
3、将drbd加入到系统服务chkconfig --add drbd (如果做HA高可用,就不需要开机自动启动)
4、初始化资源组drbdadm create-md resource_name (例如:drbdadm create-md mystore)
5、启动服务 service drbd start (配置完测试,启动服务,drbd也作为一个服务运行的)
6、设置primary主机,并同步数据
默认情况运行服务后,两个节点都是处于secondary状态,我们需要手动去设置一个节点成为primary状态
在要设置为Primary的节点上执行如下命令:drbdsetup /dev/drbd0 primary –o ,也可以在要设置为Primary的节点上使用如下命令来设置主节点: drbdadm -- --overwrite-data-of-peer primary web
7、分区、格式化/dev/drbd*
8、一个节点进行挂载
9、查看状态
三 配置过程
1、安装drbd
[root@station139 ~]# lsanaconda-ks.cfg drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpmdrbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm –> 这个包安装和kernel版本不同的话会出现出现的错误:[root@node2 ~]# service drbd startStarting DRBD resources: Can not load the drbd module.[root@station139 ~]# rpm -ivh --nodeps drbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm warning: drbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 66534c2b: NOKEYPreparing... ########################################### [100%] 1:drbd-kmdl-2.6.32-358.el########################################### [100%][root@station139 ~]# rpm -ivh drbd-8.4.3-33.el6.x86_64.rpm warning: drbd-8.4.3-33.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 66534c2b: NOKEYPreparing... ########################################### [100%] 1:drbd ########################################### [100%]
[root@station139 ~]# rpm -q drbddrbd-8.4.3-33.el6.x86_64
在配置配置文件之前,我们来为我们准备实验的两台主机分别创建磁盘文件;[root@station139 ~]# fdisk /dev/sdaWARNING: 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): pDisk /dev/sda: 128.8 GB, 128849018880 bytes255 heads, 63 sectors/track, 15665 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x000902d4 Device Boot Start End Blocks Id System/dev/sda1 * 1 26 204800 83 LinuxPartition 1 does not end on cylinder boundary./dev/sda2 26 7859 62914560 8e Linux LVM/dev/sda3 7859 9164 10489446 8e Linux LVMCommand (m for help): nCommand action e extended p primary partition (1-4)e 因为只剩下一个主分区了可以建立了,所以我们把最后一个主分区用来做扩展,在扩展分区上创建分区Selected partition 4First cylinder (9165-15665, default 9165): Using defaultvalue 9165Last cylinder, +cylinders or +size{K,M,G} (9165-15665, default 15665): Using defaultvalue 15665Command (m for help): nFirst cylinder (9165-15665, default 9165): Using defaultvalue 9165Last cylinder, +cylinders or +size{K,M,G} (9165-15665, default 15665): +5GCommand (m for help): PDisk /dev/sda: 128.8 GB, 128849018880 bytes255 heads, 63 sectors/track, 15665 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x000902d4 Device Boot Start End Blocks Id System/dev/sda1 * 1 26 204800 83 LinuxPartition 1 does not end on cylinder boundary./dev/sda2 26 7859 62914560 8e Linux LVM/dev/sda3 7859 9164 10489446 8e Linux LVM/dev/sda4 9165 15665 52219282+ 5 Extended/dev/sda5 9165 9818 5253223+ 83 Linux 创建了一个5G的磁盘空间Command (m for help): WThe partition table has been altered!Calling ioctl() to re-read partition table.WARNING: Re-reading the partition table failed with error 16: Device or resource busy.The kernel still uses the old table. The new table will be used atthe next reboot or after you run partprobe(8) or kpartx(8)Syncing disks.
让系统识别我们创建的分区:
error adding partition 3[root@station139 ~]# kpartx -af /dev/sdadevice-mapper: reload ioctl on sda1 failed: Invalid argumentcreate/reload failed on sda1device-mapper: reload ioctl on sda2 failed: Invalid argumentcreate/reload failed on sda2device-mapper: reload ioctl on sda3 failed: Invalid argumentcreate/reload failed on sda3device-mapper: reload ioctl on sda4 failed: Invalid argumentcreate/reload failed on sda4device-mapper: reload ioctl on sda5 failed: Invalid argumentcreate/reload failed on sda5[root@station139 ~]# partx -a /dev/sdaBLKPG: Device or resource busyerror adding partition 1BLKPG: Device or resource busyerror adding partition 2BLKPG: Device or resource busyerror adding partition 3BLKPG: Device or resource busyerror adding partition 4BLKPG: Device or resource busyerror adding partition 5
在另外一台主机(node2)上也应该创建一个同本机大小相同的磁盘存储设备。
2、配置配置文件
[root@node1 ~]# cat /etc/drbd.d/global_common.conf global { usage-count no; #让linbit公司收集目前drbd的使用情况,yes为参加,我们这里不参加设置为no # minor-count dialog-refresh disable-ip-verification }common { 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"; 将上面这三行的注释去掉,启用他们。# 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 degr-wfc-timeout outdated-wfc-timeout wait-after-sb } options { # cpu-mask on-no-data-accessible } disk { # size max-bio-bvecs on-io-error fencing disk-barrier disk-flushes # disk-drain md-flushes resync-rate resync-after al-extents # c-plan-ahead c-delay-target c-fill-target c-max-rate # c-min-rate disk-timeout on-io-error detach; #同步错误的做法是分离 } net { # protocol timeout max-epoch-size max-buffers unplug-watermark # connect-int ping-int sndbuf-size rcvbuf-size ko-count # allow-two-primaries cram-hmac-alg shared-secret after-sb-0pri # after-sb-1pri after-sb-2pri always-asbp rr-conflict # ping-timeout data-integrity-alg tcp-cork on-congestion # congestion-fill congestion-extents csums-alg verify-alg # use-rle加入如下两行:实现节点之间会话加密,设置算法,和加密的key注意: 最后要加分号; cram-hmac-alg "sha1"; #设置加密算法sha1 shared-secret "mydrbdlab"; #设置加密key }syncer { 需要加入的内容
rate 1000M; }}
配置资源[root@station139 ~]# vim /etc/drbd.d/mystore.resresource mystore { 资源名mystore应该和配置文件定义的名字是相同的。 on node1.corosync.com{ 主机名,如果是本机的话,要和“uname –n”结果相同,hosts文件中也应该有对应的IP解析。如果是在网络中的话需要/etc/hosts文件中要有主机名和IP地址对应的解析。 device /dev/drbd0; drbd0 为drdb的第一个设备 disk /dev/sda5; 所在本地的那个磁盘,也就是磁盘位置 address 172.16.249.207:7789; 对应的IP地址和端口号 meta-disk internal; 表示资源是在本地} on node2.corosync.com{ 这个是另外一台主机,也做同样的设置 device /dev/drbd0; disk /dev/sda3; address 172.16.249.208:7789; 这个地方配置另外这台主机的IP地址和端口。drbd服务默认端口是 7789; meta-disk internal;}}
将配置文件同步到node2如上的配置文件,是两个主机中的配置应该是相同的,所以可以直接放这两个配置文件复制过去,直接放在另外一个主机的对应的配置文件目录下。[root@station139 ~]# scp /etc/drbd.d/* node2.corosync.com:/etc/drbd.d/The authenticity of host 'node2.corosync.com (172.16.249.208)' can't be established.RSA key fingerprint is c7:65:26:ff:5e:11:b9:de:a4:7a:20:9d:a2:28:e4:66.Are you sure you want to continue connecting (yes/no)? yesWarning: Permanently added 'node2.corosync.com,172.16.249.208' (RSA) to the list of known hosts.root@node2.corosync.com's password: global_common.conf 100% 1886 1.8KB/s 00:00 mystore.res 100% 247 0.2KB/s 00:00
3、将drbd加入到系统服务chkconfig --add drbd (如果做HA高可用,就不需要开机自动启动)
因为我们的目的是做高可用集群的,在做高可用集群的时候,务必要关闭开机自动启动,所以我们就不走这条常规的道路了。
4、初始化资源组drbdadm create-md resource_name (例如:drbdadm create-md mystore)
node1与node2上初始化资源node1上的初始化[root@node1 ~]# drbdadm create-md mystore 初始化资源组命令Writing meta data...initializing activity logNOT initializing bitmapNew drbd meta data block successfully created. 初始化成功node2上的初始化[root@node2 ~]# drbdadm create-md mystore --== Thank you for participating in the global usage survey ==--The server's response is:you are the 15309th user to install this versionWriting meta data...initializing activity logNOT initializing bitmapNew drbd meta data block successfully created.
5、启动服务 service drbd start (配置完测试,启动服务,drbd也作为一个服务运行的)
node1:[root@node1 ~]# rpm -ivh drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm warning: drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 66534c2b: NOKEYPreparing... ########################################### [100%] 1:drbd-kmdl-2.6.32-431.el########################################### [100%][root@node1 ~]# service drbd startStarting DRBD resources: [ create res: mystore prepare disk: mystore adjust disk: mystore adjust net: mystore]..........*************************************************************** DRBD's startup script waits for the peer node(s) to appear. - In case this node was already a degraded cluster before the reboot the timeout is 0 seconds. [degr-wfc-timeout] - If the peer was available before the reboot the timeout will expire after 0 seconds. [wfc-timeout] (These values are for resource 'mystore'; 0 sec -> wait forever) To abort waiting enter 'yes' [ 236]:
node2:[root@node2 ~]# service drbd startStarting DRBD resources: [ create res: mystore prepare disk: mystore adjust disk: mystore adjust net: mystore]查看下drbd运行状态:[root@node1 ~]# watch -n 1 `cat /proc/drbd`GIT-hash: 89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-11-29 12:28:00 0: cs:Connected ro: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 ep:1 wo:f oos:5252056' ds:Inconsistent/Inconsistent 两个都处于非一致状态ro:Secondary/Secondary 此时还不知道谁是主谁是从
6、设置primary主机,并同步数据
从上面的信息中可以看出此时两个节点均处于Secondary状态。于是,我们接下来需要将其中一个节点设置为Primary。在要设置为Primary的节点上执行如下命令:# drbdadm primary --force resource(资源名)
注: 也可以在要设置为Primary的节点上使用如下命令来设置主节点:
# drbdadm -- --overwrite-data-of-peer primary web
打算让哪个节点做为primary就在哪个节点上执行如下命令:
[root@node1 ~]# drbdadm primary --force mystore再次查看状态,可以发现数据同步过程开始了:
[root@node1 ~]# drbd-overview 0:mystore/0 SyncSource Primary/Secondary UpToDate/Inconsistent C r---n- [======>.............] sync'ed: 35.4% (3316/5128)M我们再用watch –n 1 `cat /proc/drbd`来查看下有没有认出主从:line 0: `version: 8.4.3 (api:1/proto:86-101) GIT-hash: 89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-11-29 12:28:00 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---n- ns:1427464 nr:0 dw:0 dr:1429152 al:0 bm:87 lo:3 pe:3 ua:4 ap:0 ep:1 wo:f oos:3826648 [====>...............] sync'ed: 27.3% (3736/5128)M finish: 0:02:34 speed: 24,788 (24,156) K/sec'ro:Primary/Secondary 已经有主从了ds:UpToDate/Inconsistent 而且有一方已经开始呈现更新状态
更新完成后, drbd-overview 查看:[root@node1 ~]# drbd-overview 0:mystore/0 Connected Primary/Secondary UpToDate/UpToDate C r-----显示已经分出主从,并且已经更新完了 UpToDate/UpToDate
对主Primary/Secondary模型的drbd服务来讲,在某个时刻只能有一个节点为Primary,因此,要切换两个节点的角色,只能在先将原有的Primary节点设置为Secondary后,才能原来的Secondary节点设置为Primary:
node1: drbdadm secondary mystore
node2: drbdadm primary mystore
7、分区、格式化/dev/drbd*
文件系统的挂载只能在Primary节点进行,因此,也只有在设置了主节点后才能对drbd设备进行格式化
[root@node1 ~]# mke2fs -t ext4 /dev/drbd0 格式化成ext4 对/dev/drbd0 此刻就不是对/dev/sda#了mke2fs 1.41.12 (17-May-2010)Filesystem label=OS type: LinuxBlock size=4096 (log=2)Fragment size=4096 (log=2)Stride=0 blocks, Stripe blocks328656 inodes, 1313014 blocks65650 blocks (5.00%) reserved for the super userFirst data block=0Maximum filesystem blocks=134637158441 block groups32768 blocks per group, 32768 fragments per group8016 inodes per groupSuperblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736Writing inode tables: done Creating journal (32768 blocks): doneWriting superblocks and filesystem accounting information: doneThis filesystem will be automatically checked every 39 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.
创建目录,挂载/dev/drbd0 来看看能不能能不能挂载上这个drdb[root@node1 ~]# mkdir /mydata[root@node1 ~]# mount /dev/drbd0 /mydata/[root@node1 ~]# cd /mydata/[root@node1 mydata]# lslost+found我们拷贝文件进去,并做修改,然后取消掉挂载,让本机降级成secondary,然后让另外一台主机上升成primary,来看下数据有没有同步过去node1:[root@node1 mydata]# cp /etc/fstab .[root@node1 mydata]# vim fstab 删除剩下两行、然后讲本机降级成secondary,让另外一台主机升级成primary,然后在另外一台被提升成primary的主机上查看/dev/cdrom /media/cdrom iso9660 defaults 0 0/dev/myvg/mydata /nfs ext4 defaults 0 0[root@node1 ~]# umount /dev/drbd0 卸载挂载[root@node1 ~]# drbdadm secondary mystore 降级为secondary
node2:[root@node2 ~]# drbdadm primary mystore 升级为primary[root@node2 ~]# mkdir /mydata 创建目录[root@node2 ~]# mount /dev/drbd0 /mydata/ 挂载[root@node2 ~]# cd /mydata/[root@node2 mydata]# lsfstab lost+found[root@node2 mydata]# cat fstab 可以看到文件已经变成我们改变之后的了/dev/cdrom /media/cdrom iso9660 defaults 0 0/dev/myvg/mydata /nfs ext4 defaults 0 0
本文就是实现了 drbd的工作模式
drdb有时候可能需要自动的去实现角色切换、下一篇来讲解 drbd+corosync 实现自动切换