|
Ключевые слова: drbd, disk, storage, linux, raid, mdadm, iscsi, samba, heartbeat, (найти похожие документы)
From: Моисеев Петр <pmoiseev@inbox.ru.> Newsgroups: email Date: Mon, 24 Mar 2008 14:31:37 +0000 (UTC) Subject: Отказоустойчивые файловые хранилища на основе DRBD Цель: Собрать отказоустойчивую систему систему из 2 территориально распределенных узлов, Узлы должны предоставлять сервисы SMB и iSCSI. Первоначально система задумывалась как носитель кворума для Microsoft Windows Cluster. Установка. Берем системник с 2 х 1Gb сетевыми картами, можно пока без контроллера собираем, ставим Fedora Linux при установке можно выкинуть опции графики, добавить опции * Средства разработки * Средства разработки ядра * Windows File Server настраиваем сеть на статические адреса (192.168.1.41/23 , 10.133.133.1/24) и (192.168.1.42/23 10.133.133.2/24), имена ps02 и ps01. Перегружаем, проверяем. Вставляем контроллер и диски массива. При первой загрузке заходим в конфигуратор контролера и удаляем все разделы, массивы и проч. RAID будет софтварный, хотя это не обязательно. Пусть первая машина будет ps02 (192.168.1.42/23) на ее примере опишу настройку. Загружаемся Проверяем загрузился ли драйвер контролера ps02:~ # lsmod | grep promise sata_promise 16388 9 libata 119188 1 sata_promise Теперь наши диски доступны как обычные SCSI устройства /dev/sd[a|b|c|d|] Разобъем диски для создания массивов: Я делаю на 3 дисках по 500Gb 3 раздела: 20+20+460 под RAID5+RAID5+RAID0 режем первый диск ps02:~ # fdisk /dev/sda Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-60801, default 1): Enter Last cylinder or +size or +sizeM or +sizeK (1-60801, default 60801): +20000M Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (2434-60801, default 2434):Enter Using default value 2434 Last cylinder or +size or +sizeM or +sizeK (2434-60801, default 60801): +20000M Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First cylinder (4867-60801, default 4867):Enter Using default value 4867 Last cylinder or +size or +sizeM or +sizeK (4867-60801, default 60801):Enter Using default value 60801 Настало время посмотреть что вышло Command (m for help): p Disk /dev/sda: 500.1 GB, 500107862016 bytes 255 heads, 63 sectors/track, 60801 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 1 2433 19543041 83 Linux /dev/sda2 2434 4866 19543072+ 83 Linux /dev/sda3 4867 60801 449297887+ 83 Linux Все устаивает, записываем: Command (m for help): w The 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 at the next reboot. Syncing disks. Копируем таблицу разбиения на 2 и 3 диски: ps02:~ # sfdisk -d /dev/sda | sfdisk /dev/sdb ps02:~ # sfdisk -d /dev/sda | sfdisk /dev/sdc Это может не получится, если на дисках были какие то разделы или остатки от них, тогда разбиваем руками либо все удалить через fdisk, перегрузится и повторить копирование. Вспоминаем, что нам говорили "The new table will be used at the next reboot." ps02:~ # reboot Создаем RAID массив /dev/md0 5 уровня из 3 первых разделов с каждого диска ps02:~ # mdadm -Cv /dev/md0 --level=5 --raid-devices=3 /dev/sda1 /dev/sdb1 /dev/sdc1 mdadm: layout defaults to left-symmetric mdadm: chunk size defaults to 64K mdadm: size set to 19542976K mdadm: array /dev/md0 started. Делаем второй RAID (/dev/md1) ps02:~ # mdadm -Cv /dev/md1 --level=5 --raid-devices=3 /dev/sda2 /dev/sdb2 /dev/sdc2 mdadm: layout defaults to left-symmetric mdadm: chunk size defaults to 64K mdadm: size set to 19542976K mdadm: array /dev/md1 started. Делаем RAID массив /dev/md2 0 уровня из 3 последних разделов с каждого диска ps02:~ # mdadm -Cv /dev/md2 --level=0 --raid-devices=3 /dev/sda3 /dev/sdb3 /dev/sdc3 mdadm: chunk size defaults to 64K mdadm: array /dev/md2 started. Массивы готовы. Ставим drbd. Лучше взять свежий, стандартный в поставке у меня не завелся. Если повезло, и разработчики выложили скомпилированную версию, ставим ее через rpm. ps02:~ # rpm -i drbd-kmp-default-8.0.4_2.6.18.2_34-3.1.i586.rpm ps02:~ # rpm -i ddrbd-8.0.4-3.1.i586.rpm Если не выложили, а они скорее всего, не выложат, берем drbd (на момент написания версия 8.2.4) в исходниках и компилируем сами. ps02:~ # wget http://oss.linbit.com/drbd/8.2/drbd-8.2.4.tar.gz ps02:~ # tar -xfvz drbd-8.2.4.tar.gz ps02:~ # cd drbd-8.2.4 ps02:drbd-8.2.4 # less INSTALL и читаем, читаем, читаем.. Если все понятно, начинаем компиляцию ps02:drbd-8.2.4 # make Возможно, нам повезет и все соберется без ошибок, если нет, следуем рекомендациям разработчиков как подружить текущую версию drbd с нашей версией ядра/модулей. После сборки ps02:drbd-8.2.4 # make install Проверяем. ps02:~ # modprobe drbd Должен загрузится молча ps02:~ # lsmod | grep drbd drbd 202632 0 (конкретные цифирки могут быть другие - это его место в памяти) Пишем конфигурацию для drbd. /etc/drbd.conf resource r0 { protocol C; startup { wfc-timeout 30; degr-wfc-timeout 120; } disk { on-io-error detach; } net { timeout 60; connect-int 10; ping-int 10; max-buffers 2048; max-epoch-size 2048; after-sb-0pri discard-younger-primary; after-sb-1pri consensus; } syncer { rate 500M; } on ps01 { address 10.133.133.1:7790; disk /dev/md0; device /dev/drbd0; meta-disk "internal"; } on ps02 { address 10.133.133.2:7790; disk "/dev/md0"; device "/dev/drbd0"; meta-disk "internal"; } } resource r1 { protocol C; startup { wfc-timeout 30; degr-wfc-timeout 120; } disk { on-io-error detach; } net { timeout 60; connect-int 10; ping-int 10; max-buffers 2048; max-epoch-size 2048; after-sb-0pri discard-younger-primary; after-sb-1pri consensus; } syncer { rate 500M; } on ps01 { address 10.133.133.1:7791; disk /dev/md1; device /dev/drbd1; meta-disk "internal"; } on ps02 { address 10.133.133.2:7791; disk "/dev/md1"; device "/dev/drbd1"; meta-disk "internal"; } } resource r2 { protocol C; startup { wfc-timeout 30; degr-wfc-timeout 120; } disk { on-io-error detach; } net { timeout 60; connect-int 10; ping-int 10; max-buffers 2048; max-epoch-size 2048; after-sb-0pri discard-younger-primary; after-sb-1pri consensus; } syncer { rate 500M; } on ps01 { address 10.133.133.1:7792; disk /dev/md2; device /dev/drbd2; meta-disk "internal"; } on ps02 { address 10.133.133.2:7792; disk "/dev/md2"; device "/dev/drbd2"; meta-disk "internal"; } } Мы описали 3 реплицируемых раздела r0, r1 и r2. Имена машин должны совпадать с hostname, порты или адреса уникальные для каждого ресурса. Поскольку наши разделы пустые (Точно пустые?), сначала нужно написать туда метаданные ps02:~ # drbdadm create-md r0 About to create a new drbd meta data block on /dev/md1. ==> This might destroy existing data! <== Do you want to proceed? [need to type 'yes' to confirm] yes Creating meta data... initialising activity log NOT initialized bitmap (1196 KB) New drbd meta data block sucessfully created. --== Creating metadata ==-- As with nodes we count the total number of devices mirrored by DRBD at at http://usage.drbd.org. The counter works completely anonymous. A random number gets created for this device, and that randomer number and the devices size will be sent. http://usage.drbd.org/cgi-bin/insert_usage.pl?nu=3966802262746037346&r u=8460917460176902775&rs=40024014848 Enter 'no' to opt out, or just press [return] to continue:Enter success Длинная страшная ссылка - это отправка разработчикам данных о том, что у них появилась еще одна инсталляция, используется для сбора статистики востребованности продукта. Можно отказаться, набрав no, но я обычно радую ребят еще одним клиентом, если у тачки есть интернет ps02:~ # drbdadm create-md r1 ps02:~ # drbdadm create-md r2 Теперь объявим эту половинку главной в паре drbd ps02:~ # drbdadm -- --overwrite-data-of-peer primary all ps02:~ # service drbd start ps02:~ # service drbd status drbd driver loaded OK; device status: version: 8.0.4 (api:86/proto:86) SVN Revision: 2947 build by phil@mescal, 2007-06-27 14:17:06 0: cs:WFConnection st:Primary/Unknown ds:UpToDate/DUnknown C r--- ns:0 nr:0 dw:685488 dr:67776 al:480 bm:353 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0 act_log: used:0/127 hits:170892 misses:877 starving:0 dirty:397 changed:480 1: cs:WFConnection st:Primary/Unknown ds:UpToDate/DUnknown C r--- ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0 act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0 2: cs:WFConnection st:Primary/Unknown ds:UpToDate/DUnknown C r--- ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0 act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0 Форматируем разделы: ps02:~ # mkfs /dev/drbd1 ps02:~ # tune2fs -j -c 0 -i 0 /dev/drbd1 ps02:~ # mkfs /dev/drbd2 ps02:~ # tune2fs -j -c 0 -i 0 /dev/drbd2 Обратите внимание - форматировать (как и монтировать в дальнейшем) нужно именно /dev/drbdХ а не /dev/mdX и тем более не /dev/sdX. Настала пора ставить ietd этот демон обявит в сеть раздел диска как iSCSI устройство. Забираем исходники свежие всегда можно найти на http://iscsitarget.sourceforge.net/ Скачиваем, распаковываем, собираем, ставим. ps02:~ # wget http://downloads.sourceforge.net/iscsitarget/iscsitarget-0.4.15.tar.gz ps02:~ # tar -zfxv iscsitarget-0.4.15.tar.gz ps02:~ # cd iscsitarget-0.4.15 ps02:iscsitarget-0.4.15 # make ps02:iscsitarget-0.4.15 # make install ps02:iscsitarget-0.4.15 # modprobe iscsi_trgt Если возникли ошибки - читать README из комплекта поставки. Пишем конфигурацию для ietd /etc/ietd.conf Target iqn.2008.com.example:storage.disk2.sys1.xyz IncomingUser iscsi_user_name password_more_than_12_chars Lun 0 Path=/dev/drbd0,Type=fileio Теперь наше iSCSI устройство готово к взлету. Samba по идее была установлена вместе с системой. Пишем конфигурацию для нее. /etc/samba/smb.conf [global] workgroup = wing netbios name = FS000 interfaces = lo eth0:0 bind interfaces only = Yes server string = Print Spooler Cluster security = domain encrypt passwords = yes printing = cups printcap name = cups printcap cache time = 750 cups options = raw guest account = smbguest guest ok = yes admin users = @"WING\domain admins" valid users = @"WING\domain users" idmap uid = 1000-3000 idmap gid = 1000-3000 winbind enum users = Yes winbind enum groups = Yes wins server = 192.168.0.2 winbind use default domain = Yes template shell = /bin/bash log level = 0 log file = /var/log/samba/%m.log guest ok = Yes read only = no inherit owner = yes inherit acls = yes inherit permissions = yes map acl inherit = yes [printers] comment = All Printers path = /var/tmp printable = Yes create mask = 0600 browseable = No [print$] comment = Printer Drivers path = /var/lib/samba/drivers create mask = 0664 directory mask = 0775 writable = Yes [work] path = /HA/work valid users = @"WING\domain admins" [data] path = /HA/data valid users = @"WING\designers", @"WING\domain admins" write list = @"WING\designers", @"WING\domain admins" Итак у нас есть * Зеркалируемые по сети диски * Демон iSCSI * Windows-совместимый файловый сервер Осталось поставить службу которая будет следить за жизнеспособностью узлов, и управлять запуском наших служб. Скорее всего, если Fedora Core 6 стандартная, heartbeat при компиляции выкинет warning, что ей не хватает библиотеки libnet поэтому сначала идем на http://rpmfind.net/linux/rpm2html/search.php?query=libnet качаем и ставим libnet ps02:~ # wget ftp://rpmfind.net/linux/fedora/core/development/source/SRPMS/libnet-1.1.2.1-10.fc7.src.rpm ps02:~ # rpm -i libnet-1.1.2.1-10.fc7.src.rpm ps02:~ # cd libnet-1.1.2.1-10 ps02:libnet-1.1.2.1-10 # make ps02:libnet-1.1.2.1-10 # make instal Скачиваем, распаковываем, собираем, ставим heartbeat ps02:~ # wget http://linux-ha.org/download/heartbeat-2.1.3.tar.gz ps02:~ # tar -xfvz heartbeat-2.1.3.tar.gz ps02:~ # cd heartbeat-2.1.3 ps02:heartbeat-2.1.3 # ./configure ps02:heartbeat-2.1.3 # make ps02:heartbeat-2.1.3 # make install Конфигурация для heartbeat /etc/ha.d/ha.cf debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility local0 udpport 694 # Use port number 694 for bcast or ucast communication. # This is the default, and the official IANA registered port number. bcast eth0 eth1 keepalive 1 warntime 5 # Time in seconds before issuing a "late heartbeat" warning in the logs. deadtime 15 # Node is pronounced dead after 30 seconds. initdead 30 # With some configurations, the network takes some # time to start working after a reboot. # This is a separate "deadtime" to handle that case. # It should be at least twice the normal deadtime. auto_failback off # Required. For those familiar with Tru64 Unix, # heartbeat acts as if in "favored member" mode. # The master listed in the haresources file holds all the # resources until a failover, at which time the slave takes over. # When auto_failback is set to on once the master comes back online, # it will take everything back from the slave. When set to off this # option will prevent the master node from re-acquiring cluster resources after a failover. # This option is similar to to the obsolete nice_failback option. # If you want to upgrade from a cluster which had nice_failback set off, # to this or later versions, special considerations apply in order to want to # avoid requiring a flash cut. Please see the FAQ for details on how to deal with this situation. node ps01 ps02 # Mandatory. Hostname of machine in cluster as described by `uname -n`. # respawn userid cmd # Optional: Lists a command to be spawned and monitored. # Eg: To spawn ccm daemons the following line has to be added: # respawn hacluster /usr/lib/heartbeat/ccm # Informs heartbeat to spawn the command withthe credentials of that of userid # (hacluster, in this example) and monitors the health of the process, # respawning it if dead. For ipfail, the line would be: # respawn hacluster # /usr/lib/heartbeat/ipfail ping_group switches 192.168.1.13 192.168.1.19 192.168.1.20 # Optional: Specify ping nodes. # These nodes are not considered as cluster nodes. # They are used to check network connectivity for modules like ipfail. /etc/ha.d/haresources ps02 drbddisk::r0 192.168.1.40/23 iscsi-target drbddisk::r1 Filesystem::/dev/drbd1::/HA/work::ext3::acl drbddisk::r2 Filesystem::/dev/drbd2::/HA/data::ext3::acl samba Одна половинка готова, клонируем систему на вторую машину. Клонирование Acronis почти все сделает сам, но не сможет правильно прописать загрузчик. Поэтому: Собираем вторую тачку, Вставляем диск-клон и CDROM грузимся с загрузочного CD, например Fedora Core 6. При появлении приглашения выбираем режим восстановления boot:linux rescue Взлетаем с CD, # chroot /mnt/sysimage # grub-install /dev/hda # reboot Можно грузится с клона. Если необходимо, доставляем драйвера на железо, которого не было на первой половинке. Не забываем измсменить имя, сетевые настройки, скопировать все файлы конфигураций. Использование Вообще-то специального обслуживания эта система не требует, нужно только не забывать при изменениях в конфигрурации копировать их на вторую половинку. Восстановление после аварий. При падении/отключении одного их узлов второй принимает управление самостоятельно, самое неприятное что может произойти - это ситуация, когда узлы теряют друг друга из вида, при этом остаются on-line, оба считают себя единственными выжившими и обслуживают пользователей. В таком случае некоторое время оба узла работают в режиме Primary, и данные на них расходятся. При появлении связи между узлами drbd не сможет самостоятельно принять решение кого оставить. Такая ситуация называется split-brain. DRBD попытается разрешшить split-brain пользуясь директивами after-sb-0pri discard-younger-primary; after-sb-1pri consensus; файла конфигурации. Т.е. если split-brain произошел после того как оба узла были secondary то выбрать последнего primary в качестве ведущего, если split-brain при одном ведущем, опустить его до secondary и попробовать разрешить ситуацию по первому алгоритму. Если эти варианты не приемлемы, то узлы переходят в состояние StandAlone, т.е. синхронизации не происходит. Администратор должен сам принять решение, кого оставить главным. Тогда на узле, который будет ведомым нужно выполнить ps02:~ # drbdadm -- --discard-my-data connect all А на ведущем узле ps01:~ # drbdadm connect all DRBD синхронизирует изменения с ps01 на ps02. Эта операция занимает обычно несколько минут. В случае, если на одном из узлов данных нет или они не представляют интереса(был отказ дисковой подсистемы, узел находился на ремонте или обслуживании продолжительное время) можно выполнить полную синхронизацию. Тогда на ведущем узле выполнить: ps02:~ # drbdadm -- --overwrite-data-of-peer primary all Состояние можно увидеть ps02:~ # cat /proc/drbd version: 8.2.4 (api:88/proto:86-88) GIT-hash: fc00c6e00a1b6039bfcebe37afa3e7e28dbd92fa build by root@ps02, 2008-02-05 12:20:22 0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r--- ns:520192 nr:0 dw:1672 dr:520192 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:32492 misses:62 starving:0 dirty:0 changed:62 act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0 1: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r--- ns:520192 nr:0 dw:35384 dr:521977 al:7 bm:129 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:32612 misses:122 starving:0 dirty:0 changed:122 act_log: used:0/127 hits:239 misses:7 starving:0 dirty:0 changed:7 2: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r--- ns:524768 nr:0 dw:359320 dr:537213 al:384 bm:1032 lo:0 pe:0 ua:0 ap:0 resync: used:0/31 hits:264409 misses:651 starving:0 dirty:0 changed:651 act_log: used:0/127 hits:2036 misses:384 starving:0 dirty:0 changed:384 Полная синхронизация на массиве размером 1.2 Тб занимает чуть меньше 10 часов. Рассмотрим ситуацию отказа узла при сохранении данных на дисках, (процессор/материнская плата/...) Меняем отказавшее железо, взлетаем, строим массив из существующих дисков. ps02:~ # for i in `seq 1 9`; do mknod /dev/md$i b 9 $i ps02:~ # mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1 /dev/sdc1 ps02:~ # mdadm --assemble /dev/md1 /dev/sda2 /dev/sdb2 /dev/sdc2 ps02:~ # mdadm --assemble /dev/md2 /dev/sda3 /dev/sdb3 /dev/sdc3 В моем случае устройства /dev/md[1-9] терялсь после перезагрузки, поэтому команду for i in `seq 1 9`; do mknod /dev/md$i b 9 $i я добавил в /etc/rc.sysinit
|
Обсуждение | [ Линейный режим | Показать все | RSS ] |
|
Добавить комментарий |
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |