Как стать автором
Поиск
Написать публикацию
Обновить
Selectel
IT-инфраструктура для бизнеса

ZFS on Linux: установка Ubuntu с корнем в ZFS, RAID и шифрованием

Время на прочтение6 мин
Количество просмотров7K

Привет! Меня зовут Ваня, я системный администратор в Selectel. Допустим, вы уже «пришли к просветлению» и признали, что ZFS — удобная, функциональная и вообще единственная правильная файловая система. Осталось только понять, как начать ее использовать. Об этом и поговорим под катом!

Рассмотрим установку Ubuntu 24.04 с корнем на ZFS на UEFI-систему со всеми возможными сценариями: raidz, шифрование, сжатие и даже удаленная разблокировка для сервера. Гайд подойдет не только для Ubuntu, но и Debian или любого Debian-based дистрибутива, устанавливаемого через debootstrap. При этом часть гайда с подготовкой дисков и zpool универсальна — ее можно использовать с любым дистрибутивом. Но этап установки системы в случае non-Debian придется адаптировать самостоятельно.

Установку на BIOS-машины в инструкции не рассматриваем — все же за окном 2025 год. 🙂 Из бонусов: установка через debootstrap установит лишь необходимый минимум для работы системы — даже никакого snap и прочего «предустановленного мусора», за который Ubuntu часто критикуют.

Используйте навигацию, если не хотите читать текст целиком:

Подготовка окружения и разметка дисков

Все, что нам понадобится, — это LiveCD с поддержкой ZFS и доступ в сеть. К счастью, в стандартные установочные ISO-образы Ubuntu легко добавить поддержку ZFS.

Загружаем ВМ с ISO или пишем образ на флешку и грузим сервер с нее — как удобнее. В установщике пропускаем все предложения и добираемся до root-консоли. Любимым менеджером дисков — например, fdisk, gparted или sfdisk — размечаем диск:

nvme1n1     259:1    0 476.9G  0 disk
├─nvme1n1p1 259:5    0   127M  0 part
├─nvme1n1p2 259:6    0   1.9G  0 part
└─nvme1n1p3 259:7    0 474.9G  0 part

Что для нас важно:

  • ~100 МБ vfat-раздел под /boot/efi, флаги esp, boot;

  • ~ 2 ГБ ext4-раздел для /boot (не обязателен, но очень рекомендован — для универсальности);

  • оставшееся место — для zpool. Все остальные разделы при необходимости можно создать как dataset или volume внутри zpool.

Если планируете использовать raidz, то второй диск размечайте аналогично «байт в байт». А /boot — упакуйте в mdadm RAID1-массив (GRUB умеет с ним работать). Пример для системы с двумя дисками:

mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/nvme0n1p2 /dev/nvme1n1p2

Облачная инфраструктура для ваших проектов

Виртуальные машины в Москве, Санкт-Петербурге и Новосибирске с оплатой по потреблению.

Подробнее →

Установка ZFS и создание пула

После настройки сети (если в сети есть DHCP, то она уже настроена) устанавливаем инструменты для работы с ZFS:

apt update
apt install zfsutils-linux -y

Создаем файловые системы:

mkfs.fat -F 32 /dev/nvme1n1p1
mkfs.ext4 /dev/md0 (или раздел диска, если рейд не планируется, например: /dev/nvme1n1p2)

Создание пула zpool

Примеры команд — под разные конфигурации. Вместо POOLNAME используйте имя вашего zpool — например, совпадающее с именем хоста.

Без сжатия, raidz или шифрования:

zpool create -o ashift=12 -o autotrim=on -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt POOLNAME /dev/nvme1n1p3

С зеркалом на двух дисках:

zpool create -o ashift=12 -o autotrim=on -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt POOLNAME mirror /dev/nvme0n1p3 /dev/nvme1n1p3

Raidz2 на четырех дисках:

zpool create -o ashift=12 -o autotrim=on -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt POOLNAME raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd

Cжатый и зашифрованный:

zpool create -o ashift=12 -o autotrim=on -O compression=lz4 -O encryption=on -O keyformat=passphrase -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt $POOLNAME /dev/nvme1n1p3

Сжатый и зашифрованный на четырех дисках в raidz2:

zpool create -o ashift=12 -o autotrim=on -O compression=lz4 -O encryption=on -O keyformat=passphrase -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt $POOLNAME raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd

Краткие пояснения к опциям

  • autotrim=on — если используете SSD. Опция снизит износ и повысит производительность за счет информирования диска об освобожденных блоках.

  • ashift — размер блока. В ashift указывается степень двойки — например ashift=12 — это блоки 4 КБ (2¹² = 4 096 байт), а ashift=9 — блоки 512 байт. Для лучшей производительности рекомендуем использовать 12, но в некоторых частных случаях — например, если у вас старые диски, которые не умеют работать с 4 КБ-блоками, можно сменить на 9. 

  • compression=lz4 — быстрое и эффективное сжатие, но также вы можете выбрать lzjb, zle, gzip или zstd.

  • encryption=on, keyformat=passphrase — включают шифрование (по умолчанию — AES-256-CCM, рекомендуем не менять).

Остальные параметры менять не нужно. Подробнее о каждом можно почитать в официальной документации.

Установка системы и настройка загрузки

1. Создаем и монтируем dataset для корневой ФС:

zfs create -o canmount=noauto -o mountpoint=/ POOLNAME/root
zfs mount POOLNAME/root

Именно canmount=noauto: при запуске ядро само смонтирует dataset с корневой ФС.

2. Перед установкой можно создать и другие dataset для иных точек монтирования — например:

zfs create -o mountpoint=/home POOLNAME/home
Также создаем и монтируем /boot и /boot/efi:
mkdir /mnt/boot; mount /dev/md0 /mnt/boot # (или раздел, если не используем рейд)
mkdir /mnt/boot/efi; mount /dev/nvme1n1p1 /mnt/boot/efi

3. Устанавливаем базу системы:

apt install debootstrap -y
debootstrap noble /mnt
zfs set devices=off POOLNAME

4. Установленная система не обладает даже репозиториями, а также в ней нет нескольких важных файлов. Исправляем это (не забыв указать желаемое имя хоста вместо HOSTNAME):

echo HOSTNAME > /mnt/hostname
echo 127.0.0.1 localhost HOSTNAME > /mnt/hosts
grep -v cdrom /etc/apt/sources.list > /mnt/etc/apt/sources.list
rsync -aPvh /etc/apt/sources.list.d/ /mnt/etc/apt/sources.list.d/

5. Заходим в установленную систему через chroot для завершения установки:

mount --rbind /dev  /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys  /mnt/sys
chroot /mnt /bin/bash --login

6. Исправляем локали и часовой пояс:

locale-gen --purge "en_US.UTF-8"
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
dpkg-reconfigure --frontend noninteractive locales
dpkg-reconfigure tzdata

7. Обновляем списки пакетов и устанавливаем все необходимое для загрузки:

apt update; apt dist-upgrade -y
apt install zfs-initramfs shim-signed grub-efi-amd64-signed linux-image-generic linux-headers-generic openssh-server -y

Сейчас же можно доустановить полезные утилиты, а если планируем вводить пароль для дешифровки удаленно, то обязательно ставим dropbear-initramfs:

apt install dropbear-initramfs # tmux nano net-tools curl fdisk rsync etc

8. В /etc/fstab добавляем только отличные от ZFS файловые системы — например:

/dev/md0	/boot			ext4	noatime,nofail,x-systemd.device-timeout=5s	0	1
/dev/nvme1n1p1	/boot/efi		vfat	noatime,nofail,x-systemd.device-timeout=5s	0	1

9. ZFS сам монтирует dataset-ы при загрузке. Однако если canmount= noauto (за исключением корня), то монтирование происходит вручную. В обратном случае модуль ядра ZFS смонтирует все самостоятельно, даже если у нас нет юнита systemd, строки в /etc/fstab и т. д. Ручное монтирование:

zfs mount POOLNAME/DATASET

Если нужно временно смонтировать в нестандартную точку (отличную от mountpoint директорию), делаем это так:

mount -t zfs -o zfsutil POOLNAME/DATASET /path/to/mount

Настройка удаленной разблокировки

Для удаленной разблокировки используем Dropbear: 

1. Кладем ключ в /etc/dropbear/initramfs/authorized_keys.

2. В /etc/dropbear/initramfs/dropbear.conf указываем опции запуска, изменив 2077 на «любимый» порт:

DROPBEAR_OPTIONS="-I 180 -j -k -p 2077 -s -c zfsunlock"

3. Настраиваем сеть до монтирования корневой ФС, чтобы мы могли в процессе загрузки подключиться к нашему серверу и ввести пароль для разблокировки зашифрованного dataset. Я обычно использую статический IP, указанный в конфигурации initramfs-tools (/etc/initramfs-tools/initramfs.conf):

IP=SERVER-IP::GATEWAY:NETMASK:SERVER-HOSTNAME

Можно также использовать DHCP или настроить директиву IP в параметрах запуска ядра — что для вас привычнее.

4. Если использовали mdadm для /boot, устанавливаем и настраиваем его тоже:

apt install mdadm -y
mdadm --detail --scan > /etc/mdadm/mdadm.conf

5. Когда завершили все приготовления initramfs, перегенерируем ее и установим загрузчик (GRUB):

update-initramfs -u -k all
grub-install /dev/nvme1n1p1
update-grub

6. После update-grub рекомендуем проверить сгенерированный конфиг grub и убедиться, что он правильно передает ядру параметр root. Иногда его нет или он выглядит неправильно. Закономерности я не нашел, но и не смог воспроизвести проблему при написании инструкции. Строка с запуском ядра должна выглядеть примерно вот так:

linux	"/vmlinuz-6.8.0-59-generic" root=ZFS="POOLNAME/root" ro

Когда закончили установку и настройку всего, что вам понадобится на машине (openssh-server на сервере, KDE/Gnome/XFCE на ПК и т. д.), выходим из chroot, все размонтируем и экспортируем zpool:

exit
umount /mnt/boot/efi
umount /mnt/boot
umount -lf /mnt
zpool export -a

Готово!

Система установлена и готова к использованию. Можно перезагружаться и проверять работу. И еще раз: убедитесь в нескольких ключевых моментах.

  • Grub корректно собрал свой конфиг.

  • Сеть настроена корректно.

  • Вы не забыли экспортировать пул.

Теги:
Хабы:
+51
Комментарии58

Публикации

Информация

Сайт
slc.tl
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия
Представитель
Влад Ефименко