Второй диск в зеркале 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. Если вы не знаете, как был установлен сервер, начните с выяснения этого, а не с покупки диска.
- zpool attach синхронизирует данные пула на новый диск и делает vdev зеркалом
- загрузчик, раздел EFI и BIOS boot partition находятся вне пула и сами не копируются
- способ сделать второй диск загрузочным зависит от дистрибутива и типа загрузки (UEFI или BIOS)
- проверка загрузки с каждого диска — обязательная часть работы, а не желательная
Что находится вне пула и почему загрузчик не зеркалируется
Возьмём схему разделов из руководства 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 или другого загрузчика вашего дистрибутива.
Как добавить второй загрузочный диск в зеркало на 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, поэтому номера разделов в командах выше для такой системы нужно поменять.
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 и бэкапов: диск, который тихо накапливает ошибки, лучше заменить до того, как придётся проверять зеркало в боевых условиях.
- zpool status: оба устройства ONLINE, ресильверинг закончен
- efibootmgr -v: есть записи загрузки для обоих дисков
- физическая загрузка с каждого диска по очереди в окно обслуживания
- после обновления загрузчика: синхронизация ESP на всех дисках
Кейс: сервер компании «Цветущий двор», 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 заставляет команду вернуться только после его завершения.
Источники
- OpenZFS: zpool-attach(8) — Синтаксис, ключи -f, -s, -w, превращение vdev в зеркало, требование к размеру нового устройства: https://openzfs.github.io/openzfs-docs/man/master/8/zpool-attach.8.html
- OpenZFS: Debian Bookworm Root on ZFS — Разметка sgdisk, bpool и rpool в зеркале, grub-install для каждого диска, копирование ESP через dd и efibootmgr: https://openzfs.github.io/openzfs-docs/Getting%20Started/Debian/Debian%20Bookworm%20Root%20on%20ZFS.html
- OpenZFS: Ubuntu 22.04 Root on ZFS — compatibility=grub2 для bpool, особенности /boot/grub в зеркале, dpkg-reconfigure grub-efi-amd64: https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04 %20Root%20on%20ZFS.html
- OpenZFS: zpoolprops(7) — Свойства bootfs, autoexpand, autoreplace, compatibility: https://openzfs.github.io/openzfs-docs/man/master/7/zpoolprops.7.html
- Proxmox VE Wiki: ZFS on Linux — Раздел замены загрузочного устройства: sgdisk -R и -G, proxmox-boot-tool format и init: https://pve.proxmox.com/wiki/ZFS_on_Linux
- FreeBSD Handbook: ZFS — Присоединение зеркала и gpart bootcode для нового диска: https://docs.freebsd.org/en/books/handbook/zfs/



