28 Сен., 2021, 00:59

Излишняя торопливость, точно так же как и медлительность, ведет к печальному концу.

Уильям Шекспир


Установка Ubuntu 20.04 x64 на ZoL (ZFS on Linux)

Автор Shaman, 23 Апр., 2021, 18:43

« предыдущая - следующая »

Shaman

В сети достаточно много HowToo по этой теме:
Как от сторонних людей
ZFS на Linux
Так и от самих разработчиков ZoL.

Но эти вещи имеют свойство быстро устаревать. Да и создавались они изначально под конкретные условия (исключая инструкцию от самих разработчиков) и для вашей ситуации могут не подойти. Поэтому я решил написать ещё одно.  :)
Учитывая всё вышеизложенное прямо следовать ему не стоит или как минимум предварительно проверить работоспособность в ваших реалиях, к примеру на виртуальной машине.

На данный момент (22.04.21) есть два основных способа установки Ubuntu на ZFS, это вышеуказанный способ от разработчиков ZoL и от разработчиков Ubuntu, встроенный в инсталлятор. Поскольку эти команды работают с оглядкой друг на друга...
скрытый текст
The Ubuntu installer has support for root-on-ZFS. This HOWTO produces nearly identical results as the Ubuntu installer because of bidirectional collaboration.
[свернуть]
... то и установки приводят к схожим результатам, но к сожалению обе они являются крайностями. В первой вы абсолютно всё настраиваете в ручную из терминала, во второй полагаетесь на преднастройки разработчиков. Золотой середины, графического инсталлятора с возможностью выбора параметров, пока не существует. Единственной альтернативой на данный момент остаётся редактирование скрипта установки.

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

Начнём.

1. Загружаемся с установочного носителя и выбираем пункт "Try Ubuntu (Попробовать Ubuntu)"

2. Открываем любым удобным для вас способом файл zsys-setup
sudo gedit /usr/share/ubiquity/zsys-setup
3. Уменьшаем размер раздела подкачки.
Совсем убрать его невозможно, скрипт падает.
В самом скрипте об этом тоже написано
        # Give us a minimum swap partition size of 4MB in case we decide on
 # no swap, just to keep the partition layout stable:
[свернуть]
Поиском находим все выражения ${ss} и меняем их на значение 4. Минимальный возможный размер. Если делать меньше скрипт отрабатывает, но установка падает.
Пример
Код (Было) Выделить
${partprefix}${partswap}  :   size= ${ss}M,         type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
Код (Стало) Выделить
${partprefix}${partswap}  :   size= 4M,             type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
[свернуть]
[свернуть]

4. Отключаем создание отдельной файловой системы для каталога пользователя.

4.1 Ищем и удаляем:
zfs create rpool/USERDATA -o canmount=off -o mountpoint=/4.2 Ищем move_user и удаляем все до init_system_partitions
скрытый текст
move_user () {
 target="$1"
 user="$2"
 userhome="$3"
 uuid="$4"

 echo "I: Creating user $user with home $userhome"
 mv "${target}/${userhome}" "${target}/tmp/home/${user}"
 zfs create "rpool/USERDATA/${user}_${uuid}" -o canmount=on -o mountpoint=${userhome}
 chown $(chroot "${target}" id -u ${user}):$(chroot ${target} id -g ${user}) "${target}/${userhome}"
 rsync -a "${target}/tmp/home/${user}/" "${target}/${userhome}"
 bootfsdataset=$(grep "\s${target}\s" /proc/mounts | awk '{ print $1 }')
 zfs set com.ubuntu.zsys:bootfs-datasets="${bootfsdataset}" rpool/USERDATA/${user}_${UUID_ORIG}
}
[свернуть]
[свернуть]

5. Я буду использовать msql и для этого создаю дополнительный набор данных с recordsize=16K (поскольку именно такой размер блока использует эта база данных). Вам для повтора необязателен.
5.1 Ищем строку # Desktop specific system dataset и вставляем строчку
zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib/mysql" -o recordsize=16K
[свернуть]

Чуть подробнее об остальных настройках
В этом блоке создаются пулы для корневой файловой системы и загрузчика, задаются флаги настроек (подробнее о флагах здесь и здесь). С параметром -O идут настройки для пула, а с -o параметры для файловой системы
скрытый текст

  # Pools
  # rpool 
  zpool create -f \                           
 -o ashift=12 \
 -O compression=lz4 \
 -O acltype=posixacl \
 -O xattr=sa \
 -O relatime=on \
 -O normalization=formD \
 -O mountpoint=/ \
 -O canmount=off \
 -O dnodesize=auto \
 -O sync=disabled \
 -O mountpoint=/ -R "${target}" rpool "${partrpool}"

 # bpool
 # The version of bpool is set to the default version to prevent users from upgrading
 # Then only features supported by grub are enabled.
 zpool create -f \
 -o ashift=12 \
 -d \
 -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@spacemap_histogram=enabled \
 -O compression=lz4 \
 -O acltype=posixacl \
 -O xattr=sa \
 -O relatime=on \
 -O normalization=formD \
 -O canmount=off \
 -O devices=off \
 -O mountpoint=/boot -R "${target}" bpool "${partbpool}"
[свернуть]

В этом создаются сами наборы
[/b]
# Root and boot dataset
 zfs create rpool/ROOT -o canmount=off -o mountpoint=none
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}" -o mountpoint=/
 zfs create bpool/BOOT -o canmount=off -o mountpoint=none
 zfs create "bpool/BOOT/ubuntu_${UUID_ORIG}" -o mountpoint=/boot

 # System dataset
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var" -o canmount=off
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib/AccountServices"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib/apt"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib/dpkg"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/lib/NetworkManager"

 # Desktop specific system dataset
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/srv"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/usr" -o canmount=off
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/usr/local"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/games"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/log"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/mail"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/snap"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/spool"
 zfs create "rpool/ROOT/ubuntu_${UUID_ORIG}/var/www"
[свернуть]

Здесь настраивается система автоматического создания снапшотов
[/b]
        # Set zsys properties
 zfs set com.ubuntu.zsys:bootfs='yes' "rpool/ROOT/ubuntu_${UUID_ORIG}"
 zfs set com.ubuntu.zsys:last-used=$(date +%s) "rpool/ROOT/ubuntu_${UUID_ORIG}"
 zfs set com.ubuntu.zsys:bootfs='no' "rpool/ROOT/ubuntu_${UUID_ORIG}/srv"
 zfs set com.ubuntu.zsys:bootfs='no' "rpool/ROOT/ubuntu_${UUID_ORIG}/usr"
 zfs set com.ubuntu.zsys:bootfs='no' "rpool/ROOT/ubuntu_${UUID_ORIG}/var"[/spoiler]
[свернуть]
Я с этими настройками согласен, но вы можете изменить их по своему усмотрению. Подробнее о том почему настройки именно такие написано в блоге разработчика.
[свернуть]

6. Сохраняем изменения файла zsys-setup и ...
...запускаем установку.
6.1 На этапе выбора дисков нажимаем "Earse disk and install Ubuntu (Стереть диск и установить Ubuntu)"
zfs_install_step1.png

6.2 Выбираем опцию "EXPERIMENTAL:Earse disk and use ZFS (Экспериментальное: Стереть диск и использовать ZFS"
zfs_install_step2.png

6.3 Если отобразиться "ZFS selected (Выбранка ZFS)" продолжаем установку.
zfs_install_step3.png

6.4 Если у вас более одного диска то откроется окно выбора оных. А после или вместо него окно с подтверждением настроек.
zfs_install_step4.png

6.5 После появления окна создания пользователя ждем некоторое время и, если скрипт не упал с ошибкой,  :)  продолжаем установку, которая далее не отличается от стандартной. Если же возникла ошибка заново открываем скрипт, ищем её, запоминаем, перезагружаемся и начинаем всё с начала. Поскольку без перезагрузки скрипт, даже исправленный, всё равно будет падать в ошибку.
[свернуть]

7. После установки (если всё прошло удачно и система загрузилась) перезаходим под рутом.

8. Создание пула для каталога пользователя
8.1 Для создания пула вводим команду:

# zpool create -o ashift=12 -O xattr=sa -o autoexpand=on -o autoreplace=on -O atime=off -O compression=lz4 -o autotrim=on -O acltype=posixacl -O relatime=on -O normalization=formD -O canmount=off -O dnodesize=auto -O sync=disabled  USER -f -m none raidz  /dev/sd[c-f]Где:
  • USER - имя вашего пула (может быть любым),
  • -m none - точка монтирования (в данном случае её нет),
  • raidz - тип пула,
Типы пулов
  • stripe - страйп, нечто среднее между RAID0 и JBOD. Не имеет избыточности, вся информация теряется при смерти любого из дисков.
  • mirror - зеркало, примерный аналог RAID1. Каждый диск зеркала содержит полную копию всей информации. Выдерживает смерть одного любого диска. Возможно и тройное зеркало.
  • raidz1 - примерный аналог RAID5, требует минимум 3 дисков, объем одного диска уходит на избыточность. Выдерживает смерть одного любого диска.
  • raidz2 - примерный аналог RAID6, требует минимум 4 диска, объем двух дисков уходит на избыточность. Выдерживает смерть двух любых дисков.
  • raidz3 - требует минимум 5 дисков, объем трёх дисков уходит на избыточность. Выдерживает смерть трёх любых дисков.
[свернуть]
  • /dev/sd[c-f] - диски из которых собирается пулл. Если диски идут не по порядку то путь до каждого диска необходимо прописать отдельно разделяя пробелами
Подробнее об остальных параметрах команды в ссылках под спойлером Чуть подробнее об остальных настройках

8.2 Перемонтируем пул для использования /dev/disk/by-id в место /dev/sd*
# zpool export USER
# zpool import -d /dev/disk/by-id USER
Зачем это надо
Первая команда отключит пул, вторая соберёт его заново, но с другими именами дисков. Это необходимо поскольку если по какой то причине названия дисков sd*  в пуле поменяются (диск будет подлючен в другой разъём, или добавиться новый и при перезагрузке названия сместятся) пул не подключиться. А в by-id диски отображаются по серийным номерам, независимо от физического подключения.
Можно было сразу создать пул через эти имена, но тогда бы пришлось в ручную их прописывать, а это неудобно.
[свернуть]

8.3 Создаём в каталоге mnt подкаталог 1 и скопируем в него каталог пользователя.
# mkdir /mnt/1
# rsync -avPX /home/user1 /mnt/1
Здесь и далее в место user1 подставляем имя вашего пользователя.

8.4Удаляем каталог пользователя.
Важно!!!
Следующая команда удаляет данные без подтверждения поэтому внимательно проверте путь, а также, что копирование в п 8.3 прошло успешно.
# rm -rf /home/user1
8.5 Cоздаём наборы данных для каталога home и пользователя.
# zfs create USER/home
# zfs create USER/home/user1
Команды также смонтируют эти наборы данных в одноимённые каталоги. Монтирование невозможно если каталог не пустой. Поэтому были необходимы п 8.3 и 8.4.

8.6Скопируем данные пользователя обратно.
# rsync -avPX /mnt/1 /home/user1
8.7 Выходим из рута и логинимся под вашим пользователем. И, если всё прошло успешно, удаляем временный каталог 1.
# rm -rf /mnt/1
[свернуть]

Поздравляю, установка завершена!