Skip to content

By Тодор in Linux

За да сме сигурни, че няма да загубим някаква информация обикновено я архивираме, нали? Веднъж месечно, веднъж седмично, веднъж дневно? Ами ако ни е необходимо по-често архивиране, на ресурс, който постоянно се актуализира, като база данни например? Някои сървъри за бази данни (като mysql) осигуряват собствено репликиране върху отдалечен сървър.

Нещо по-добро е репликирането на цяла файлова система на блоково ниво. Всяка една промяна върху диска се репликира моментално каквато и да е тя – и то без софтуерът, който ползва тази файлова система да разбере.

Удобен начин да се направи това в линукс е чрез DRBD. Тъй като репликацията е на много ниско ниво, не можем да репликираме отделни директории или файлове – работим с цели дискове или дялове (партишъни). Тъй като не всеки разполага със свободен диск/дял, който да ползва за репликацията, ще дам пример с “изкуствен” диск, създаден във файл върху текущата файлова система (loopback image). Т.е. правим един файл с размер 1GB, присъединяваме го като виртуален локален диск, правим му файлова система по желание и вече е в бизнеса 😉

Създаваме файл с размер 1GB (на двата сървъра между, които ще репликираме):
# dd if=/dev/zero of=/root/disk.img bs=1M count=1024

Сега да го прилепим към локално устройство /dev/loop0:
# losetup /dev/loop0 /root/disk.img

Това до тук ще работи, но докато не рестартираме машината. За тази цел правим един init-скрипт, който да върши тази работа при стартиране на операционната система:

#!/bin/bash
# lofsd:         Loopback filesystem
#
# chkconfig:    - 10 80
# description:  Creates loopback device
DRBD_SRC="/root/disk.img"
DRBD_DEVICE="/dev/loop0"
LOSETUP_CMD="/sbin/losetup"
RETVAL=0
start() {
        echo "Connecting loop devices $DRBD_DEVICE"
        $LOSETUP_CMD $DRBD_DEVICE $DRBD_SRC
        RETVAL=$?
        return $RETVAL
}
stop() {
        echo "Releasing loop devices $DRBD_DEVICE"
        $LOSETUP_CMD -d $DRBD_DEVICE
        RETVAL=$?
        return $RETVAL
}
restart() {
    stop
    sleep 1
    start
}
case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
        *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac
exit $?
exit $RETVAL

Записваме го под името /etc/init.d/lofsd. След това го правим изпълним:
# chkmod +x /etc/init.d/lofsd

Регистрираме скрипта като системна услуга и го активираме:

# chkconfig --add lofsd
# chkconfig lofsd on

До тук вече имаме един локален виртуален диск на /dev/loop0 и нищо повече. Сега е ред да инсталираме и самото DRBD:
# yum -y install drbd kmod-drbd

Конфигурационният му файл /etc/drbd.conf, е съвсем празен веднага след инсталацията, но има много добре коментиран примерен такъв в /usr/share/doc/drbd. Набързо спретвам следната конфигурация, която изглежда сложна само на пръв поглед (еднаква е и за двата сървъра):

global { usage-count no; }
resource repdata {
    protocol C;
    startup { wfc-timeout 0; degr-wfc-timeout     120; }
    disk { on-io-error detach; }
    net {  cram-hmac-alg "sha1"; shared-secret "ie74t6384"; }
    syncer { rate 10M; }
    on n1.kamenitza.org {
        device /dev/drbd0;
        disk /dev/loop0;
        address 10.0.0.1:7788;
        meta-disk internal;
    }
    on n2.kamenitza.org {
        device /dev/drbd0;
        disk /dev/loop0;
        address 10.0.0.2:7788;
        meta-disk internal;
    }
}

Няма да коментирам кой ред какво върши – вероятно само очевидните неща като, пътища до устройства и адреси ще трябва да редактирате – останалото е почти универсално. Все пак, ако се интересувате – разгледайте примерният drbd.conf, който е изключително добре коментиран. Когато приключите с конфигурацията – копирайте я и на вторият сървър.

Време е да инициализираме мета-данните (и на двата сървъра):

# drbdadm create-md repdata
v08 Magic number not found
v07 Magic number not found
v07 Magic number not found
v08 Magic number not found
Writing meta data...
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.

Сигурно веднага ще опитате да стартирате услугата, но може да ударите стена:

# /etc/init.d/drbd start
Restarting all DRBD resourcesNo response from the DRBD driver! Is the module loaded?
Command '/sbin/drbdsetup /dev/drbd0 down' terminated with exit code 20
command exited with code 20
ERROR: Module drbd does not exist in /proc/modules

Ами това помага :):
# modprobe drbd

След като сте стартирали сървиса (и на двата сървъра), можете да наблюдавате статуса на дисковия ресурс ето така:

# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-x8664-build, 2008-10-03            11:30:17
 0: 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 oos:1048508

Ако някой забелязва – и двете копия са вторични (secondary). Такива ще си останат, докато ние не изберем, кой да е водещият сървър и в неговия шел пуснем ето това:
# drbdadm -- --overwrite-data-of-peer primary repdata

Я да видим статуса:

# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-x8664-build, 2008-10-03            11:30:17
 0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---
    ns:16932 nr:0 dw:0 dr:19168 al:0 bm:1 lo:0 pe:4 ua:70 ap:0 oos:1031676
        [>....................] sync'ed:  2.0% (1031676/1048508)K
        finish: 0:00:59 speed: 16,832 (16,832) K/sec

Сякаш работи и вече тече репликация, а? 🙂
Остана да направим една файлова система на DRBD диска:
# mkfs -t ext3 /dev/drbd0

И да го монтираме (създайте директорията /mnt/disk и на двата сървъра, но го монтирайте само на първия):
mount /dev/drbd0 /mnt/disk

След приключване на репликацията, нещата изглеждат горе долу така:

# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-x8664-build, 2008-10-03 11:30:17
 0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---
    ns:56 nr:1412 dw:1468 dr:21 al:2 bm:3 lo:0 pe:0 ua:0 ap:0 oos:0

Ами можем вече да го изпробваме. Копирайте някакви файлове на диска преди това.
Ръчно размонтираме и правим вторичен първият сървър (n1):
# umount /mnt/disk ; drbdadm secondary repdata

Сега отиваме на втория (n2) и правим следното:
# drbdadm primary repdata ; mount /dev/drbd0 /mnt/disk

И трябва да виждаме същите файлове, които преди това копирахме от сървър n1.

За да си улесним живота в бъдеще можем да редактираме и /etc/fstab, който до момента изглежда горе-долу така:

LABEL=/                 /                       ext3    defaults        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
LABEL=SWAP-sda2         swap                    swap    defaults        0 0

Добавяме следният ред най-долу:

/dev/drbd0              /mnt/disk               ext3    noauto          0 0

Така, че файлът да придобие този вид:

LABEL=/                 /                       ext3    defaults        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
LABEL=SWAP-sda2         swap                    swap    defaults        0 0
/dev/drbd0              /mnt/disk               ext3    noauto          0 0

Цялата тази глезотия става изключително полезна, когато се съвмести с Heartbeat. Тогава в /etc/ha.d/haresources добавяме следният ред:

n1.kamenitza.org   drbddisk::repdata Filesystem::/dev/drbd0::/mnt/disk::ext3::rw

Ще се радвам, ако някой успее да приложи това някъде и сподели коментари 😉

Tags: , , , , ,

Comment Feed

No Responses (yet)



Some HTML is OK

or, reply to this post via trackback.