Дмитрий Рожков
Вряд ли стоит говорить о том, насколько важным бывает сохранить в рабочем
состоянии сервер или рабочую станцию. И одним из способов повысить надёжность
системы – внести в неё избыточность.
В данной статье речь пойдёт о построении программных
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). В этой секции должен всегда присутствовать один из
следующих параметров:
n raid-disk – определяет индекс раздела в
массиве;
n spare-disk – определяет индекс резервного
диска;
n 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. Тогда всё, что остаётся сделать системному администратору, это:
n остановить работу ОС;
n выключить компьютер;
n заменить сбойный диск на новый;
n включить компьютер и подождать, пока загрузится
ОС;
n создать раздел /dev/sda1 с размером, равным или
чуть большим, чем размер /dev/sdb1;
n изменить тип файловой системы раздела /dev/sda1
на 0xFD;
n добавить новый раздел в RAID-массив.
# raidhotadd
/dev/md0 /dev/sda1
После этого можно, не дожидаясь окончания
процесса зеркалирования диска, устанновить boot-сектор в MBR диска /dev/sda
вводом команды:
# lilo
на случай, если в следующий раз выйдет из строя диск /dev/sdb.
На этом рассказ о построении RAID-массивов можно
считать законченным. Но в заключение всё же добавлю, что применение технологии
RAID помогает избежать потери данных при выходе из строя дисков, лишь тогда,
когда контроллер дисков может этот сбой обнаружить. И кроме того, в случае,
когда целостность файловой системы нарушается из-за программного сбоя или
внезапного отключения питания, RAID-массив тоже окажется бесполезен. Поэтому
никогда не стоит отказываться от такой полезной вещи, как свежий бэкап.
Литература:
1. Серебряков
А. Основы систем хранения данных. – Журнал «Системный администратор», №3, март
2003 г.– 62-76 с.