Привет, товарищь! Решил поделиться опытом, как я настраивал отказоустойчивость на своём сервере. После скоропостижной смерти M2 SSD со всеми конфигами домашней лаборатории мне пришлось начать собрать её заново. Так что если у тебя тоже есть два одинаковых SSD и ты хочешь, чтобы система продолжала работать при отказе одного из них, этот гайд про то как сразу делать по уму точно для тебя.

Почему я выбрал mdadm

Есть два основных пути: mdadm и LVM RAID. Я остановился на mdadm. Для нашей задачи это проще и прозрачнее. LVM даёт крутую гибкость в управлении томами, но если нужна именно защита от смерти диска, mdadm справляется лучше. Восстановление после сбоя понятнее, мониторинг проще, и меньше шансов запутаться в конфигурации.

Важный нюанс про EFI

Тут есть подвох. UEFI не умеет загружаться с mdadm массивов. Поэтому EFI разделы нельзя объединять в RAID. Я оставил их отдельными на каждом диске. Просто синхронизирую содержимое вручную через rsync. Это небольшая плата за возможность загрузки с любого диска.

В самом инсталляторе Ubuntu я не догадался выделить отдельный раздел для EFI, чтобы правильно разбить диски при устанвоке. Так что я поставил систему целиком на один диск, а потом на втором создал программный RAID 1, перенёс данные и после этого добавил в RAID первый диск.

Пошаговая инстуркция

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

1
2
3
4
5
lsblk -f
# Показывает структуру дисков и файловые системы

sudo fdisk -l | grep "Disk /dev/sd"
# Находим второй диск для RAID. Я ориентировался по размеру.

Установил mdadm:

1
2
3
sudo apt update
sudo apt install mdadm
# Устанавливаем утилиту управления RAID массивами. В убунте она по-умолчанию уже есть.

Скопировал таблицу разделов с первого диска на второй:

1
2
sudo sfdisk -d /dev/sda | sudo sfdisk /dev/sdb
# Копируем структуру разделов с sda на sdb

Создал RAID1 массив. Важный момент - создавал в деградированном режиме, чтобы не затереть работающую систему:

1
2
3
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb2 missing
# Создаём массив пока только с одним диском (sdb2)
# Второй диск (sda2) добавим позже

Отформатировал и скопировал данные:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sudo mkfs.ext4 /dev/md0
# Создаём файловую систему на новом RAID массиве

sudo mkdir -p /mnt/new-root
sudo mount /dev/md0 /mnt/new-root
# Монтируем новый массив

sudo rsync -axHAWX --numeric-ids --info=progress2 \
  --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run --exclude=/tmp \
  / /mnt/new-root/
# Копируем все данные с сохранением прав и атрибутов
# Исключаем виртуальные файловые системы

Подготовил chroot и обновил конфигурацию:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Монтируем необходимые директории для chroot
for dir in /dev /dev/pts /proc /sys /run; do
    sudo mount --bind $dir /mnt/new-root$dir
done

# Монтируем EFI раздел
sudo mount /dev/sda1 /mnt/new-root/boot/efi

# Заходим в систему
sudo chroot /mnt/new-root

# Внутри chroot обновляем fstab
sed -i 's|/dev/sda2|/dev/md0|g' /etc/fstab
# Меняем корневой раздел с sda2 на md0

# Добавляем конфигурацию mdadm
mdadm --detail --scan >> /etc/mdadm/mdadm.conf

# Обновляем initramfs чтобы RAID собрался при загрузке
update-initramfs -u -k all

# Переустанавливаем GRUB
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Ubuntu --recheck
update-grub

# Выходим из chroot
exit

Отмонтировал и перезагрузился для проверки:

1
2
3
sudo umount -R /mnt/new-root
sudo reboot
# Перезагружаемся - система должна загрузиться с RAID

После успешной загрузки добавил оригинальный диск в массив:

1
2
3
4
5
6
sudo mdadm /dev/md0 --add /dev/sda2
# Добавляем sda2 в массив - начнётся синхронизация

watch cat /proc/mdstat
# Следим за прогрессом синхронизации
# Это может занять от одного до четрёх  часов. У меня чуть больше часа заняло.

Настроил второй EFI раздел:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
sudo mkfs.vfat -F 32 -n EFI /dev/sdb1
# Форматируем EFI раздел второго диска в FAT32

sudo mkdir -p /boot/efi2
sudo mount /dev/sdb1 /boot/efi2
# Монтируем второй EFI раздел

sudo rsync -a /boot/efi/EFI/ /boot/efi2/EFI/
# Копируем файлы загрузчика

sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi2 --bootloader-id=Ubuntu /dev/sdb
# Устанавливаем GRUB на второй диск

sudo umount /boot/efi2

Настроил уведомления:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sudo apt install postfix
# Устанавливаем почтовый сервер
# При настройке выбираем "Local only"

sudo nano /etc/mdadm/mdadm.conf
# Добавляем строку: MAILADDR username. Где username это ник твоей учтёки.

sudo systemctl enable --now mdmonitor
# Включаем мониторинг RAID массивов

sudo mdadm --monitor --test --oneshot /dev/md0
# Тестируем отправку уведомлений

Как проверить что всё работает

После настройки прогони несколько команд для спокойствия:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
cat /proc/mdstat
# В строке md0 должны быть две буквы U в скобках [UU]
# Это значит что оба диска активны и синхронизированы

sudo mdadm --detail /dev/md0
# State должно быть active
# Working Devices должно быть равно 2

df -h | grep " / "
# Корневая файловая система должна быть на /dev/md0

sudo efibootmgr -v
# Проверяем что запись Ubuntu есть в списке загрузочных устройств

cat /etc/mdadm/mdadm.conf | grep ARRAY
# Проверяем что конфигурация массива сохранена

Что делать после обновления ядра

После apt upgrade файлы загрузчика обновляются только на основном EFI разделе. Нужно вручную синхронизировать второй диск:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sudo mkdir -p /boot/efi2
sudo mount /dev/sdb1 /boot/efi2
# Монтируем второй EFI раздел

sudo rsync -a /boot/efi/EFI/ /boot/efi2/EFI/
# Синхронизируем файлы загрузчика

sudo grub-install --target=x86_64-efi --efi-directory=/boot/efi2 --bootloader-id=Ubuntu /dev/sdb
# Обновляем GRUB на втором диске

sudo umount /boot/efi2

Я добавил эти команды в скрипт /usr/local/bin/sync-efi.sh и если не забуду про его существоавание, то буду запускать его после обновлений. Занимает минуту, зато спокойнее.

Что делать при сбое диска

Если пришло уведомление о проблеме, сначала проверь статус массива:

1
2
3
cat /proc/mdstat
sudo mdadm --detail /dev/md0
# Проверяем какой диск вышел из строя

Если диск помечен как failed, действуй по плану:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sudo mdadm /dev/md0 --fail /dev/sdX2 --remove /dev/sdX2
# Отмечаем диск как неисправный и удаляем из массива
# Замените sdX2 на имя проблемного раздела

# После физической замены диска добавляем новый:
sudo mdadm /dev/md0 --add /dev/sdX2
# Добавляем новый диск в массив

watch cat /proc/mdstat
# Следим за восстановлением
# Система продолжает работать во время синхронизации

Важные заметки на будущее

RAID это не бэкап. Он защищает от отказа железа, но не от случайного удаления файлов или вирусов. Настрой отдельное резервное копирование критичных данных.

Сохрани вывод efibootmgr в файл:

1
2
sudo efibootmgr -v > ~/efiboot-backup.txt
# Это поможет восстановить загрузочные записи если настройки UEFI сбросятся

Не прерывай синхронизацию массива. Это может повредить данные.

Итог

Настройка заняла пару часов включая время на синхронизацию дисков. Теперь сервер защищён от выхода из строя одного из SSD. Если хочешь сделать так же и возникнут вопросы - пиши, помогу разобраться.