Sibilia octopress blog

notes on memory.

Репликация дисков по сети с помощью DRBD

| Comments

В этой статье я рассмотрю установку и настройку распределённой файловой системы с использованием DRBD. Данное решение может применяться для ряда задач в кластерах высокой доступности (High Availability). Для начала, разъясним понятие DRBD: DRBD

DRBD (от англ. Distributed Replicated Block Device — «Распределённое Копируемое Блочное Устройство») — это блочное устройство, обеспечивающее синхронизацию (RAID1) между локальным блочным устройством и удалённым.

Подготовка

Эта статья будет продолжением предыдущей статьи, однако это не является полностью обязательным требованием. В частности, перед началом установки из предыдущей статьи нужен раздел “Подготовка”. Так же я буду использовать из предыдущей статьи имена нод и их ip адреса.

Так же нам потребуется дополнительно два диска (или раздела), по одному на ноду, на которых мы и будем собирать DRBD. Подготовьте их самостоятельно. У меня в статье они будут фигурировать под именами /dev/sdb.

Установка

Если посмотреть на сайте разрабтчиков, то там есть несколько активных версий drbd. Основные стабильные сейчас - 8.3.x и 8.4.x. Ситуация с пакетами rpm немного сложная. Я начну с рецепта сборки из исходников, а потом приведу способ загрузки собранных пакетов на “elrepo” и выложу свою сборку.

Сборка из исходников

Итак приступим. Я остановился на версии 8.4.х. Сборку рекомендую проводить на отдельной ноде, чтоб не засорять основные сервера. Подготавливаем инструменты для сборки и окружение:

1
2
yum install gcc rpm-build make flex kernel kernel-headers kernel-devel
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

Загружаем исходники и собираем:

1
2
3
4
5
6
7
cd /usr/src/
wget http://oss.linbit.com/drbd/8.4/drbd-8.4.3.tar.gz
tar -xzf drbd-8.4.3.tar.gz
cd drbd-8.4.3/
./configure --with-km
make rpm
KDIR=/usr/src/kernels/2.6.32-358.11.1.el6.x86_64/ make km-rpm

Здесь основной момент в том, что мы собираем не только сам drbd на и его модуль для ядра. Если всё отлично, то после последней команды мы увидим примерно это:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
+ exit 0
You have now:
/root/rpmbuild/RPMS/x86_64/drbd-udev-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-km-2.6.32_358.11.1.el6.x86_64-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-xen-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-heartbeat-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-debuginfo-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-km-debuginfo-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-utils-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-pacemaker-8.4.3-2.el6.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/drbd-bash-completion-8.4.3-2.el6.x86_64.rpm

Теперь можно приступать непосредственно к установке этих пакетов. Пакеты содержащие в имени debuginfo не обязательны к установке.

1
yum install /root/rpmbuild/RPMS/x86_64/drbd-*.rpm

Все собранные пакеты я любезно упаковал в этот архив.

Установка из репозитория “elrepo”

Тут сложного ничего нет, подключаем репозиторий, и ставим.

1
2
rpm -Uvh http://elrepo.org/elrepo-release-6-5.el6.elrepo.noarch.rpm
yum install --enablerepo=elrepo drbd84-utils kmod-drbd84

Однако, стоит заметить что в этом репозитории отсутствуют некоторые пакеты. В частности полезным является drbd-pacemaker, который устанавливает фирменные ресурс агенты от linbit для pacemaker.

Я использовал способ сборки из исходников. Учитывайте этот момент в дальнейшем, если вы ставили из “elrepo”

Теперь можно приступать к настройке.

Настройка

Начнём с глобального конфигурационного файла /etc/drbd.d/global_common.conf. В нём прописываются параметры общие для всех ресурсов. Приведу пример (за подробнастями как обычно в man drbd.conf):

1
2
3
4
5
6
7
8
9
10
11
global {
}
common {
  net {
      protocol C;

      after-sb-0pri discard-younger-primary;
      after-sb-1pri discard-secondary;
      after-sb-2pri disconnect;
  }
}

Здесь параметр protocol C обозначает что операция записи считается завершённой, когда и локальный, и сетевой диски сообщают об успешном завершении записи. А параметры начинающиеся на after-sb определяют действия при Split brain, полезно для автоматического восстановления при мелких неполадках.

Теперь приступим к созданию конфигурационного файла ресурса drbd. В нём прописывается имя ресурса, устройство, и сетевой адрес. Конфигурационные файлы ресурсов хранятся в /etc/drbd.d/.res

Вот к примеру мой /etc/drbd.d/r0.res:

1
2
3
4
5
6
7
8
9
10
11
12
13
resource r0 {
  volume 0 {
    device    /dev/drbd1;
    disk      /dev/sdb;
    meta-disk internal;
  }
  on node1 {
    address   10.10.0.210:7789;
  }
  on node2 {
    address   10.10.0.211:7789;
  }
}

Здесь device /dev/drbd1 это устрйство drbd которое автоматически создастся. В дальнейшем с ним и будем работаем.

При создании нового ресурса, первым шагом необходимо создать метаданные для диска. Выполняем на node1 и node2:

1
2
3
4
5
6
# drbdadm create-md r0
Writing meta data...
initializing activity log
NOT initializing bitmap
New drbd meta data block successfully created.
success

Теперь подгружаем модуль для ядра и поднимаем наш ресурс:

1
2
modprobe drbd
drbdadm up r0

Теперь проверяем состояние диска drbd. Это можно делать двумя способами: drbd-overview и cat /proc/drbd. Разница лишь в том, что второй способ более информативный.

1
2
3
# cat /proc/drbd 
 1: 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:1048508

ds:Inconsistent/Inconsistent - это состояние синхрнизации. На данном этапе это нормальное состояние, просто drbd не разобрался ещё кто главный. Поможем ему, выполняем на любой ноде (к примеру на node1) и смотрим сново состояние:

1
2
3
4
5
6
7
8
9
10
# drbdadm primary --force r0
# cat /proc/drbd 
 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:680960 nr:0 dw:0 dr:681624 al:0 bm:41 lo:0 pe:3 ua:0 ap:0 ep:1 wo:f oos:370620
        [===========>........] sync'ed: 64.9% (370620/1048508)K
        finish: 0:00:03 speed: 96,840 (96,840) K/sec

# cat /proc/drbd 
 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:1048508 nr:0 dw:0 dr:1049172 al:0 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

Устройство drbd готово к использованию.

У DRBD есть два режима работы: Active-Pacive и Active-Active. Рассмотрим оба.

Режим Active-Pacive

Начнём с примера настройки режима Active-Pacive, как более простого. В нём одна нода доступна для чтения и записи, а вторая недоступна вовсе, однако она постоянно синхронизируется на блочном уровне. Так как доступна только одна, то нет необходимости использовать кластерные файловые системы (об этом ниже). Мы будем использовать ext4.

Создаём точку монтирования, файловую систему, монтируем (выполняем на ноде которая в данный момент primary):

1
2
3
mkdir /mnt/data
mkfs.ext4 /dev/drbd1
mount /dev/drbd1 /mnt/data/

Приступим к интеграции drbd с нашим кластером pacemaker.

Перед добавлением drbd в конфигурацию pacemaker, останавливаем ресурс drbd:

1
2
umount /mnt/data
drbdadm down r0

Добавляем ресурс для drbd в pacemaker (не забываем запустить кластер перед этим, если он был остановлен):

1
2
3
# crm
crm(live)# configure
crm(live)configure# edit

Приведу лишь часть конфигурации которую добавляем для drbd:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
primitive drbd_data ocf:linbit:drbd \
        params drbd_resource="r0"
primitive fs-data ocf:heartbeat:Filesystem \
        params device="/dev/drbd1" directory="/mnt/data" fstype="ext4" \
        meta target-role="Started"
ms ms_drbd_data drbd_data \
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
location fs-data_on_node1 fs-data 1000: node1
location fs-data_on_node2 fs-data 1000: node2
location ms_drbd_data_on_node1 ms_drbd_data 1000: node1
location ms_drbd_data_on_node2 ms_drbd_data 1000: node2
colocation drbd_fs-data inf: ms_drbd_data:Master fs-data
order fs-data_after_drbd inf: ms_drbd_data:promote fs-data:start
...

ms используется для Master/Slave ресурсов. Ещё обязательно прописываем order для очерёдности запуска и colocation для обозначения что файловая система подниматся там где у нас Primary drbd.

Теперь применяем конфигурацию и смотрим состояние кластера:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
crm(live)configure# commit
# crm_mon -fnr
Node node1: online
        fs-data (ocf::heartbeat:Filesystem):    Started
        nginx1  (ocf::heartbeat:nginx): Started
        ipaddr_215      (ocf::heartbeat:IPaddr2):       Started
        lsyncd:1        (ocf::heartbeat:lsyncd):        Started
        drbd_data:1     (ocf::linbit:drbd):     Master
Node node2: online
        nginx2  (ocf::heartbeat:nginx): Started
        lsyncd:0        (ocf::heartbeat:lsyncd):        Started
        ipaddr_216      (ocf::heartbeat:IPaddr2):       Started
        drbd_data:0     (ocf::linbit:drbd):     Started

Inactive resources:

Migration summary:
* Node node2: 
* Node node1: 

Всё отлично. На этом настройка drbd в режиме Active-Pacive закончена.

Режим Active-Active

Тут всё немного усложняется тем, что нам уже нужно использовать кластерные файловые системы. Я приведу пример настройки GFS2.

Для начала нужно изменить конфигурацию drbd, разрешив режим active-active. Привожу изменённый файл /etc/drbd.d/global_common.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
global {
}
common {
    net {
        protocol C;
      
      allow-two-primaries;
      
        after-sb-0pri discard-younger-primary;
        after-sb-1pri discard-secondary;
        after-sb-2pri disconnect;
    }
}

Устанавливаем необходимые пакеты для gfs2:

1
yum install gfs2-utils gfs2-cluster

Так же для gfs2 нужен cman, но он у нас установлен ещё в предыдущей статье, как и настроена его конфигурация /etc/cluster/cluster.conf.

Создаём файловую систему gfs2 на диске drbd (на той ноде, что primary):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# mkfs.gfs2 -p lock_dlm -j 2 -t my_cluster:data /dev/drbd1
This will destroy any data on /dev/drbd1.
It appears to contain: Linux rev 1.0 ext4 filesystem data (extents) (large files) (huge files)

Are you sure you want to proceed? [y/n] y

Device:                    /dev/drbd1
Blocksize:                 4096
Device Size                1.00 GB (262127 blocks)
Filesystem Size:           1.00 GB (262125 blocks)
Journals:                  2
Resource Groups:           4
Locking Protocol:          "lock_dlm"
Lock Table:                "my_cluster:data"
UUID:                      78a43254-2c97-1116-5328-3a313ff433f3

По поводу параметров: -j 2 указывает что создавать надо два журнала, -t my_cluster:data указываем имя кластера (он прописан в /etc/cluster/cluster.conf) и имя таблицы блокировок. Отлично, файловая система готова. Останавливаем drbd и правим конфигурацию кластера (опять же привожу лишь часть для drbd):

1
2
3
4
drbdadm down r0
crm
crm(live)# configure 
crm(live)configure# edit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
primitive drbd_data ocf:linbit:drbd \
        params drbd_resource="r0"
primitive fs-data ocf:heartbeat:Filesystem \
        params device="/dev/drbd1" directory="/mnt/data" fstype="gfs2" \
        meta target-role="Started"
ms ms_drbd_data drbd_data \
        meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
clone fs-data_clone fs-data \
        params clone-max="2" clone-node-max="1"
location fs-data_on_node1 fs-data_clone 1000: node1
location fs-data_on_node2 fs-data_clone 1000: node2
location ms_drbd_data_on_node1 ms_drbd_data 1000: node1
location ms_drbd_data_on_node2 ms_drbd_data 1000: node2
colocation drbd_fs-data inf: ms_drbd_data:Master fs-data_clone
order fs-data_after_drbd inf: ms_drbd_data:promote fs-data_clone:start
...

Отличия от active-slave в том, что мы указываем master-max=”2” и само собой fstype=”gfs2”. Так же я добавил clone для fs-data.

Чтож, посмотрим что у нас вышло:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# crm_mon -1
...
Online: [ node1 node2 ]

 ipaddr_215     (ocf::heartbeat:IPaddr2):       Started node1 
 ipaddr_216     (ocf::heartbeat:IPaddr2):       Started node2 
 nginx1 (ocf::heartbeat:nginx): Started node1 
 nginx2 (ocf::heartbeat:nginx): Started node2 
 Clone Set: lsyncd-cl [lsyncd]
     Started: [ node1 node2 ]
 Master/Slave Set: ms_drbd_data [drbd_data]
     Masters: [ node1 node2 ]
 Clone Set: fs-data_clone [fs-data]
     Started: [ node1 node2 ]

# drbd-overview 
  1:r0/0  Connected Primary/Primary UpToDate/UpToDate C r----- /mnt/data gfs2 1.0G 259M 766M 26% 

Вот в принципе и всё. По поводу решения некоторых проблем с drbd я делал заметку тут.

Comments