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

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

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

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

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

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

Прежде чем приступить, обязательно установите в систему следующие пакеты: mdadm, lvm2, parted

Очистка

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

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 --metadata=0.90 --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 >

Обычно после этих операций, информация о существующих массивах сохраняется в /etc/mdadm/mdadm.conf. Это нужно проверить. В случае отсутствия информации про новые массивы, следует это исправить

root@server:~# mdadm --detail --scan >> /etc/mdadm/mdadm.conf
LMV

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

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

root@server:~# pvcreate /dev/md1

Создадим группу томов из одного PV раздела с именем, например, «system»

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

На старых системах, после этого, нужно было активировать группу

root@server:~# vgchange -a y system

 

Создадим логические тома

Под SWAP: размер 2GiB, наименование: swap, в группе: system

root@server:~# lvcreate -L2g -nswap system

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

root@server:~# lvcreate -L20g -nroot system

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

root@server:~# lvcreate -L50g -nhome system

Наименование группы «system» и логических томом «swap, root, home», можно сменить на более удобные для вас. Практика показала, что название группы, где будут системные разделы, лучше называть так же как и хост (имя машины), другие группы соответственно по их назначению. Важно помнить, что название группы сохраняется так же, как и метка диска. Однако, в дальнейшем названия групп можно сменить.

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

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

root@server:~# mkswap /dev/system/swap

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

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

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

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

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

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

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

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

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

root@server:~# mount /dev/system/root /mnt/raid1/

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

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

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

root@server:~# mkdir /mnt/raid1/home
mount /dev/system/home /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/system-root                         /       ext4    errors=remount-ro       0       1
/dev/mapper/system-home                         /home   ext4    usrquota                0       2
/dev/mapper/system-swap                         none    swap    sw                      0       0

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

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

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

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

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

Воскрешение
Клонируем таблицу разделов
root@server:~# sfdisk -d /dev/sdb | sfdisk --force /dev/sda
root@server:~# partprobe
Восстанавливаем 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: Эта своеобразная инструкция основа на реальном опыте автора. За основу была взята эта статья.