Fedora на ZFS (Beta).

Установка, настройка, эксплуатация.

Модератор: ROOT

Fedora на ZFS (Beta).

Сообщение ROOT » 24 янв 2020, 22:28

Оглавление


Темы
 Подготовка системы к клонированию 
 Настраиваем систему на целевом диске 
 Обновляем образ initramfs 
 Установка Grub2 на целевой диск 
 Замена Grub 2 на systemd-boot 
 Добавляем в bash_completion zfs 
Дополнительные материалы
Convert MBR to GPT
Перенос системы на другой диск (xfs_copy)
XFS: Файловая система


Fedora_Root_On_ZFS.md статья на github
Reliably boot Fedora with root on ZFS статья с csparks.com
ZFS на Linux Debian 9.9 Видео на youtube



Нерешенные вопросы
  1. Почему на завершающей стадии не могу экспортировать пул из системы (после выхода из chroot)?
  2. Не устраивает сборка при помощи dkms (требуется выполнение некоторых операций руками). Желательно мигрировать на akmods


Основные команды
Действия с пулом
  • zpool create tank /dev/disk/by-id/… — Создание пула с именем tank на блочном устройстве (диск, раздел) /dev/disk/by-id/… Крайне желательно указывать именно ссылку на устройство из каталога /dev/disk/by-id/
  • zpool import — Выводит список пулов доступных для импорта
  • zpool list — Выводит список импортированных пулов
  • zpool import tank — Импортирует в систему пул с именем tank
  • zpool export tank — После выполнения этой команды пул tank больше не отображается в системе. Перед продолжением предпринимается попытка размонтирования всех смонтированных файловых систем в пуле. Если размонтировать какую-либо из файловых систем не удается, ее можно размонтировать принудительно с помощью параметра
  • zpool add — расширяет пространство пула объёмом добавляемого блочного устройства (stripe)
  • zpool attach — присоединяет блочного устройство к массиву (MIRROR и др)
  • zpool detach — отсоединяет блочное устройство от массива (MIRROR и др)
Действия с файловой системой
  • zfs create tank/ws — Создать dataset ws в пуле tank
  • zfs destroy -r tank/ws — Удаляет все вложенные dataset рекурсивно
  • zfs set … =on/off tank/ws — Установить/отключить параметр для указанного dataset
  • zfs mount — Монтирование определённого dataset
  • zfs unmount — Размонтирование отдельного dataset


 Подготовка системы к клонированию 
Поскольку в дистрибутиве Fedora изначально не создаётся файл /etc/hostid, а для работы файловой системы ZFS он нужен, то необходимо создать его
Код: выделить все
genhostid

Проверить существование файла hostid можно примерно так
Код: выделить все
[ -f /etc/hostid ] && echo true

Устанавливаем репозиторий zfsonlinux для Fedora 31 в систему
Код: выделить все
dnf install http://download.zfsonlinux.org/fedora/zfs-release.fc31.noarch.rpm

Инсталлируем необходимое программное обеспечение
Код: выделить все
dnf install dkms zfs-dracut zfs-dkms zfs grub2-efi-x64-modules

  • dkms - Этот пакет содержит платформу для динамической сборки модулей ядра (DKMS)
  • zfs-dracut - zfs-dracut позволяет dracut создавать образы initramfs с поддержкой ZFS
  • zfs-dkms - Пакет содержит модули ZFS для dkms
  • zfs - Пакет содержит основные утилиты командной строки ZFS.
  • grub2-efi-x64-modules - Этот пакет предоставляет дополнительные модули для сборки вашего собственного grub.efi.
Fedora предоставила пакет zfs-fuse, он уже установлен в системе. Затем следует использовать команду dnf swap для замены существующих пакетов fuse на пакеты ZFS.
Код: выделить все
dnf swap zfs-fuse zfs

Грузим zfs модули
Код: выделить все
modprobe zfs

Проверяем загрузились ли модули ядра zfs
Код: выделить все
lsmod |grep zfs

Собираем образ initramfs
Код: выделить все
dracut -f


Подготовка дискового пространства на новом диске
Теперь подготовим разделы на свободном диске и создаём следующие разделы
  • EFI System Partition - 256 MB
  • ZFS POOL - 34,4GB
Код: выделить все
parted -a optimal -s /dev/sdb 'mklabel gpt' 'mkpart primary fat32 1MiB 601MiB' \
   'name 1 "EFI System Partition"' 'set 1 esp on' \
   'mkpart primary 601MiB -1' 'name 2 "ZFS"'

Сделаем теперь на разделе EFI файловую систему FAT
Код: выделить все
mkfs.fat -F32 /dev/sdb1



Создаём структуру пулов и набора данных ZFS
Код: выделить все
tank/
tank/boot
tank/home

Создадим пул ZFS и корневую файловую систему с оптимальными параметрами
Код: выделить все
zpool create -d -o feature@allocation_classes=enabled \
    -o feature@async_destroy=enabled \
    -o feature@bookmarks=enabled \
    -o feature@embedded_data=enabled \
    -o feature@empty_bpobj=enabled \
    -o feature@enabled_txg=enabled \
    -o feature@extensible_dataset=enabled \
    -o feature@filesystem_limits=enabled \
    -o feature@hole_birth=enabled \
    -o feature@large_blocks=enabled \
    -o feature@lz4_compress=enabled \
    -o feature@project_quota=enabled \
    -o feature@resilver_defer=enabled \
    -o feature@spacemap_histogram=enabled \
    -o feature@spacemap_v2=enabled \
    -o feature@userobj_accounting=enabled \
    -o feature@zpool_checkpoint=enabled \
    -o ashift=9 -o altroot=/sysroot \
    -O atime=off -O compression=lz4 \
    -O xattr=sa -O normalization=formD \
    -O mountpoint=/ -O acltype=posixacl \
    tank /dev/disk/by-id/ata-VBOX_HARDDISK_VB08f83824-88e6cb2e-part2

??? -o multihost=on
Указываем параметр altroot равным /sysroot чтобы не менять значение перед перезагрузкой.
При создании пула указываются два типа параметров:
  • -o — параметры пула
  • -O — параметры корневого dataset
Теперь разберём значения основных параметров
  • ashift - Размер физ. сектора (9,12) степень двойки 2^9=512 или 2^12=4048=4K
  • altroot - Смещение относительно какого-то каталога точки монтирования
  • atime - Отключение обновления времени доступа к файлу при каждом обращении
  • canmount - Отключаем монтирование корневого dataset
  • compression - Метод сжатия данных для создаваемого dataset
  • xattr - Место хранения расширенных атрибутов, по умолчанию хранятся в виде скрытых файлов (только для Linux), что негативно влияет на производительность
  • -m none - Отключаем точку монтирования для корневого dataset
  • -f - Форсированное создание пула (подавляет предупреждения)
  • tank - Имя пула
  • /dev/... - Раздел или диск под создаваемый пул
  • multihost - осуществляется проверка, что пул уже кем-то импортирован
  • normalization -
Создаём dataset для файловой системы под домашние каталоги пользователей. Долее можно не указывать o mountpoint, точка монтирования значится автоматически исходя из названия dataset
Код: выделить все
zfs create \
    -o compression=on -o exec=off -o setuid=off \
    tank/home

setuid=off — запрещает выполнение программ от имени владельца файла в файловой системе для домашних каталогов пользователей.
-o exec=off — с файловой системы запрещаем выполнять программы.
Создаём dataset для файловой системы boot.
Код: выделить все
zfs create \
    -o compression=on -o atime=off \
    tank/boot

Теперь устанавливаем на параметр bootfs значение для dataset с загрузочной файловой системой
Код: выделить все
zpool set bootfs=tank/boot tank

Пример создания области подкачки swap
В данном случае создаём zfs volume, а не dataset. Том zfs является блочным устройством, а dataset - НЕТ
Код: выделить все
zfs create -V 4G -b $(getconf PAGESIZE) \
    -o logbias=throughput -o sync=always \
    -o primarycache=metadata -o secondarycache=none \
    -o com.sun:auto-snapshot=false -o compression=zle \
    tank/swap

Монтируем EFI раздел в соответствующий каталог вновь созданной структуры ZFS
Код: выделить все
mkdir -p /sysroot/boot/efi && mount /dev/sdb1 /sysroot/boot/efi

Переносим данные на диск с ZFS
Перед переносом данных на целевой диск нужно создать lvm snapshot либо остановить все основные сервисы и выполнить синхронизацию исходного диска с целевым
Код: выделить все
rsync -qaHAWXS --numeric-ids \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found/*","/sysroot"} \
/* /sysroot

Если возникла потребность в перезапуске или в поднятии существующего пула на иной системе, то нужно указывать ALTROOT параметром '-R /sysroot/tank' и тогда вся структура датасетов будет смонтирована по своим местам относительно значения ALTROOT
Код: выделить все
zpool import -R /sysroot tank



 Настраиваем систему на целевом диске 
Меняем корень файловой системы на каталог в который только что скопировали данные с исходного диска
Код: выделить все
mount /dev/sdb1 /sysroot/boot/efi
mount -t proc /proc /sysroot/proc
mount --rbind /sys /sysroot/sys
mount --make-rslave /sysroot/sys
mount --rbind /dev /sysroot/dev
mount --make-rslave /sysroot/dev
mount -t tmpfs tmpfs /sysroot/tmp
chroot /sysroot /bin/bash


Определяем UUID для загрузочного раздела на целевом диске и добавляем его отдельной строкой в fstab
Код: выделить все
blkid /dev/sdb1 | cut -d " " -f2 >> /etc/fstab


Вносим изменения в файл fstab
Меняем UUID для EFI раздела и добавляем подключение ZFS-тома для swap
e /etc/fstab
Код: выделить все
UUID=69CB-015C           /boot/efi         vfat        umask=0077,shortname=winnt 0 2
/dev/zvol/swap           none              swap        sw                         0 0



Код: выделить все
systemctl enable --now zfs-import-cache.service
systemctl enable --now zfs-import-scan.service
systemctl enable --now zfs-mount.service
systemctl enable --now zfs-share.service
systemctl enable --now zfs-zed.service
systemctl enable --now zfs.target



 Обновляем образ initramfs 
Добавляем ZFS_MOUNT ZFS_UNMOUNT в /etc/default/zfs
Код: выделить все
grep -q "ZFS_MOUNT" /etc/default/zfs 2> /dev/null || echo "
ZFS_MOUNT=yes
ZFS_UNMOUNT=yes
" | tee -a /etc/default/zfs

обновляем строку add_dracutmodules+ конфигурации в /etc/dracut.conf
Код: выделить все
add_dracutmodules+="zfs"


???
e /usr/lib/dracut/dracut-init.sh примерная строка 969
Код: выделить все
После строк
     local _optional="-o"
     local _silent
     local _ret
добавить
   if (($# == 0)); then
      return 0
   fi
 перед строкой
     [[ $no_kernel = yes ]] && return

обновляем initramfs
Код: выделить все
dracut /boot/initramfs-$(uname -r).img $(uname -r) --force


 Установка Grub2 на целевой диск 
Изменяем параметры загрузчика GRUB в /etc/default/grub
исходные строки
Код: выделить все
GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora_fs/root ...
GRUB_ENABLE_BLSCFG=true

И добавляем отсутствующие параметры или меняем значения у существующих
Код: выделить все
GRUB_CMDLINE_LINUX="boot=zfs rpool=tank bootfs=tank/fedora ...
GRUB_PRELOADED_MODULES="zfs"
GRUB_ENABLE_BLSCFG=false

Устанавливаем Grub2 на клонируемый диск
Код: выделить все
grub2-install --target=x86_64-efi --efi-directory=/boot/efi --recheck
Выполняется установка для платформы x86_64-efi.
Установка завершена. Ошибок нет.

Обновление конфигурации Grub2
Код: выделить все
ZPOOL_VDEV_NAME_PATH=YES grub2-mkconfig -o /etc/grub2-efi.cfg

Теперь изменим расположение grub.cfg и пересоздадим символическую ссылку /etc/grub2-efi.cfg
Код: выделить все
mv /boot/efi/EFI/fedora/grub.cfg /boot/grub2/grub.cfg
rm /etc/grub2-efi.cfg
ln -s /boot/grub2/grub.cfg /etc/grub2-efi.cfg



При обновлении конфигурации grub2 может вылезать ошибка
Код: выделить все
grub2-mkconfig -o /etc/grub2-efi.cfg
/usr/sbin/grub2-probe: ошибка: не удалось получить канонический путь "/dev/ata-VBOX_HARDDISK_VBf6a8f669-2de5ab43-part2".

Исправление ошибки Grub2 связанной с именами путей устройств пула
Позже нам нужно будет запустить скрипт с именем grub2-mkconfig. Этот скрипт использует команду zpool status для вывода списка компонентов пула. Но когда эти компоненты не являются простыми именами устройств, скрипт завершается ошибкой. Самое простое решение - добавить системную переменную среды. Нужно определить переменную для тек сеанса и создать файл e /etc/profile.d/grub2_zpool_fix.sh с аналогичной строкой:
Код: выделить все
export ZPOOL_VDEV_NAME_PATH=YES



Подготовка системы к перезапуску.
Завершаем chroot, рекурсивно демонтируем файловые системы в каталоге /sysroot и и экспортируем pool zfs из системы
Код: выделить все
exit
umount -R /sysroot (if you have a legacy boot partition)
zfs umount -a
zpool export tank

-a — размонтировать все доступные файловые системы ZFS. Вызывается автоматически как часть процесса выключения.


 Замена Grub 2 на systemd-boot 
Grub 2 имеет существенный недостаток применительно к ZFS. Пул собранный с некоторыми опциями довольно плохо воспринимается ZFS-модулем от Grub. Именно по данной причине и производится замена на systemd-boot
Шаг 1.
Удаляем Grub 2
Код: выделить все
dnf remove grubby grub2\* shim\* memtest86\*
rm -rf /boot/grub2 && rm -rf /boot/loader

Шаг 2.
Настройка точки монтирования. Откроем файл /etc/fstab в текстовом редакторе:
e /etc/fstab
Код: выделить все
UUID=69CB-015C  /boot/efi vfat umask=0077,shortname=winnt 0 2

Убедимся, что точка монтирования ESP раздела задана корректно и UUID совпадает с номером EFI-раздела диска-клона
Здесь 69CB-015C — это UUID, который можно определить при помощи blkid. Добавим параметр монтирования umask=0077 (при отсутствии), т.к. файловая система FAT32 не поддерживает права доступа и любой пользователь может вносить любые изменения, что для нас не приемлемо.
Сохраним изменения в файле.

Шаг 3.
Настройка параметров ядра
В данной конфигурации параметры ядра будут указаны в файле /etc/kernel/cmdline в формате обычной строки, разделённые пробелом:
Код: выделить все
cat /proc/cmdline | cut -d ' ' -f 2- | tee /etc/kernel/cmdline && chmod 644 /etc/kernel/cmdline

В данном примере будут автоматически использованы параметры текущего загруженного ядра из /proc/cmdline.
В результате должен получиться файл /etc/kernel/cmdline с подобным содержимым:
Код: выделить все
root=ZFS=tank ro boot=zfs rpool=tank bootfs=tank rhgb quiet

При необходимости внесём соответствующие правки:
Код: выделить все
e /etc/kernel/cmdline

Удаляем файл zpool.cache перед сборкой микроядра системы. В процессе сборки он (если есть) попадает в микроядро системы и препятствует нормальному запуску
Код: выделить все
rm /etc/zfs/zpool.cache

Шаг 4.
Установка systemd-boot на раздел ESP:
Код: выделить все
bootctl --path=/boot/efi install

Инициируем пересборку initrd ядра, а также сгенерируем новые файлы конфигурации:
Код: выделить все
kernel-install add $(uname -r) /lib/modules/$(uname -r)/vmlinuz

Шаг 5.
Перезагрузка системы. Проверим всё ли сделано верно и перезагрузим систему для применения изменений:
Завершаем chroot, рекурсивно демонтируем файловые системы в каталоге /sysroot и и экспортируем pool zfs из системы
Код: выделить все
exit
umount -R /sysroot (if you have a legacy boot partition)
zfs umount -a
zpool export tank
systemctl reboot

Если всё было сделано верно, Fedora успешно загрузится при помощи EFIStub под управлением systemd-boot. В противном случае следует восстановить резервную копию, либо воспользоваться chroot с LiveUSB для решения возникших проблем.


При обрыве запуска системы нужно единожды выполнить импорт пула, из режима восстановления, с параметром "-f" и перезапустить машину
Код: выделить все
zpool import -R /sysroot -f
reboot



Настройка параметров загрузки
Параметры загрузки допускается изменять в файлах
Код: выделить все
/boot/efi/loader/loader.conf
/boot/efi/loader/entries/*


cat /boot/efi/loader/entries/9ec751ae2d584182b2b2c596917bafea-5.4.13-201.fc31.x86_64.conf
Код: выделить все
title      Fedora 31 (Server Edition)
version    5.4.13-201.fc31.x86_64
machine-id 9ec751ae2d584182b2b2c596917bafea
options    root=ZFS=tank ro boot=zfs rpool=tank bootfs=tank rhgb quiet
linux      /9ec751ae2d584182b2b2c596917bafea/5.4.13-201.fc31.x86_64/linux
initrd     /9ec751ae2d584182b2b2c596917bafea/5.4.13-201.fc31.x86_64/initrd

cat /boot/efi/loader/loader.conf
Код: выделить все
timeout 5
#console-mode keep
default 9ec751ae2d584182b2b2c596917bafea-*



При обновлении ядра в системе может не правильно или несвоевременно собираться модули ядра. Данная проблема решается в одну команду, нужно только пересобрать модули ядра под конкретную версию:
Код: выделить все
dkms autoinstall -k 5.4.14-200.fc31.x86_64

подставив номер только что установленного ядра
А так же инициируем пересборку initrd ядра, и сгенерируем новые файлы конфигурации:
Код: выделить все
kernel-install add 5.4.14-200.fc31.x86_64 /lib/modules/5.4.14-200.fc31.x86_64/vmlinuz

Проверить генерацию минимального ядра можно по дате и времени создания файла
Код: выделить все
ll /boot/efi/9ec751ae2d584182b2b2c596917bafea/5.4.14-200.fc31.x86_64/
итого 38M
-rwx------ 1 root root  28M фев  1 18:19 initrd
-rwx------ 1 root root 9,9M фев  1 18:19 linux



 Добавляем в bash_completion zfs 
Код: выделить все
wget -O /etc/bash_completion.d/zfs https://raw.githubusercontent.com/zfsonlinux/zfs/master/contrib/bash_completion.d/zfs
chmod -R  ugo+x /etc/bash_completion.d/zfs
Для желающих отблагодарить
SB: 4274320029755744
QIWI: +79175241450
Аватар пользователя
ROOT
Администратор
 
Сообщений: 135
Зарегистрирован: 01 авг 2011, 09:36
Откуда: Моск. обл., г. Железнодорожный

Вернуться в Fedora

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron