Установите и настройте DRDB для репликации сетевой файловой системы в Debian 8.
На этой странице
- Предпосылки
- Установка DRBD
- Первичная/дополнительная конфигурация — аварийное восстановление
Давайте поговорим о репликации сетевой файловой системы.
Репликация сетевой файловой системы сегодня часто используется во многих сценариях:
- Репликация файловой системы из соображений безопасности: в случае сбоя одного узла другой узел становится доступным.
- Для репликации файловой системы в штаб-квартиру другой компании, чтобы каждый сотрудник имел доступ к своим данным локально, а не через общедоступную сеть. Но если он идет в другой штаб, у него есть все его данные, и он снова может получить доступ локально.
Как вы можете себе представить, такая система часто используется для создания файловых систем для кластерной среды.
Мы решили реализовать решение с помощью DRDB. Его основной задачей является (как и другие подобные системы) высокая доступность и аварийное восстановление для файловых систем.
Мы реализуем решение с Debian 8, но оно должно работать и на Ubuntu.
Предпосылки
Прежде чем мы начнем, вот предварительные условия:
- Не менее 2 серверов Debian.
- Debian устанавливается как минимальная установка (вовсе необязательно, если вы знаете, что делаете в производственных системах). Рекомендуемое руководство https://linux-console.net/tutorial/debian-8-jessie-minimal-server/
- Не менее 2 дисков Linux на каждом сервере: /dev/sda для установки Linux, /dev/sdb для установки DRDB.
ВНИМАНИЕ!!!: При установке все данные на диске /dev/sdb будут уничтожены, поэтому не работайте с диском с данными внутри.
Установка ДРБД
В нашем примере я буду использовать два узла, а именно:
- 192.168.152.100 mysql1.local.vm
- 192.168.152.110 mysql2.local.vm
На всех узлах измените файл /etc/hosts следующим образом:
127.0.0.1 localhost
192.168.152.100 mysql1.local.vm mysql1
192.168.152.110 mysql2.local.vm mysql2
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Затем выполните следующие команды для установки DRDB:
apt-get update
apt-get -y upgrade
apt-get install drbd-utils
Первичная/вторичная конфигурация — аварийное восстановление
Основной файл конфигурации — /etc/drbd.conf, который выглядит следующим образом:
include "drbd.d/global_common.conf";
include "drbd.d/*.res";
По соглашению /etc/drbd.d/global_common.conf
содержит глобальные и общие разделы конфигурации DRBD, тогда как файлы .res
содержат по одному ресурсу в каждом разделе.
В нашем примере мы выполняем минимальную настройку, которая реплицирует данные на двух узлах. На каждом узле выполните следующую модификацию:
Начнем редактировать файл /etc/drbd.d/global_common.conf, изменив строку по умолчанию из
global {
usage-count yes;
# minor-count dialog-refresh disable-ip-verification
}
...
net {
protocol C;
# 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
}
...
Теперь создайте файл конфигурации /etc/drbd.d/r0.res для нашего ресурса. Создайте файл на всех узлах и добавьте это внутрь:
resource r0 { on mysql1.local.vm { device /dev/drbd1; disk /dev/sdb; address 192.168.152.100:7789; meta-disk internal; } on mysql2.local.vm { device /dev/drbd1; disk /dev/sdb; address 192.168.152.110:7789; meta-disk internal; } }
Что мы сделали до сих пор, так это следующее:
- Вы \согласились\ на то, чтобы вас включили в статистику использования DRBD с параметром usage-count.
- Ресурсы настроены на использование полностью синхронной репликации с протоколом Cunless, явно указанным в противном случае.
- Наш кластер состоит из двух узлов: mysql1 и mysql2.
- У нас есть ресурс с произвольным названием
r0
, который использует/dev/sdb
в качестве устройства нижнего уровня и настроен с внутренние метаданные. - Ресурс использует TCP-порт 7789 для сетевых подключений и привязывается к IP-адресам 192.168.152.100 и 192.168.152.110 соответственно.
На всех узлах инициализируйте метаданные с помощью следующей команды:
drbdadm create-md r0
Вы должны увидеть что-то вроде этого:
--== Thank you for participating in the global usage survey ==--
The server's response is:
you are the 2963th user to install this version
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.
success
Затем мы включаем ресурс и инициализируем первый запуск репликации, только на первом узле, он должен начать репликацию:
drbdadm up r0
drbdadm primary --force r0
Чтобы убедиться, что все работает хорошо, вы можете проверить файл /proc/drbd на обоих узлах, и вы должны увидеть что-то вроде этого:
Mysql1
:# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
ns:54624 nr:0 dw:0 dr:55536 al:0 bm:3 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:5188060
[>....................] sync'ed: 1.1% (5064/5116)Mfinish: 0:17:21 speed: 4,964 (4,964) K/sec
Mysql2
:# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
ns:0 nr:17496 dw:17496 dr:0 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:5225188
[>....................] sync'ed: 0.4% (5100/5116)Mfinish: 0:29:41 speed: 2,916 (2,916) want: 5,160 K/sec
На этапе сборки вы можете заметить UpToDate/Inconsistent, это правильно, поскольку это первая синхронизация данных.
После синхронизации файловой системы этот shloud изменится на UpToDate/UpToDate, как показано в следующем журнале:
:/home/sysop# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:5242684 nr:0 dw:0 dr:5243596 al:0 bm:320 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
Теперь у нас есть новое блочное устройство с именем /dev/drbd1, которое мы можем отформатировать с использованием предпочитаемого нами типа файловой системы. Например, если мы хотим отформатировать его в ext4 и смонтировать в /var/www, мы можем просто сделать:
:/home/sysop# mkfs.ext4 /dev/drbd1
mke2fs 1.42.12 (29-Aug-2014)
Creazione del file system con 1310671 4k blocchi e 327680 inode
Etichetta del file system=ab3e18c9-e8cb-42c8-977a-ab79bdb18aea
Backup del superblocco salvati nei blocchi:
32768, 98304, 163840, 229376, 294912, 819200, 884736
Allocating group tables: fatto
Scrittura delle tavole degli inode: fatto
Creating journal (32768 blocks): fatto
Scrittura delle informazioni dei super-blocchi e dell'accounting del file system: fatto
Затем мы можем смонтировать нашу файловую систему:
mkdir /var/www
mount /dev/drbd1 /var/www
Каталог /var/www теперь монтируется через систему drbd.
В этом сценарии с основной/дополнительной конфигурацией мы внедрили систему аварийного восстановления.
В этом случае, если вы попытаетесь смонтировать файловую систему на втором узле, вы получите ошибку:
:~# mount /dev/drbd1 /var/www/
mount: /dev/drbd1 is write-protected, mounting read-only
mount: mount /dev/drbd1 on /var/www failed: Tipo di supporto errato
Это нормально и ожидаемо из-за нашей конфигурации.
Теперь мы можем имитировать отказ mysql1, поэтому выключите его с помощью команды poweroff.
На mysql2 мы видим, что происходит:
Oct 5 13:52:14 mysql2 kernel: [13458.629215] drbd r0: PingAck did not arrive in time.
Oct 5 13:52:14 mysql2 kernel: [13458.629587] drbd r0: peer( Primary -> Unknown ) conn( Connected -> NetworkFailure ) pdsk( UpToDate -> DUnknown )
Oct 5 13:52:14 mysql2 kernel: [13458.629919] drbd r0: asender terminated
Oct 5 13:52:14 mysql2 kernel: [13458.629921] drbd r0: Terminating drbd_a_r0
Oct 5 13:52:14 mysql2 kernel: [13458.630028] drbd r0: Connection closed
Oct 5 13:52:14 mysql2 kernel: [13458.630035] drbd r0: conn( NetworkFailure -> Unconnected )
Oct 5 13:52:14 mysql2 kernel: [13458.630035] drbd r0: receiver terminated
Oct 5 13:52:14 mysql2 kernel: [13458.630036] drbd r0: Restarting receiver thread
Oct 5 13:52:14 mysql2 kernel: [13458.630037] drbd r0: receiver (re)started
Oct 5 13:52:14 mysql2 kernel: [13458.630041] drbd r0: conn( Unconnected -> WFConnection )
Узел mysql2 обнаруживает, что mysql1 мертв, и если мы проверим файл /proc/drbd:
:~# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown C r-----
ns:0 nr:5457236 dw:5457236 dr:0 al:0 bm:320 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
мы можем видеть, что статус изменился с Вторичный/основной на Вторичный/неизвестный. Итак, теперь мы делаем трюк, продвигая mysql2 как первичный. В mysql2 просто запустите:
drbdadm primary r0
давайте еще раз проверим /proc/drbd и увидим волшебство...
:~# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown C r-----
ns:0 nr:5457236 dw:5457236 dr:912 al:0 bm:320 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
Как видите, наша нода теперь первична и может регулярно монтироваться.
:~# df -h
File system Dim. Usati Dispon. Uso% Montato su
/dev/sda1 9,3G 1,4G 7,5G 16% /
udev 10M 0 10M 0% /dev
tmpfs 97M 4,6M 92M 5% /run
tmpfs 241M 0 241M 0% /dev/shm
tmpfs 5,0M 4,0K 5,0M 1% /run/lock
tmpfs 241M 0 241M 0% /sys/fs/cgroup
/dev/drbd1 4,8G 10M 4,6G 1% /var/www
Теперь предположим, что мы снова хотим заняться mysql1, если мы начнем сейчас, то можно разделить мозг, фактически вы можете проверить журнал и увидеть эти ошибки:
Oct 5 14:26:04 mysql1 kernel: [ 7.760588] drbd r0: conn( StandAlone -> Unconnected )
Oct 5 14:26:04 mysql1 kernel: [ 7.760599] drbd r0: Starting receiver thread (from drbd_w_r0 [458])
Oct 5 14:26:04 mysql1 drbdadm[435]: adjust net: r0
Oct 5 14:26:04 mysql1 drbdadm[435]: ]
Oct 5 14:26:04 mysql1 kernel: [ 7.769318] drbd r0: receiver (re)started
Oct 5 14:26:04 mysql1 kernel: [ 7.769327] drbd r0: conn( Unconnected -> WFConnection )
Oct 5 14:26:04 mysql1 /etc/init.d/mysql[485]: MySQL PID not found, pid_file detected/guessed: /var/run/mysqld/mysqld.pid
Oct 5 14:26:04 mysql1 acpid: starting up with netlink and the input layer
Oct 5 14:26:04 mysql1 acpid: 1 rule loaded
Oct 5 14:26:04 mysql1 acpid: waiting for events: event logging is off
Oct 5 14:26:05 mysql1 kernel: [ 8.270578] drbd r0: Handshake successful: Agreed network protocol version 101
Oct 5 14:26:05 mysql1 kernel: [ 8.270581] drbd r0: Agreed to support TRIM on protocol level
Oct 5 14:26:05 mysql1 kernel: [ 8.270770] drbd r0: conn( WFConnection -> WFReportParams )
Oct 5 14:26:05 mysql1 kernel: [ 8.270771] drbd r0: Starting asender thread (from drbd_r_r0 [461])
Oct 5 14:26:05 mysql1 kernel: [ 8.272594] block drbd1: drbd_sync_handshake:
Oct 5 14:26:05 mysql1 kernel: [ 8.272597] block drbd1: self 242B364F4A5B9C68:525CC995A3CFBA2B:44A1DE193A6C6701:0000000000000004 bits:64463 flags:0
Oct 5 14:26:05 mysql1 kernel: [ 8.272598] block drbd1: peer 6903F6042F95F5FF:525CC995A3CFBA2A:44A1DE193A6C6700:0000000000000004 bits:4 flags:0
Oct 5 14:26:05 mysql1 kernel: [ 8.272599] block drbd1: uuid_compare()=100 by rule 90
Oct 5 14:26:05 mysql1 kernel: [ 8.272601] block drbd1: helper command: /sbin/drbdadm initial-split-brain minor-1
Oct 5 14:26:05 mysql1 kernel: [ 8.272692] drbd r0: meta connection shut down by peer.
Oct 5 14:26:05 mysql1 kernel: [ 8.272720] drbd r0: conn( WFReportParams -> NetworkFailure )
Oct 5 14:26:05 mysql1 kernel: [ 8.272722] drbd r0: asender terminated
Oct 5 14:26:05 mysql1 kernel: [ 8.272722] drbd r0: Terminating drbd_a_r0
Oct 5 14:26:05 mysql1 kernel: [ 8.279158] block drbd1: helper command: /sbin/drbdadm initial-split-brain minor-1 exit code 0 (0x0)
Oct 5 14:26:05 mysql1 kernel: [ 8.279173] block drbd1: Split-Brain detected but unresolved, dropping connection!
Oct 5 14:26:05 mysql1 kernel: [ 8.279197] block drbd1: helper command: /sbin/drbdadm split-brain minor-1
Oct 5 14:26:05 mysql1 kernel: [ 8.286125] block drbd1: helper command: /sbin/drbdadm split-brain minor-1 exit code 0 (0x0)
Oct 5 14:26:05 mysql1 kernel: [ 8.286144] drbd r0: conn( NetworkFailure -> Disconnecting )
Oct 5 14:26:05 mysql1 kernel: [ 8.286146] drbd r0: error receiving ReportState, e: -5 l: 0!
Oct 5 14:26:05 mysql1 kernel: [ 8.287009] drbd r0: Connection closed
Oct 5 14:26:05 mysql1 kernel: [ 8.287017] drbd r0: conn( Disconnecting -> StandAlone )
Oct 5 14:26:05 mysql1 kernel: [ 8.287018] drbd r0: receiver terminated
Oct 5 14:26:05 mysql1 kernel: [ 8.287019] drbd r0: Terminating drbd_r_r0
Это связано с тем, что теперь у нас есть два основных узла, что невозможно в конфигурации «первичный/вторичный». Итак, предполагая новый идентификатор данных в mysql2, мы должны понизить mysql1 до вторичного.
Итак, на mysql1 запустите:
[email :~# drbdadm connect --discard-my-data r0
Вместо этого на mysql2, который является выжившим из-за расщепленного мозга, мы должны выполнить:
:~# drbdadm connect r0
теперь вы можете проверить и убедиться, что все перестраивается правильно, но теперь mysql1 является вторичным, а mysql2 — первичным.
:~# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
srcversion: 1A9F77B1CA5FF92235C2213
1: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
ns:0 nr:28224 dw:28224 dr:0 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:229628
[=>..................] sync'ed: 11.2% (229628/257852)K
finish: 0:01:04 speed: 3,528 (3,528) want: 6,600 K/sec