1. drbd簡介
DRDB(Distributed Replicated Block Device)由內核模塊和相關應用層工具程序組成,主要被用於Linux平臺下的高可用(HA)方案之中,實現不同機器上數據的同步,保持數據的一致性。當本地節點的主機出現故障時,遠程節點的主機上還會保留有一份完全相同的數據,可以繼續使用,以達到高可用的目的。在高可用(HA)解決方案中使用DRBD,可以代替使用一個共享盤陣列存儲設備。因爲數據同時存在於本地主機和遠程主機上,在遇到需要切換的時候,遠程主機只需要使用它上面的那份備份數據,就可以繼續提供服務了。
如圖所示,DRBD位於文件系統的下層,他將磁盤數據的變化同步到對端機器,並不關心上層數據的類型,也不檢測上層的錯誤,例如上層的文件系統崩潰了,DRBD是檢測不到的,他同樣將數據同步到對端。
DRBD的使用手冊非常完備,網上的功能介紹也很多,本文試圖從開發者的角度,從代碼實現的層面分析DRBD的原理及依賴的相關Linux內核技術。
DRBD是一個虛擬的塊設備,實現了一個塊設備驅動程序,主設備號是147,每一個DRBD塊設備對應一個實際的物理設備,Mount磁盤分區時,使用的是DRBD設備,例如/dev/drbd0等。
與塊設備相關的內核組件是非常多的,參見圖2,要想理解DRBD的工作原理,首先需要了解Linux文件系統中一個普通的文件I/O操作的執行過程,也就是要對圖2所示的結構有一個整體的瞭解,這裏不做深入介紹,可以閱讀《Understanding The Linux Kernel》的第12、14、16章節。
通用塊層:
Generic Block Layer,通用塊層,它處理來自系統中所有塊設備發出的請求。通用塊層的核心數據結構是一個稱爲bio的描述符,他描述了塊設備的I/O操作。每個bio結構包括一個設備描述符,I/O操作的起始磁盤扇區號和扇區數目,內存段等,幾個關鍵字段如下所示:
2. 案例拓撲圖
3. 安裝並配置drbd
1) 配置兩臺linux主機的ip地址
n1.xht.com
n2.xht.com
2)設置兩臺linux主機的主機名
n1.xht.com
[root@localhost ~]# vim /etc/sysconfig/network
n2.xht.com
[root@localhost ~]# vim /etc/sysconfig/network
3) 要保證兩個節點之間可以相互解析,在兩臺節點上分別配置hosts文件
[root@n1 ~]# vim /etc/hosts
[root@n2 ~]# vim /etc/hosts
4) 爲兩個節點的磁盤進行分區,要求兩個節點上的分區大小要一樣
Command (m for help): n
First cylinder (1632-2610, default 1632):
Using default value 1632
Last cylinder or +size or +sizeM or +sizeK (1632-2610, default 2610): +1g
Command (m for help): p
Disk /dev/sda: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 65 522081 83 Linux
/dev/sda2 66 1370 10482412+ 83 Linux
/dev/sda3 1371 1631 2096482+ 82 Linux swap / Solaris
/dev/sda4 1632 2610 7863817+ 5 Extended
/dev/sda5 1632 1754 987966 83 Linux
[root@n2 ~]# fdisk /dev/sda
The number of cylinders for this disk is set to 2610.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): p
Disk /dev/sda: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 65 522081 83 Linux
/dev/sda2 66 1370 10482412+ 83 Linux
/dev/sda3 1371 1631 2096482+ 82 Linux swap / Solaris
/dev/sda4 1632 2610 7863817+ 5 Extended
/dev/sda5 1632 1754 987966 83 Linux
5)讓兩臺主機重新識別分區表
[root@n1 ~]# cat /proc/partitions
major minor #blocks name
8 0 20971520 sda
8 1 522081 sda1
8 2 10482412 sda2
8 3 2096482 sda3
8 4 0 sda4
8 5 987966 sda5
[root@n2 ~]# partprobe /dev/sda
[root@n2 ~]# cat /proc/partitions
major minor #blocks name
8 0 20971520 sda
8 1 522081 sda1
8 2 10482412 sda2
8 3 2096482 sda3
8 4 0 sda4
8 5 987966 sda5
6)上傳drbd主程序和內核模塊程序並安裝這兩個軟件
drbd83-8.3.8-1.el5.centos.i386.rpm GRBD主程序
kmod-drbd83-8.3.8-1.el5.centos.i686.rpm 內核模塊
[root@n1 ~]# rpm -ivh drbd83-8.3.8-1.el5.centos.i386.rpm
warning: drbd83-8.3.8-1.el5.centos.i386.rpm: Header V3 DSA signature: NOKEY, key ID e8562897
Preparing... ########################################### [100%]
1:drbd83 ########################################### [100%]
[root@n1 ~]# rpm -ivh kmod-drbd83-8.3.8-1.el5.centos.i686.rpm
warning: kmod-drbd83-8.3.8-1.el5.centos.i686.rpm: Header V3 DSA signature: NOKEY, key ID e8562897
Preparing... ########################################### [100%]
1:kmod-drbd83 ########################################### [100%]
[root@n2 ~]# rpm -ivh drbd83-8.3.8-1.el5.centos.i386.rpm
warning: drbd83-8.3.8-1.el5.centos.i386.rpm: Header V3 DSA signature: NOKEY, key ID e8562897
Preparing... ########################################### [100%]
1:drbd83 ########################################### [100%]
[root@n2 ~]# rpm -ivh kmod-drbd83-8.3.8-1.el5.centos.i686.rpm
warning: kmod-drbd83-8.3.8-1.el5.centos.i686.rpm: Header V3 DSA signature: NOKEY, key ID e8562897
Preparing... ########################################### [100%]
1:kmod-drbd83 ########################################### [100%]
7)查看軟件的安裝位置
[root@n1 ~]# rpm -ql drbd83
/etc/bash_completion.d/drbdadm
/etc/drbd.conf
/etc/drbd.d/global_common.conf
/etc/ha.d/resource.d/drbddisk
/etc/ha.d/resource.d/drbdupper
/etc/rc.d/init.d/drbd
/etc/udev/rules.d/65-drbd.rules
/etc/xen/scripts/block-drbd
/sbin/drbdadm
/sbin/drbdmeta
/sbin/drbdsetup
/usr/lib/drbd/crm-fence-peer.sh
8)在兩個節點上分別執行以下命令
[root@n1 ~]# modprobe drbd
[root@n1 ~]# lsmod |grep drbd
drbd 228528 0
[root@n2 ~]# modprobe drbd
[root@n2 ~]# lsmod |grep drbd
drbd 228528 0
9)在兩個節點上編輯drbd的配置文件 :/etc/grbd.conf
[root@n1 ~]# cp /usr/share/doc/drbd83-8.3.8/drbd.conf /etc/
cp:是否覆蓋“/etc/drbd.conf”? y
[root@n1 ~]# vim /etc/drbd.conf
[root@n2 ~]# cp /usr/share/doc/drbd83-8.3.8/drbd.conf /etc/
cp:是否覆蓋“/etc/drbd.conf”? y
10)在兩個節點上編輯global_common.conf文件,編輯之前最好做備份
[root@n1 ~]# cd /etc/drbd.d/
[root@n1 drbd.d]# cp -p global_common.conf global_common.conf.bak
[root@n2 ~]# cd /etc/drbd.d/
[root@n2 drbd.d]# cp -p global_common.conf global_common.conf.bak
[root@n1 drbd.d]# vim global_common.conf
global {
usage-count no; 不統計用法計數(影響性能)
# minor-count dialog-refresh disable-ip-verification
}
common {
protocol C; 使用C類協議當存儲到對方的磁盤後纔算結束
handlers {
# 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 120;
degr-wfc-timeout 120;
}
disk {
on-io-error detach; 當io出錯時拆除磁盤
fencing resource-only;
}
net {
cram-hmac-alg "sha1";通訊時使用sha1加密
shared-secret "xht"; 預共享密鑰,雙方應相同
}
syncer {
rate 100M; 同步時的速率
}
}
在n2.xht.com上做同樣的配置
11)在兩個節點上分別編輯資源文件,文件名可隨便寫,但是不能有空格
[root@n1 drbd.d]# vim wweb.res
resource wweb { 資源名
on n1.xht.com { n1.xht.com的資源
device /dev/drbd0; 邏輯設備名,在/dev/下
disk /dev/sda5; 真實設備名,節點間共享的磁盤或分區
address 192.168.10.1:7789; 節點1的ip地址
meta-disk internal; 磁盤類型
}
on n2.xht.com { n2.xht.com的資源
device /dev/drbd0;
disk /dev/sda5;
address 192.168.10.2:7789;
meta-disk internal;
}
在n2.xht.com上作同樣的配置
12)在兩個節點上初始化資源wweb
[root@n1 drbd.d]# drbdadm create-md wweb
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
[root@n2 drbd.d]# drbdadm create-md wweb
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
13) 在兩個節點上啓動drbd服務
[root@n1 drbd.d]# service drbd start
[root@n2 drbd.d]# service drbd start
14) 查看當前哪臺設備室激活設備
[root@n1 drbd.d]# cat /proc/drbd
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by [email protected], 2010-06-04 08:04:16
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:b oos:987896
當前設備的角色/對方的角色 ,可知當前兩臺設備都未激活,都無權限讀取磁盤
或是使用命令drbd-overview 查看當前設備狀態
[root@n1 drbd.d]# drbd-overview
0:wweb Connected Secondary/Secondary Inconsistent/Inconsistent C r----
15) 在節點1上執行命令,將當前設備成爲主設備
[root@n1 drbd.d]# drbdadm -- --overwrite-data-of-peer primary wweb
[root@n1 drbd.d]# drbd-overview
0:wweb Connected Primary/Secondary UpToDate/UpToDate C r----
16 ) 在節點1上格式化主設備的磁盤
[root@n1 drbd.d]# mkfs -t ext3 /dev/drbd0
17 ) 在節點1上新建掛載點,將/dev/drbd0掛載到上面
[root@n1 drbd.d]# mkdir /mnt/wweb
[root@n1 drbd.d]# mount /dev/drbd0 /mnt/wweb
[root@n1 drbd.d]# cd /mnt/wweb
[root@n1 wweb]# ll
總計 16
drwx------ 2 root root 16384 09-11 16:52 lost+found
產生網頁文件index.html
[root@n1 wweb]# vim index.html
18 ) 將n1變爲備份設備,n2 變爲主設備,在n1上執行命令
[root@n1 ~]# umount /mnt/wweb
[root@n1 ~]# drbdadm secondary wweb
查看當前設備node1的狀態,顯示:兩個節點都爲備份節點
[root@n1 ~]# drbdadm role wweb
Secondary/Secondary
在節點2上,將當前設備設置爲主設備
[root@n2 drbd.d]# drbdadm primary wweb
[root@n2 drbd.d]# drbdadm role wweb
Primary/Secondary
19 ) 在節點2上格式化/dev/drbd0
[root@n2 drbd.d]# mkfs -t ext3 /dev/drbd0
20 ) 節點2上創建掛載點,將/dev/drbd0 掛載上
[root@n2 drbd.d]# mkdir /mnt/wweb
[root@n2 drbd.d]# mount /dev/drbd0 /mnt/wweb
[root@n2 drbd.d]# cd /mnt/wweb
此時先前的index文件丟失
21) 在n2上/mnt/wweb下創建index.html文件
[root@n2 wweb]# echo "hello n2">index.html
[root@n2 ~]# umount /mnt/wweb
[root@n2 ~]# drbdadm secondary wweb
22)重新設置n1爲主
[root@n1 ~]# drbdadm primary wweb
[root@n1 ~]# drbdadm role wweb
Primary/Secondary
23)掛載/dev/drbd0
[root@n1 ~]# mount /dev/drbd0 /mnt/wweb
[root@n1 ~]# cd /mnt/wweb
[root@n1 wweb]# ll
總計 24
-rw-r--r-- 1 root root 9 09-11 17:08 index.html
drwx------ 2 root root 16384 09-11 17:02 lost+found
此時數據已經同步
23)在以上試驗中我們知道,只有手動將一個節點設置爲主節點時,纔可訪問該節點下的內容,顯然不符合智能化的要求,可以使用heartbeat工具,將drbd作爲其資源,實現主節點和 備份節點的自動切換。在兩個節點上都安裝nfs服務,將分區共享出來,這樣客戶端就可以看到這些內容。
4. 配置nfs
1)在兩個節點上新建掛載點,掛載光盤
[root@n1 ~]# mkdir /mnt/cdrom
[root@n1 ~]# mount /dev/cdrom /mnt/cdrom
[root@n2 ~]# mkdir /mnt/cdrom
[root@n2 ~]# mount /dev/cdrom /mnt/cdrom
2) 在兩個節點上編輯nfs的共享清單
[root@n1 ~]# vim /etc/exports
/mnt/wweb 192.168.10.0/24(rw,sync)
[root@n2 ~]# vim /etc/exports
/mnt/wweb 192.168.10.0/24(rw,sync)
3) 在兩個節點上導出共享清單
[root@n1 ~]# exportfs –rv
[root@n2 ~]# exportfs –rv
4) 在兩個節點上修改nfs的啓動腳本文件
[root@n1 ~]# vim /etc/init.d/nfs
5 . 安裝配置heartbeat
1) 需要的軟件包如下,
heartbeat-2.1.4-9.el5.i386.rpm
heartbeat-devel-2.1.4-9.el5.i386.rpm
heartbeat-gui-2.1.4-9.el5.i386.rpm
heartbeat-pils-2.1.4-10.el5.i386.rpm
heartbeat-stonith-2.1.4-10.el5.i386.rpm
libnet-1.1.4-3.el5.i386.rpm
perl-MailTools-1.77-1.el5.noarch.rpm
2) 並在兩個節點上配置yum
# vim /etc/yum.repos.d/rhel-debuginfo.repo
3) 在兩個節點上安裝heartbeat
# yum localinstall heartbeat-2.1.4-9.el5.i386.rpm heartbeat-pils-2.1.4-10.el5.i386.rpm heartbeat-stonith-2.1.4-10.el5.i386.rpm libnet-1.1.4-3.el5.i386.rpm perl-MailTools-1.77-1.el5.noarch.rpm –nogpgcheck
4) 在兩個節點上配置heartbeat
將/usr/share/doc/heartbeat-2.1.4下的文件複製到/etc/ha.d下
# cd /usr/share/doc/heartbeat-2.1.4/
# cp authkeys ha.cf haresources /etc/ha.d/
切換至/etc/ha.d/
編輯ha.cf文件,定義心跳參數
bcast eth0 # Linux 在eth0上監測心跳
node n1.xht.com
node n2.xht.com
編輯authkeys驗證文件,進行節點之間的驗證
# vim authkeys
auth 3
3 md5 xht
5) 手工創建文件:
#vim /etc/ha.d/resource.d/killnfsd
killall -9 nfsd;
/etc/init.d/nfs restart;
exit 0
6) 修改權限
# chmod 600 authkeys (不能少)
# chmod 755 resource.d/killnfsd
7) 編輯資源文件,兩個節點配置一樣
n1.xht.com IPaddr::192.168.10.3/24/eth0 drbddisk::wweb Filesystem::/dev/drbd0::/mnt/wweb::ext3 killnfsd
8) 在兩個節點上啓動heartbeat服務
# service heartbeat start
9) 查看是哪個節點獲得了虛擬ip
節點1上:
[root@n1 ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:70:3F:F7
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe70:3ff7/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:575 errors:0 dropped:0 overruns:0 frame:0
TX packets:642 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:120878 (118.0 KiB) TX bytes:130368 (127.3 KiB)
Interrupt:67 Base address:0x2000
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:70:3F:F7
inet addr:192.168.10.3 Bcast:192.168.10.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:67 Base address:0x2000
當前設備爲主節點
[root@n1 ~]# drbd-overview
0:wweb Connected Primary/Secondary UpToDate/UpToDate C r---- /mnt/wweb ext3 950M 18M 885M 2%
6. 測試
1)在客戶端n2.xh.com上新建掛載點,進行掛載
[root@n2 ~]# mkdir /mnt/nfs
[root@n2 ~]# mount 192.168.10.3:/mnt/wweb /mnt/nfs
[root@n2 ~]# cd /mnt/nfs
[root@n2 nfs]# ll
總計 24
-rw-r--r-- 1 root root 9 09-11 17:08 index.html
drwx------ 2 root root 16384 09-11 17:02 lost+found
2) 把n1.xht.com的heartbeat服務停止
可以看到資源立刻轉移到n2.xht.com
3)n1.xht.com的服務啓動資源又被搶佔過來
4) #vim /mnt/nfs/test.sh
//此配置腳本文件的主要作用是爲了反覆的讀寫操作
#!bash
while true
do
echo --\<;trying touch x:`date`
touch x
echo \<-----done touch x:`date`
echo
sleep 2
done
把此腳本移動到root的家目錄下
[root@n2 nfs]# mv test.sh /root
切換到掛載點下執行該腳本
測試完畢!