Миграция работающей системы Debian на RAID1

Представьте себе ситуацию: у вас есть некий сервер собранный из остатков старого железа. Всё это железо рабочее, но не внушает доверия, особенно жёсткий диск. Именно он будет  главным героем этой статьи. В это же время у вас чудесным образом нашелся ещё один жёсткий диск, аналогичный тому, что используется в сервере. Я оказался именно в такой ситуации. И я решил, что лучшим применением «нового» ЖД будет постройка RAID1, т.е. зеркального массива. Дальше будет собственно инструкция, как это сделать.

Стоит ли объяснять, что сперва «новый» ЖД нужно протестировать, например с помощью «Victoria HDD», после чего подключить к серверу.

И тут я хочу обратить ваше внимание, если ваше железо действительно старое, то на системной (материнской) плате будет два разъёма PATA (aka IDE), вместо современных SATA. Так вот, не поленитесь и подключите жёсткие диски отдельно друг от друга, т.е. к каждому разъёму своим шлейфом. Такой способ подключения несколько увеличит скорость работы с ЖД.

После всех выполненных манипуляций, в работающей операционной системе должен появится наш «новый» ЖД, примерно здесь: /dev/sdb. Будьте предельно внимательны с адресами устройств, иначе это может привести к печальным и не обратимым последствиям. Не забывайте про резервные копии (если это конечно нужно и возможно).

В моей ситуации 1-ый ЖД был размечен элементарным образом, что со временем стало неоправданным, да и просто неудобным. Поэтому, я решил заново разметить ЖД, но на этот раз по всем «православным канонам» (или пастафарианским? :). Сперва разметка выполняется на пустом «новом» ЖД. Печально, если вы сами не догадались об этом.

Очистка

Что бы там не было ранее на диске, затрём начало нулями и будем считать ЖД абсолютно чистым:

root@server:~# root@server:~# dd if=/dev/zero of=/dev/sdb bs=1024 count=10000
10000+0 записей считано
10000+0 записей написано
 скопировано 10240000 байт (10 MB), 0.68383 c, 15.0 MB/c

При желании или от скуки, «count=» можно увеличить, например до 1000000 (1 гигабайт) или даже больше 🙂

Разметка

Выполним разметку диска с помощью штатной утилиты «fdisk»

root@server:~# fdisk /dev/sdb

Command (m for help): m
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partitions system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)
Создадим новые разделы

Раздел номер: «1», тип: «primary», размер 500 мегабайт.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 0 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-16083XYZ…, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (ABC…-XYZ…, default XYZ…): +500M
Using value ...

Раздел номер: «2», тип: «primary», размер: максимально возможный, с расчётом, что он поместится и на первом ЖД.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 0 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (ABC…-XYZ…, default ABC…): 
Using default value ABC…
Last sector, +sectors or +size{K,M,G} (ABC…-XYZ…, default XYZ…): +70G
Using value ...

Меняем тип раздела, как для первого, так и для второго используем «fd» (Linux raid auto)

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): L 

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data    
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi eb  BeOS fs        
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT            
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f1  SpeedStor      
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f4  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f2  DOS secondary  
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      fb  VMware VMFS    
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT            
1e  Hidden W95 FAT1 80  Old Minix      
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Повторить для второго раздела

Устанавливаем загрузочный флаг на первый раздел и записываем изменения на диск

Command (m for help): a
Partition number (1-4): 1

Command (m for help): w

Диск «разделан», теперь «замаринуем» его 🙂

RAID

Создадим неполноценный, так сказать «битый», зеркальный массив, из пока-что одного диска, точнее его подготовленных разделов

root@server:~# mdadm --create /dev/md0 --level=1 --raid-disks=2 missing /dev/sdb1
mdadm: array /dev/md0 started.
root@server:~# mdadm --create /dev/md1 --level=1 --raid-disks=2 missing /dev/sdb2 --auto=yes
mdadm: array /dev/md1 started.
root@server:~# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[1]
      511936 blocks [2/1] [_U]
      
md1 : active raid1 sdb2[1]
      77572096 blocks super 1.2 [2/1] [_U]
      
unused devices: < none >
LMV

О удобности и функциональности LVM можно написать много статей, здесь же мы просто полагаемся на опыт автора и сообщества. Первый массив (md0) будет использоваться для загрузки. Второй массив (md1) мы полностью отдадим Logical Volume Manager’у. Итак, инициализируем LVM

root@server:~# vgscan

Инициализируем, т.е. создадим LVM раздел

root@server:~# pvcreate /dev/md1

Создадим группу томов, правда лишь из одного тома, но это не важно

root@server:~# vgcreate vg0 /dev/md1

Активируем свежесозданную группу

root@server:~# vgchange -a y vg0

Создадим логические тома.
Под SWAP: размер 2GiB, метка: swap, наименование: lv0, в группе: vg0

root@server:~# lvcreate -L2g -nswap lv0 vg0

Под корень системы (/)

root@server:~# lvcreate -L18g -nroot lv1 vg0

Под домашние каталоги пользователей (/home)

root@server:~# lvcreate -L50g -nhome lv2 vg0

Наименование группы «vg0» и логических томом «lv0», можно и нужно сменить на более удобные для вас. Например вместо «vg0» использовать «system», а вместо «lv0» => «swap», «lv1» => «root», «lv2» => «home». В таком случае у вас будут читаемые и понятные адреса, например: /dev/system/home и соответственно /dev/mapper/system-home

Форматирование

Подготовка «swap» раздела

root@server:~# mkswap /dev/vg0/lv0

Подготовка «boot» раздела

root@server:~# mkfs.ext2 -L boot /dev/md0

Подготовка «root» раздела

root@server:~# mkfs.ext4 -L root /dev/vg0/lv1

Подготовка «home» раздела

root@server:~# mkfs.ext4 -L home /dev/vg0/lv2
Монтирование
Сборка новой корневой файловой системы

Теперь у нас всё не всё готово для переноса (копирования) нашей системы. Готово лишь на 99%. Прежде чем начать копирование, необходимо воссоздать правильную структуру корневой файловой системы. Для этого создадим новый каталог

root@server:~# mkdir /mnt/raid1/

Примонтируем новый корневой раздел

root@server:~# mount /dev/vg0/lv1 /mnt/raid1/

Восстановим верное расположение «boot» каталога-раздела

root@server:~# mkdir /mnt/raid1/boot
mount /dev/md0 /mnt/raid1/boot

Восстановим верное расположение «home» каталога-раздела

root@server:~# mkdir /mnt/raid1/home
mount /dev/vg0/lv2 /mnt/raid1/home

«Маринование» закончено 🙂 Теперь начнём «жарить»

Копирование
root@server:~# cp -dpRx / /mnt/raid1

Обратите внимание! ЭТО ОЧЕНЬ ВАЖНО!
Копирование будет выполнятся рекурсивно, со всеми правами доступа, ссылками и прочим (и это хорошо), но ТОЛЬКО В ПРЕДЕЛАХ ОДНОГО ФИЗИЧЕСКОГО ТОМА. Это значит, что если текущая система уже использует примонтированные тома, например в /boot или /home, то команду копирования необходимо будет повторить для каждого такого раздела, например:

root@server:~# cp -dpRx /boot/ /mnt/raid1
root@server:~# cp -dpRx /home/ /mnt/raid1

Процесс не быстрый, можно сходить на чаепитие. После выполнения полного копирования, не поленитесь проверить, что бы всё было на своих местах!

Копирование. Способ 2
root@server:~# mkdir /mnt/rootfs
root@server:~# mount --bind / /mnt/rootfs
root@server:~# mount --bind /boot /mnt/rootfs/boot
root@server:~# mount --bind /home /mnt/rootfs/home
root@server:~# rsync -avPHAX /mnt/rootfs/* /mnt/raid1/

Здесь копирование выполняется одной командой, однако прежде следует воссоздать текущую корневую ФС в /mnt/rootfs посредством команд «mount —bind …»

На этом казалось бы всё закончено, но это не так. Пожалуй самым сложным шагом, которым нам предстоит сейчас сделать, это загрузить систему со свеженького ЖД, который уже содержит всё необходимое, за исключением верно настроенных загрузочных файлов. Если перезагрузить систему прямо сейчас, то вы окажетесь снова, в старой. А нам нужно высвободить первый «старый» диск, чтобы «вернуть» его в «битый» массив.

Автозагрузка

Мы воспользуемся маленькой хитростью, притворимся, что уже работаем в новой системе. Для того, чтобы выполнить «восстановление GRUB«, точнее автоматическую настройку.

root@server:~# mount --bind /dev /mnt/raid1/dev
root@server:~# mount --bind /proc /mnt/raid1/proc
root@server:~# mount --bind /sys  /mnt/raid1/sys
root@server:~# chroot /mnt/raid1

Установим загрузчик GRUB на втором диске, в качестве резервного, чтобы можно было загрузиться без первого диска

root@server:~# grub-install --recheck /dev/sdb

Обновим конфигурацию GRUB для последующего выполнения штатной загрузки со второго диска

root@server:~# update-grub

После выполнения этой команды, у вас скорее всего ещё останется возможность загрузки в старую систему. Её можно будет выбрать в загрузочном меню. Однако новая система будет на первом месте в списке, что собственно нам и нужно. Для уверенности в правильной автонастройке, просмотрите файл /boot/grub/grub.cfg. Вы должны найти там упоминания о новых разделах.

Кроме GRUB, необходимо поправить файл /etc/fstab. Внимательно проверьте каждую строчку. Узнать UUID разделов можно с помощью команды «blkid». А текущее положение дел, т.е. что, куда и как примонтировано, можно подсмотреть в файле /etc/mtab

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#                                              

# /boot was on /dev/md0 during installation
UUID=dc01d33c-0240-4597-9cfc-e2dc7a02865c       /boot   ext2    defaults                0       2
/dev/mapper/vg0-lv1                             /       ext4    errors=remount-ro       0       1
/dev/mapper/vg0-lv2                             /home   ext4    usrquota                0       2
/dev/mapper/vg0-lv0                             none    swap    sw                      0       0

Здесь показан пример, это значит, что он может отличаться от вашей конфигурации.

Перезагрузка

Чтобы загрузится в новую систему и завершить миграцию, необходимо перезагрузить сервер. По своему опыту, порекомендую под рукой держать загрузочный диск или флэшку, чтобы в случае каких либо ошибок, можно было оперативно их исправить. Так же обратите внимание, если вы работаете с удалённой машиной, особенно если она находится далеко от вас, будьте готовы к тому, что придётся кого-то просить о помощи, либо самому добираться до «незагрузившейся» машины.

Во имя святых Control, Alt и Delete, REBOOT!
Автор искренне надеется, что у вас всё получилось и система загрузилась, как и ожидалось.
Осталась «сервировка» и «подача на стол» нашего горячего блюда 🙂

Убедитесь, что первый диск (/dev/sda) более не используется, т.е. никуда не примонтирован.

Воскрешение
Клонируем таблицу разделов
root@server:~# sfdisk -d /dev/sdb | sfdisk --force /dev/sda
root@server:~# sfdisk --re-read
Восстанавливаем RAID 1

Добавляем в существующие массивы, недостающие разделы

root@server:~# mdadm --add /dev/md0 /dev/sda1
root@server:~# mdadm --add /dev/md1 /dev/sda2
root@server:~# watch cat /proc/mdstat

Теперь нам осталось только следить за синхронизацией

И всё теперь прекрасно и жизнь спокойна. Однако GRUB по прежнему считает, что на первом диске есть старая система. Чтобы его переубедить, выполним

root@server:~# update-grub

PS: Эта своеобразная инструкция основа на реальном опыте автора. За основу была взята эта статья.