ДМИТРИЙ РОЖКОВ
Построение программных RAID-массивов в Linux
Вряд ли стоит говорить о том, насколько важным бывает сохранить в рабочем состоянии сервер или рабочую станцию. И одним из способов повысить надёжность системы – внести в неё избыточность.
В данной статье речь пойдёт о построении программных RAID-массивов в Linux, которые, вообще говоря, придумывались не только для повышения надёжности. Но, как правило, именно эту цель преследуют системные администраторы, вставляя в системный блок «лишние» диски. И судя по тому, как расшифровывается RAID (Redundant Array of Inexpensive Disk), именно об этом думал автор аббревиатуры. Поэтому в своей статье я сделаю ударение именно на надёжности. Кроме того, я исхожу из предположения, что читатель уже имеет представление о том, какие разновидности RAID существуют, и знаком с терминологией, так как эти вопросы уже были очень подробно освещены в статье Алексея Серебрякова [1].
Несмотря на то, что данная тема уже очень хорошо раскрыта во множестве статей и, в частности, в документе «The Software-RAID HOWTO», который стоит прочитать всем, кому не безразлична судьба своих данных, почему-то часто описываемая технология не находит себе применение. Объяснением сему может послужить тот факт, что на сегодняшний день автору известен только один дистрибутив Linux (видимо, плохо искал, но всё же), в инсталляторе которого присутствует поддержка RAID. Пока только инсталлятор от RedНat позволяет разместить всю файловую систему на RAID1-массиве и загрузиться с него. Поэтому для того, чтобы мой рассказ был универсальным, я хотел бы описать процедуру переноса файловой системы уже установленного сервера с «обычного» диска на RAID1-массив, независимую от типа дистрибутива. Следует отметить, что в настоящее время возможно реализовать автоматическую загрузку операционной системы с RAID-массива только в том случае, если раздел файловой системы, с которой производится загрузка ОС, размещен на устройстве RAID1.
Итак, прежде всего нам потребуется ядро с включенной в него поддержкой RAID.
Убедитесь, что в файле конфигурации ядра присутствуют следующие строчки:
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_RAID1=y
В принципе не является проблемой включить поддержку RAID в модули и загружать эти модули из ram-диска, но как показал мой опыт, скомпилированный в ядро драйвер md ведет себя несколько иначе, чем в случае его выноса в отдельный модуль. Например, в последнем случае некорректно обрабатывается ситуация, когда при поднятии RAID-массива, в котором один из дисков (а именно первый опрашиваемый драйвером на наличие RAID-суперблока) не имеет RAID-суперблока, то есть при создании массива был помечен как сбойный, драйвер отказывается запускать весь массив в «деградированном режиме» (degraded mode). Кроме ядра нам потребуются также и raidtools, которые входят в состав практически любого дистрибутива.
Предположим, что в нашем распоряжении уже имеется установленная система на диске /dev/sda, на котором есть только один корневой раздел, тогда нам потребуется сначала создать файл /etc/raidtab следующего содержания:
raiddev /dev/md0
raid-level 1
nr-raid-disks 2
chunk-size 64k
persistent-superblock 1
device /dev/sda1
raid-disk 0
failed-disk 0
device /dev/sdb1
raid-disk 1
Формат этого файла описан в одноимённой man-странице. Но коротко пройдёмся по нему строчка за строчкой. Ключевое слово raiddev определяет начало секции, относящейся к одному RAID-массиву (/dev/md0). Параметр raid-level, как можно догадаться, задаёт уровень RAID-массива. В нашем случае массив /dev/md0 определён как RAID-1. Допустимыми значениями являются также linear (линейный режим), 0 для RAID-0, 4 для RAID-4 и 5 для RAID-5. Параметр nr-raid-disks указывает, сколько дисков входит в RAID-массив; chunk-size – размер чанка. Очень важной является строчка:
persistent-superblock 1
Значение 1 разрешает при создании RAID-массива средствами raidtools записывать в конец каждого дискового раздела специальный суперблок, в котором хранится конфигурация RAID-устройства. Именно благодаря наличию этого суперблока при загрузке системы у ядра появляется возможность читать конфигурацию RAID-массива непосредственно с диска без необходимости монтировать корневую файловую систему, чтобы прочитать содержимое файла raidtab. Соответственно значение 0 препятствует созданию суперблока.
Ключевое слово device определяет начало подсекции, относящейся к реальному дисковому разделу, входящему в массив (/dev/sda1 и /dev/sdb1). В этой секции должен всегда присутствовать один из следующих параметров:
- raid-disk – определяет индекс раздела в массиве;
- spare-disk – определяет индекс резервного диска;
- parity-disk – принудительно определяет раздел для хранения информации о контроле чётности (данный параметр применим к RAID-массивам уровней 4 и 5).
Кроме того, в нашем случае параметром failed-disk устройство /dev/sda1 было помечено как сбойное с индексом 0, что должно предотвратить включение в RAID-массив при его создании раздел с работающей ОС (этот параметр применим к RAID-массивам уровней 1, 4 и 5).
После этого надо убедиться, что в системе присутствуют файлы устройств /dev/md0, а также /dev/md1,...,/dev/mdN, если разделов больше одного. Если файлы отсутствуют, их необходимо создать командами:
# mknod /dev/md0 b 9 0
# mknod /dev/md1 b 9 1
.....
# mknod /dev/mdN b 9 N
Далее можно приступить уже к поднятию RAID-массива. Для этого необходимо изменить тип файловой системы на 0xFD (Linux raid autodetect) на всех разделах жесткий дисков, которые планируется включить в массив. Также надо убедиться, что размеры созданных на диске /dev/sdb разделов чуть меньше или равны размерам соответствующих разделов на диске /dev/sda. И командой:
# mkraid /dev/md0
наконец запустить RAID-массив. Это устройство нужно отформатировать под нужную файловую систему. Файловая система может быть какой угодно, но нас интересует ext2.
# mke2fs /dev/md0
Теперь новое устройство можно подмонтировать к какому-нибудь каталогу:
# mount -t ext2 /dev/md0 /mnt/newroot
и скопировать на него содержимое текущего root-раздела.
# cd /
# find . -xdev | cpio -pm /mnt/newroot
В том случае, когда исходная файловая система состоит из нескольких разделов, эту процедуру придется повторить и для них, но для этого можно уже воспользоваться более понятной командой:
# cp -a /usr /mnt/newroot/usr
После этого требуется изменить два конфигурационных файла в новой файловой системе: /mnt/newroot/etc/fstab и /mnt/newroot/etc/lilo.conf. В первом надо заменить все файловые системы, которые планируется перевести на RAID-массив, на соответствующие RAID-устройства. В нашем случае старая строчка для корневого раздела:
/dev/sda1 / ext2 defaults,errors=remount-ro 0 1
заменится на что-то вроде:
/dev/md0 / ext2 defaults,errors=remount-ro 0 1
Во втором файле потребуются более существенные изменения: во-первых, надо изменить путь к устройству, с которого будет производиться загрузка, и путь к устройству, которое будет монтироваться как устройство с корневой файловой системой; во-вторых, необходимо дополнительно указать, на какие устройства надо записать загрузочную запись. Тогда обновленный lilo.conf приобретет следующий вид:
# Описывает загрузочное устройство, куда LILO устанавливает boot-сектор. Это устройство может быть либо обычным
# разделом, либо raw-устройством http://www.acq.osd.mil/bmdo/bmdolink/bcmt/images/images_lg/boom.jpg (в этом случае
# boot-сектор записывается в MBR). В нашем же случае загрузочным устройством является RAID-массив.
#
boot=/dev/md0
# Определяет устройство, которое должно быть подмонтировано в качестве корневой файловой системы. (`/')
#
root=/dev/md0
# Так как при записи загрузочного блока на RAID-устройство LILO никогда не изменяет автоматически MBR жесткого
# диска включенного в RAID-массив и при этом пронумерованным BIOS как 0x80 (то есть диск определён в BIOS
# как загрузочный), единственный способ записать всё же в MBR такого диска boot-сектор – это перечислить в параметре
# raid-extra-boot все устройства, куда необходимо установить boot-сектор. Тогда в случае выхода из строя одного из дисков,
# а именно с которого фактически загружалась ОС, загрузка всё равно будет происходить с другого диска, входящего
# в RAID-массив.
#
raid-extra-boot="/dev/sda,/dev/sdb"
# Так как текущий загрузочный диск пока ещё не входит в RAID-массив, загрузка ОС, размещённой на RAID-массиве, должна
# производиться со второго диска. Для этого сообщаем LILO, что диск /dev/sdb будет выбран в BIOS как загрузочный.
#
disk=/dev/sdb
bios=0x80
# Устанавливает указанный файл в новый boot-сектор
#
install=/boot/boot.b
delay=20
default=Linux
image=/vmlinuz
label=Linux
read-only
Когда необходимые изменения внесены, достаточно командой:
# chroot /mnt/newroot lilo
установить системный загрузчик. Теперь операционная система должна загружаться и с RAID-массива. Однако пока в RAID-массив входит только один диск /dev/sdb. Чтобы загрузиться с него, нужно перезагрузить компьютер и в BIOS выбрать в качестве загрузочного диска /dev/sdb.
Когда операционная система загрузится, работу RAID-массива можно проверить, посмотрев содержимое файла /proc/mdstat. Там должно быть что-то похожее на:
Personalities : [raid1]
read_ahead 1024 sectors
md0 : active raid1 sdb1[1]
3365504 blocks [1/2] [_U]
Такая запись означает, что пока только один диск входит в работающий RAID-массив. Для завершения процедуры остается только добавить второй диск в массив:
# raidhotadd /dev/md0 /dev/sda1
После ввода этой команды начнется процесс зеркалирования диска, по окончании которого файл /proc/mdtstat приобретет следующий вид:
Personalities : [raid1]
read_ahead 1024 sectors
md0 : active raid1 sda1[0] sdb1[1]
3365504 blocks [2/2] [UU]
На этом построение RAID-массива можно считать законченным. Но тема вряд ли будет исчерпана, если не сказать пару слов о средствах мониторинга. А таким средством уже стало принято считать утилиту Нейла Брауна mdadm (multiple device admin). Применение ее чрезвычайно просто – достаточно запустить эту программу в режиме мониторинга и перечислить в командной строке устройства, состояние которых надо отслеживать.
# nohup mdadm -F -m admin@mydomain.com /dev/md0 &
В случае какого-либо изменения в состоянии RAID-массива описание события отправится по адресу admin@mydomain.com.
Вообще говоря, утилита mdadm предназначена не только для мониторинга, а скорее задумывалась как замена raidtools. И всю описанную процедуру построения массива можно было бы выполнить, используя только mdadm, которая имеет множество преимуществ по сравнению с raidtools. Использование этой утилиты полностью описано в её man-странице, поэтому в данной статье ограничусь лишь несколькими замечаниями.
Во-первых, вся функциональность, которая в raidtools разбросана по нескольким командам (mkraid, raidstart, raidstop, raidhotadd и т. д.), в mdadm сосредоточена в одной команде и определяется параметрами этой команды. А во-вторых, mdadm не полагается на файл /etc/raidtab. Всю необходимую информацию для создания и управления RAID-массивами mdadm черпает из командной строки или, дабы не перечислять каждый раз в командной строке, какое устройство к какому массиву относится, из конфигурационного файла /etc/mdadm.conf. Впрочем, этот файл mdadm может опять же создать автоматически после того, как будут созданы все RAID-массивы.
И напоследок, пара слов о восстановлении системы после сбоя.
Если контроллер жёстких дисков сообщает соответствующему драйверу ОС, что на каком-то разделе одного из дисков невозможно произвести операцию чтения или записи, то такой раздел помечается в RAID-массиве как сбойный. И как уже было сказано, системный администратор может быть уведомлен письмом об этом событии.
Допустим, произошёл сбой на диске /dev/sda. Тогда всё, что остаётся сделать системному администратору, это:
- остановить работу ОС;
- выключить компьютер;
- заменить сбойный диск на новый;
- включить компьютер и подождать, пока загрузится ОС;
- создать раздел /dev/sda1 с размером, равным или чуть большим, чем размер /dev/sdb1;
- изменить тип файловой системы раздела /dev/sda1 на 0xFD;
- добавить новый раздел в RAID-массив.
# raidhotadd /dev/md0 /dev/sda1
После этого можно, не дожидаясь окончания процесса зеркалирования диска, устанновить boot-сектор в MBR диска /dev/sda вводом команды:
# lilo
на случай, если в следующий раз выйдет из строя диск /dev/sdb.
На этом рассказ о построении RAID-массивов можно считать законченным. Но в заключение всё же добавлю, что применение технологии RAID помогает избежать потери данных при выходе из строя дисков, лишь тогда, когда контроллер дисков может этот сбой обнаружить. И кроме того, в случае, когда целостность файловой системы нарушается из-за программного сбоя или внезапного отключения питания, RAID-массив тоже окажется бесполезен. Поэтому никогда не стоит отказываться от такой полезной вещи, как свежий бэкап.
Литература:
- Серебряков А. Основы систем хранения данных. – Журнал «Системный администратор», №3, март 2003 г.– 62-76 с.