ServerAdmin.ru
31K subscribers
573 photos
46 videos
22 files
2.83K links
Авторская информация о системном администрировании.

Информация о рекламе: @srv_admin_reklama_bot
Автор: @zeroxzed

Второй канал: @srv_admin_live
Сайт: serveradmin.ru

Регистрация в РКН: https://vk.cc/cG1Urj
Download Telegram
В ОС на базе Linux существуют несколько наиболее популярных программных решений для построения отказоустойчивого дискового хранилища, или по простому - софтовых рейдов:

◽️Mdadm
◽️LVM Raid
◽️ZFS

Про Mdadm рассказывать особо нечего. Это самый популярный программный рейд, которому сто лет в обед. Он очень прост в настройке и эксплуатации, про него масса статей с инструкциями. Я использую его повсеместно и проблем с ним никогда не знал. Много писал про него на канале.

Про ZFS тоже рассказывать большого смысла нет. Известная и проверенная временем технология. Я ещё на Freebsd её использовал и очень радовался, когда корень системы можно было поставить на ZFS. Она спокойно переживала аварийные выключения сервера, в отличие от UFS, которая была файловой системой по умолчанию и постоянно ломалась после аварийных отключений.

А вот про LVM Raid и информации немного, и практического применения я не видел. Мне не очень понятно, почему. Я немного поигрался с этим рейдом на тестах. Выглядит интересно. Сразу скажу, почему я решил обратить на него внимание. LVM Raid поддерживает технологию DM-integrity (device mapper integrity), с помощью которой можно контролировать целостность хранимой информации с помощью дополнительного хранения и проверки метаданных (checksum) файлов. Это то, что ZFS делает по умолчанию. Поясню, зачем это надо.

В современных дисках, как HDD, так и SSD, очень высокая плотность записи. Это делает сохранение заряда в ячейках менее надёжным и долговременным. Допустим, у вас на дисках долго хранится какой-то объём информации. В каких-то ячейках изменились записанные биты либо из-за ошибок при записи, либо возникли во время хранения. При этом диски полностью исправны и ошибок чтения нет. То есть технически всё в порядке. Но во время чтения вы можете получить битые файлы, которые при этом успешно прочитаются. Но информация будет разрушена.

При использовании Mdadm и поверх него ФС EXT4 или XFS, никакой защиты от подобных ошибок у вас не будет. Если не делать регулярное сопоставление записанных файлов с каким-то другим хранилищем таких же файлов, то о битых файлах вы не узнаете, пока явно не наткнётесь на них во время проверки. В LVM Raid с поддержкой DM-integrity часть хранилища выделяется под хранение метаданных файлов. Я не нашёл точно информации, сколько конкретно % от общего объёма тратится. Но там немного, не более 10%.

При использовании LVM Raid + DM-integrity вы узнаете о битых файлах при очередной проверке файлов с тем, что записано ранее в хранилище метаданных. Это происходит как минимум во время чтения. Я так понимаю, что процесс этот может происходить и в фоне, можно и принудительно запускать и смотреть результаты. CLI от LVM даёт такие возможности. При обнаружении повреждённых файлов, они будут автоматически восстановлены с других носителей в рейд массиве.

Хотел сделать заметку с примерами создания и управления LVM Raid, но сделаю это позже отдельной заметкой в виде готовой шпаргалки. Вводная теоретическая часть получилась слишком длинной.

Если кто-то использовал LVM Raid, поделитесь опытом и впечатлениями. Особенно интересно, если дополнительно включали DM-integrity. Без неё я не вижу смысла использовать рейд LVM, а не Mdadm. LVM хоть и даёт бОльшую гибкость в управлении. Например, можно на лету изменить уровень рейда, увеличить или уменьшить тома. Но на практике это не особо нужно. Mdadm проще и более предсказуем, интуитивен в управлении. Технически DM-integrity можно включить и для дисков в составе Mdadm, но там нет нативной поддержки, как в LVM. Битые файлы будут помечаться как ошибки чтения диска и Mdadm будет пытаться их синхронизировать с других дисков. Это тоже рабочий вариант, но не такой удобный в плане управления и отслеживания ошибок.

#lvm #raid
Шпаргалка на тему создания LVM Raid. Создаём RAID1.

# apt install lvm2
# pvcreate /dev/sdb /dev/sdc
# vgcreate vgroup /dev/sdb /dev/sdc
# lvcreate --type raid1 -l 100%FREE -n lvraid1 vgroup

Проверяем:

# lvs -o+segtype

Создаём файловую систему и монтируем:

# mkfs.ext4 /dev/vgroup/lvraid1
# mkdir /mnt/lvraid1
# mount /dev/vgroup/lvraid1 /mnt/lvraid1

Смотрим, что в итоге получилось:

# lsblk

Скопируем туда что-нибудь, дождёмся полной синхронизации и удалим один из дисков.

# cp -r /var/log/* /mnt/lvraid1/

Диск отключил. Проверяю данные, всё на месте. То есть LV работает как и прежде. Проверяю статус:

# lvs -a -o name,devices vgroup

Вижу, что одно устройство в статусе [unknown]. Добавляю в систему новый диск. Не тот же самый, что я отключил.

# lsblk

Вижу, что он подключился на /dev/sdd. Добавляю его в VG:

# pvcreate /dev/sdd
# vgextend vgroup /dev/sdd

Удаляем вывалившийся диск:

# vgreduce --removemissing vgroup --force

Проверяем:

# lvs -a -o name,devices vgroup

Устройства в статусе [unknown] больше нет. Добавляем в наш LV новый диск:

# lvconvert --repair vgroup/lvraid1
# lvconvert -m1 vgroup/lvraid1 /dev/sdd

На все вопросы отвечаем утвердительно. Смотрим результат и наблюдаем за синхронизацией:

# lvs -a -o name,devices vgroup
# lvs -o+segtype

Пошла синхронизация, данные все на месте. Замена прошла без остановки системы. Диски убирал и добавлял наживую. В целом, ничего сложного. Вполне понятный и логичный набор команд. Один раз проверил, записал и воспроизвёл в случае выхода из строя диска.

Из особенностей LVM Raid - LV можно конвертировать налету в разные уровни рейдов, добавлять к ним диски. Можно из raid1 сделать raid5, добавить туда диски. Не думаю, что на практике это будет оправданно. А вот превратить raid1 в raid10 видится полезным. Было 2 диска, добавил ещё 2 и получил raid10. Для этого надо добавить 2 диска в VG и сконвертировать LV. Прямой конвертации из raid1 в raid10 нет. Нужно сначала сконвертировать в raid5, добавить туда 2 диска, дождаться синхронизации и сконвертировать в raid10:

# pvcreate /dev/sdc /dev/sde
# vgextend vgroup /dev/sdc /dev/sde
# lvconvert --type raid5_n vgroup/lvraid1
# lvresize -l5118 vgroup/lvraid1 # размер зависит от размера LV
# lvconvert --stripes 1 vgroup/lvraid1
# lvconvert --stripes 2 vgroup/lvraid1
# lvconvert --type raid10 vgroup/lvraid1
# lvconvert --type raid10 vgroup/lvraid1

На выходе получил из RAID1 ⇨ RAID10 без остановки и потери данных. Я по всем этим командам получал подсказки в консоли. Там и по размеру подсказки были, и по тому, что финальная конвертация проходит в 2 этапа, и что сначала надо в raid5_n сконвертировать.

Если делать с нуля RAID10, то команда простая. Сначала добавляем 4 одинаковых диска в VG, потом создаём LV:

# lvcreate --type raid10 -l 100%FREE -n lvraid10 vgroup

А теперь ради чего всё это затевалось. LVM Raid умеет вести контроль целостности файлов на основе хэшей. Реализуется это на базе технологии DM Integrity. Включаем её во время создания LV:

# lvcreate --type raid1 --raidintegrity y -L 9G -n lvraid1 vgroup

Размер нужно будет вычислять опытным путём. Я сначала указал размер 100% и получил ошибку, что для моих 10G дисков нужно 150 MiB под метаданные. В итоге указал 9G.

Если в VG есть свободное место, то добавить raidintegrity можно к существующему тому:

# lvconvert --raidintegrity y vgroup/lvraid1

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

Для каждого диска в составе LV с DM Integrity создаётся отдельный LV rimage для хранения метаданных. В нём можно посмотреть статистику по ошибкам:

# lvs -o+integritymismatches vgroup/lvraid1_rimage_0_imeta

Колонка IntegMismatches. Все события по DM Integrity будут в системном логе /var/log/syslog.

Всё, что я показал, подробно описано в руководстве по LVM от Red Hat.

#lvm #raid
Продолжу тему с LVM Raid, чтобы получить законченное решение, которое можно будет использовать в проде. Я хочу установить корень системы / на LVM Raid, чтобы в случае выхода из строя диска иметь полностью работающую систему.

Для этого взял виртуалку с Debian 12 и установил систему с ручным разбитием диска. Создал ровно один раздел /dev/sda1, на нём создал VG - vgroup и один LV - root на весь доступный объём. Больше не делал ничего. Раздел /boot не выносил отдельно. Всё только в корне. Grub уже давно умеет грузиться с LVM разделов.

Установил систему. Добавил туда ещё один диск /dev/sdb. Скопировал на него разметку с sda и добавил его в VG:

# sfdisk -d /dev/sda | sfdisk /dev/sdb
# pvcreate /dev/sdb1
# vgextend vgroup /dev/sdb1

Пробую сконвертировать корневой раздел в RAID1:

# lvconvert --type raid1 -m 1 vgroup/root

Получаю ошибку:

Insufficient free space: 1 extents needed, but only 0 available

Суть её в том, что при создании любого RAID необходимо создать отдельный малюсенький LV на 4 MiB для хранения метаданных массива. А я полностью весь VG во время установки отдал на LV root. Чтобы избежать этой ошибки, оставляйте во время установки немного места на VG.

Решить эту проблему не трудно. LV можно уменьшить вместе с ФС, если это ext4:

# lvreduce -l -1 --resizefs /dev/vgroup/root

Команда сработает, только если раздел размонтирован. А у меня это корень системы, так что получил ошибку. Решение простое. Загрузился с SystemRescueCD и выполнил её там. Откусил кусочек от LV, теперь конвертирую в RAID1:

# lvconvert --type raid1 -m 1 vgroup/root

Всё проходит без ошибок. Загружаю систему, проверяю массив:

# lvs -o+segtype
# lvs -a -o name,devices vgroup

Всё в порядке, оба диска на месте. Ставлю загрузчик на второй диск sdb:

# dpkg-reconfigure grub-pc

Теперь вынимаю первый диск sda, на который изначально ставилась система и перезагружаю её. Grub запускается со второго диска, а дальше вываливаюсь в initramfs. Система не грузится, пишет, что не видит диск /dev/mapper/vgroup-root. В консоли initramfs ввожу команду на активацию всех lvm томов:

# vgchange -ay

Находит VG vgroup, но ругается, что там нет sda. Логично, диск этот отключен. После этого выхожу из initramfs:

# exit

Так как LVM раздел активирован, грузится система со второго диска. То есть в целом всё в порядке. Система жива, загружается. Надо только разобраться с тем, чтобы initramfs автоматически активировал неактивный VG с raid1.

Как оказалось, проблема эта нередкая. Нашёл решение в интернете. Создаём файл /etc/initramfs-tools/scripts/local-top/forcelvm следующего содержания:

#!/bin/sh

PREREQ=""
prereqs()
  {
    echo "$PREREQ"
  }
case $1 in
  prereqs)
  prereqs
  exit 0
   ;;
  esac
. /scripts/functions
lvm vgchange -ay


Пересобираем initramfs:

# chmod +x /etc/initramfs-tools/scripts/local-top/forcelvm
# update-initramfs -u -k all

Перезагружаемся. Теперь загрузка работает нормально. Что с одним, что с двумя дисками.

Заменяем выключенный диск новым. Смотрим, какие диски есть в системе:

# lsblk

У меня с данными диск стал sda, новый sdb. Копирую на него разметку, добавляю в VG и LV с raid1:

# sfdisk -d /dev/sda | sfdisk /dev/sdb
# pvcreate /dev/sdb1
# vgextend vgroup /dev/sdb1
# vgreduce --removemissing vgroup --force
# lvconvert --repair vgroup/root
# lvconvert -m1 vgroup/root /dev/sdb1

Ставим загрузчик на новый диск:

# dpkg-reconfigure grub-pc

Следим за синхронизацией:

# watch lvs -a

Когда закончится, перезагружаем систему и убеждаемся, что всё работает.

Получилась готовая инструкция по установке системы на LVM Raid1 и по замене вышедшего из строя диска. В целом, всё примерно то же самое, что и в mdadm со своими нюансами. При случае попробую на каком-нибудь железном сервере вместо mdadm - LVM. На вид выглядит удобнее и функциональнее.

❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.

#lvm #raid