Будет ли загрузочным зеркальный диск в zpool: ESP, GRUB
АйТи Фреш
Серверы и инфраструктура

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

Автор: , директор ООО «АйТи-Фреш» · · ~14 мин чтения
Два SSD в зеркале ZFS: данные скопированы, а загрузчик остался только на первом диске
Зеркало копирует данные пула, но не загрузчик.

Нет, не будет. Команда zpool attach превращает диск в зеркало данных, но загрузчик лежит вне пула, и сам он на второй диск не попадёт. Нужно повторить разметку, скопировать ESP или поставить GRUB, а потом проверить загрузку. Ниже — порядок для Debian, Ubuntu, Proxmox VE и FreeBSD и разбор из моей практики.

Будет ли загрузочным второй диск после zpool attach

Вопрос приходит ко мне регулярно, обычно в такой форме: «У нас на сервере один SSD с ZFS, купили второй, сделали zpool attach, пул стал mirror. Если первый умрёт, сервер поднимется?» Отвечаю прямо: не факт, а чаще всего нет. Зеркало в ZFS защищает данные внутри пула. Загрузчик, раздел EFI и служебные разделы в пул не входят, поэтому zpool attach их не трогает. Такими вещами мы занимаемся в рамках ИТ-аутсорсинга для небольшой компании, и этот сценарий я видел и на старых серверах, и на свежих установках.

Что делает команда, написано в официальной справке OpenZFS. Если vdev не зеркальный, то при zpool attach он автоматически превращается в двухстороннее зеркало из старого и нового устройства, а новое устройство сразу начинает ресильверинг. Про загрузку в этой справке ничего нет, и это логично: ZFS отвечает за блоки внутри пула, а не за то, что прошивка читает с диска в первую очередь. Прошивка (UEFI или BIOS) ищет загрузчик на разделе с FAT или в области перед первым разделом, а не внутри ZFS.

Отсюда простое правило, которое я повторяю клиентам. Зеркальный пул и зеркальная загрузка — две разные задачи. Первая решается одной командой. Вторая состоит из нескольких шагов, и они зависят от способа установки: Debian или Ubuntu по руководству OpenZFS, Proxmox VE со своим proxmox-boot-tool, FreeBSD с gpart. Если вы не знаете, как был установлен сервер, начните с выяснения этого, а не с покупки диска.

Что находится вне пула и почему загрузчик не зеркалируется

Возьмём схему разделов из руководства OpenZFS Root on ZFS для Debian. Для UEFI там создаётся раздел 2 размером 512 МиБ с типом EF00, раздел 3 на 1 ГиБ с типом BF01 под загрузочный пул bpool и раздел 4 на остаток диска с типом BF00 под корневой пул rpool. Для старой загрузки BIOS добавляется ещё раздел 1 с типом EF02 для GRUB. Видно главное: на диске четыре раздела, а ZFS-зеркалом становятся только третий и четвёртый. Раздел с EFI и раздел BIOS boot остаются обычными разделами, которые нужно заполнить отдельно.

Отдельный загрузочный пул bpool в этой схеме — не прихоть. По тексту руководства, его создают с ограничением функций теми, которые поддерживает GRUB, через параметр compatibility=grub2. Это значит, что на bpool не стоит бездумно включать новые функции командой zpool upgrade: GRUB может перестать читать такой пул. Параметр compatibility в справке описан так: пул остаётся совместимым с заданным набором функций. Для корневого пула rpool такого ограничения нет, там GRUB ничего не читает.

Есть ещё свойство пула bootfs, в нём записан загрузочный набор данных корневого пула. В справке сказано, что его в основном выставляют программы установки и обновления, а не все загрузочные цепочки Linux его вообще используют. Поэтому, глядя на zpool get bootfs, не делайте выводов о том, что именно будет загружено: проверяйте конфигурацию GRUB или другого загрузчика вашего дистрибутива.

Если при создании пула передать ZFS целый диск вместо раздела, он разметит диск по-своему. Руководство OpenZFS прямо предупреждает: без указания раздела -part4 ZFS перераспределит диск, и вы потеряете разделы загрузчика. Для нового диска в зеркало разметку делайте сами и передавайте в пул именно разделы.
Схема разделов загрузочного диска ZFS: bpool и rpool в зеркале, ESP и BIOS boot вне пула
В зеркало попадают только разделы пула, остальное делается вручную.

Как добавить второй загрузочный диск в зеркало на Debian и Ubuntu

Порядок для системы, установленной по руководству OpenZFS, у меня такой. Сначала смотрим, что есть: lsblk и zpool status. Убеждаемся, что номера разделов совпадают со схемой выше (ESP — второй, bpool — третий, rpool — четвёртый). Если установка была нестандартной, ориентируйтесь на ваш реальный вывод, а не на мои номера. Новый диск должен быть не меньше самого маленького диска в vdev: это прямо требование справки zpool attach. Если модель и размер другие, не копируйте таблицу разделов вслепую, а создайте разделы командами sgdisk из руководства.

Для диска того же размера таблицу разделов можно скопировать так, как это описано в вики Proxmox VE: sgdisk с ключом -R копирует разметку с исправного диска на новый, а -G выдаёт новому диску свежие GUID. Затем присоединяем разделы к пулам. Путь к существующему разделу указывайте так, как он записан в выводе zpool status, а новый раздел лучше брать из /dev/disk/by-id. Ключ -w заставит команду дождаться окончания ресильверинга.

OLD=/dev/disk/by-id/ata-SSD_OLD
NEW=/dev/disk/by-id/ata-SSD_NEW

sgdisk $OLD -R $NEW
sgdisk -G $NEW
udevadm settle

zpool attach -w bpool ${OLD}-part3 ${NEW}-part3
zpool attach -w rpool ${OLD}-part4 ${NEW}-part4
zpool status

Теперь загрузчик. Для UEFI руководство OpenZFS предлагает скопировать раздел ESP побайтово и добавить запись в менеджер загрузки. Для второго диска имя записи заменяем на debian-2, для третьего — на debian-3 и так далее. Разделы указаны по именам /dev/disk/by-id, как в руководстве.

umount /boot/efi
dd if=${OLD}-part2 of=${NEW}-part2
efibootmgr -c -g -d $NEW -p 2 -L "debian-2" -l '\EFI\debian\grubx64.efi'
mount /boot/efi

Для старой загрузки BIOS путь короче: grub-install на новый диск целиком, не на раздел. В руководстве сказано повторить grub-install для каждого диска пула, а после первой загрузки можно выполнить dpkg-reconfigure grub-pc и отметить все диски пула, именно диски, не разделы. Для UEFI-зеркала в руководстве Ubuntu есть аналогичная подсказка: dpkg-reconfigure grub-efi-amd64 и выбор всех разделов ESP, чтобы обновления GRUB шли на все диски. Учтите, что в схеме руководства Ubuntu ESP — первый раздел на каждом диске, а не второй, как в Debian, поэтому номера разделов в командах выше для такой системы нужно поменять.

Пошаговый чек-лист добавления второго загрузочного диска в зеркало ZFS на Debian
Загрузчик ставится после ресильверинга и проверяется физической загрузкой.

Proxmox VE и FreeBSD: свои правила для загрузочного зеркала

На Proxmox VE всё устроено иначе, и копировать ESP через dd там не нужно. В вики Proxmox описана замена загрузочного устройства: сначала проверяем, чем загружается система, командой proxmox-boot-tool status. Общие шаги те же — sgdisk -R, sgdisk -G и затем замена или присоединение ZFS-раздела. После этого раздел ESP нового диска форматируем и инициализируем средствами самого инструмента: proxmox-boot-tool format и proxmox-boot-tool init. Если статус показывает, что диски загружаются через GRUB, особенно при включённом Secure Boot, в init передаётся режим grub.

proxmox-boot-tool status
proxmox-boot-tool format <ESP нового диска>
proxmox-boot-tool init <ESP нового диска> grub

Последняя команда с grub нужна не всегда: если status показывает systemd-boot, режим не указывают. Вики также отмечает, что при установке из инсталлятора Proxmox VE начиная с 5.4 раздел ESP на загрузочных дисках идёт вторым. Чистый grub-install без proxmox-boot-tool, по тексту вики, остался только на системах, установленных на Proxmox VE 6.3 и более ранних версий и не переведённых на новый инструмент. Если у вас именно так, на новом диске выполняют grub-install.

FreeBSD решает задачу ещё проще, но тоже вручную. В руководстве FreeBSD для присоединения зеркала показан zpool attach, после которого на новый диск записывается загрузочный код: gpart bootcode с файлами /boot/pmbr и /boot/gptzfsboot и ключом -i 1. Там же предупреждение, которое стоит запомнить: перед перезагрузкой дождитесь окончания ресильверинга. Пример в руководстве рассчитан на диск с таблицей GPT и загрузкой через BIOS. Для EFI-системы схема отличается, поэтому сверьтесь с разделом Root-on-ZFS вашей версии.

zpool attach mypool ada0p3 ada1p3
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

Как проверить, что сервер загрузится со второго диска

Проверка делается в три прохода. Первый — состояние пула: в zpool status оба диска должны быть ONLINE, а ресильверинг завершён. Для имён устройств полезны ключи -P и -L: первый показывает полные пути, второй разворачивает символические ссылки в реальные блочные устройства, и вы видите, какой физический диск стоит за записью. Второй проход — загрузчик: efibootmgr -v покажет записи менеджера загрузки, и среди них должны быть записи для обоих дисков. Для Proxmox выводит статус proxmox-boot-tool status: в нём перечислены все ESP, настроенные для синхронизации.

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

Ещё одна вещь, которая ломает уже работающую схему: обновления. ESP лежит вне пула, поэтому после обновления GRUB или ядра синхронизируются не все копии. На Debian и Ubuntu это решает dpkg-reconfigure с выбором всех разделов ESP, о котором я писал выше. На Proxmox эту работу берёт на себя proxmox-boot-tool, но статус всё равно стоит смотреть после крупных обновлений. Следить за самим состоянием дисков помогает мониторинг SMART и бэкапов: диск, который тихо накапливает ошибки, лучше заменить до того, как придётся проверять зеркало в боевых условиях.

Сравнение до и после: один SSD против зеркала ZFS с загрузкой с обоих дисков
После работ отказ одного SSD не останавливает всех сотрудников.

Кейс: сервер компании «Цветущий двор», 27 рабочих мест

Озеленительная компания «Цветущий двор» держит на одном физическом сервере файловые ресурсы для 27 рабочих мест, проектную документацию и сметы. Система стояла на Debian 12 с корневым пулом на одном SATA SSD объёмом 480 ГБ. Занято было порядка 140 ГБ. Директор давно знал, что диск один, и попросил «поставить зеркало». Я начал с проверки: lsblk показал разметку по схеме OpenZFS с ESP на втором разделе, bpool на третьем и rpool на четвёртом. Загрузка UEFI. Это был лучший из возможных вариантов: порядок действий известен и описан.

Мы купили второй SSD той же модели и ёмкости и в пятницу вечером выполнили всё по схеме из третьего раздела: копирование таблицы разделов, присоединение разделов к bpool и rpool, копирование ESP и запись в efibootmgr. Само присоединение заняло около десяти минут, ресильверинг rpool при таких объёмах — примерно двадцать пять, и только после его окончания мы вернулись к загрузчику. Основную работу вместе с проверками закончили за час сорок минут. Про общие принципы организации хранилища на ZFS для такого сервера я писал в разборе файлового сервера на ZFS, здесь же речь только о загрузке.

Итог проверили в воскресенье, как положено, физической загрузкой. Сначала загрузили сервер с нового диска через меню прошивки, затем со старого. В обоих случаях система поднялась, пул rpool показывал нужное состояние. После этого в плановые работы мы добавили разовую проверку статуса пула после обновления ядра и настроили оповещение, если один из дисков уходит из ONLINE. Для директора результат выглядит просто: один отказавший SSD больше не означает простой всех 27 рабочих мест, а замену можно планировать, а не делать в аврале. Копии данных при этом остаются обязательными, зеркало их не заменяет, о чём ниже.

Типичные ошибки и что зеркало не защищает

Первая ошибка — путаница между zpool attach и zpool add. Attach присоединяет устройство к существующему vdev и делает зеркало. Add добавляет новый отдельный vdev в пул, и вместо зеркала вы получаете расширение пула без избыточности. Из-за этой опечатки я видел случаи, когда админ добавлял диск «для надёжности», а получил ещё одну точку отказа. Перед запуском проверяйте команду глазами и читайте вывод zpool status после неё. Если после команды в дереве устройств у корня пула стоят два отдельных диска, а не слово mirror, это не зеркало.

Вторая ошибка — передать в пул диск целиком. Руководство OpenZFS предупреждает, что без указания раздела ZFS перераспределит диск, и вы потеряете разделы загрузчика. Третья — забыть про ESP после установки обновлений. Четвёртая — надеяться на свойство autoreplace: оно по умолчанию выключено, и, пока вы его не включили, замену нужно запускать вручную командой zpool replace. Включённый autoexpand тоже про другое: он касается роста диска, а не загрузки, подробности я разбирал в статье про autoexpand и zpool online -e.

И главное: зеркало не бэкап. Оно честно скопирует на второй диск удалённый файл, ошибку администратора и результат работы шифровальщика. Загрузочное зеркало закрывает сценарий отказа диска и не закрывает сценарии с данными. Поэтому рядом с ним всегда должна быть копия по правилу 3-2-1. Если сервер важен для бизнеса, добавьте проверку восстановления, а не только факт создания копии.

Частые вопросы

Будет ли загрузочным зеркальный диск в zpool?

Не автоматически. zpool attach копирует данные пула, а загрузчик (ESP, BIOS boot partition, код загрузки) лежит вне пула. Его нужно установить на новый диск отдельно и проверить загрузку.

Как сделать второй диск зеркала загрузочным на Debian или Ubuntu?

Повторить разметку, присоединить разделы bpool и rpool через zpool attach, на UEFI скопировать ESP и добавить запись efibootmgr, на BIOS выполнить grub-install на новый диск. Команды приведены в статье.

Что делать на Proxmox VE при добавлении загрузочного диска?

Скопировать разметку через sgdisk -R и sgdisk -G, присоединить ZFS-раздел, затем выполнить proxmox-boot-tool format и init для ESP нового диска. Режим grub указывают, если status показывает загрузку через GRUB.

Чем zpool attach отличается от zpool add?

attach делает устройство зеркалом существующего vdev. add добавляет в пул новый отдельный vdev, избыточности это не даёт. Для зеркала нужен именно attach.

Нужно ли ждать окончания ресильверинга перед перезагрузкой?

Да. Руководство FreeBSD прямо предупреждает дождаться окончания ресильверинга. Ключ -w у zpool attach заставляет команду вернуться только после его завершения.

Столкнулись с похожей задачей? Обращайтесь — решим

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

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи