Привет! Меня зовут Денис, я 3D-художник и Linux-энтузиаст. Более 8 лет Arch Linux является моей основной и единственной операционной системой. Мне не удалось найти ни одного приличного гайда по установке Arch на ZFS. Где-то была устаревшая информация, где-то использовался плохо подходящий для ZFS GRUB, где-то ядро ставилось на FAT. Хороший повод написать новый гайд.

Почему ZFS? Однажды я решил собрать stripe (RAID0) на ноутбуке с двумя дисками. Хотелось сохранить привычную структуру директорий и не думать о том, на каком диске что лежит.
На тот момент я уже использовал ZFS на файловом сервере, а на ноутбуках - Btrfs + LUKS2. Загрузить Arch Linux с RAID на Btrfs у меня не получилось. С ZFS, напротив, не возникло никаких трудностей.

Почему страйп а не зеркало? Ноутбук ношу с собой, ноутбук можно потерять, забыть в кафе, ноутбуки воруют. Все важное в любом случае бекапится на сервер, поэтому избыточность на ноутбуке мне не нужна. На сервере ZFS, поэтому Btrfs на ноутбуке мне не подходит.

Задача:

  • ZFS stripe из двух дисков

  • Полное шифрование

  • Ядро на ZFS

Установочный образ archiso не имеет поддержки ZFS. Нам придётся добавить zfs модуль в archiso самостоятельно.

Ставим пакет archiso и копируем дефолтный профиль для дальнейшего редактирования.

pacman -Syu archiso
cp -r /usr/share/archiso/configs/releng/ ~/archlive

Из файла ~/archlive/packages.x86_64 удаляем linux и broadcom-wl и добавляем пакеты:

linux-lts
linux-lts-headers
libunwind
zfs-utils
zfs-dkms

В ~/archlive/pacman.conf добавляем репозиторий archzfs:

[archzfs]
SigLevel = Never
Server = https://github.com/archzfs/archzfs/releases/download/experimental

Ставим LTS ядро для лучшей совместимости с ZFS. Заменяем vmlinuz-linux и initramfs-linux.img на vmlinuz-linux-lts и initramfs-linux-lts.img в следующих конфигах:

archlive/airootfs/etc/mkinitcpio.d/linux.preset
archlive/efiboot/loader/entries/01-archiso-linux.conf
archlive/syslinux/archiso_sys-linux.cfg
archlive/grub/loopback.cfg
archlive/grub/grub.cfg

Собираем образ. Затем пишем на флешку и грузимся.

mkdir isobuild
mkarchiso -v -r -w /tmp/archiso-tmp -o isobuild ~/archlive

На дисках создаём таблицу разделов GPT и следующую разметку:

nvme0n1p1 - 256 Mb - EFI System
nvme0n1p2 - всё свободное место - Solaris Root
nvme1n1p1 - весь диск - Solaris Root

Тут подойдет любая программа для разметки диска, например cfdisk.
На EFI-разделе будет находиться только загрузчик ZFSBootMenu, поэтому большой раздел нам не нужен. Ядро и система будут храниться непосредственно на ZFS.

Создаем ZFS пул:

zpool create -f -o ashift=12 \
-O acltype=posixacl \
-O relatime=on \
-O xattr=sa \
-O dnodesize=auto \
-O normalization=formD \
-O mountpoint=none \
-O canmount=off \
-O devices=off
-o autotrim=on \
-R /mnt \
-O compression=lz4 \
-O encryption=aes-256-gcm \
-O keyformat=passphrase \
-O keylocation=prompt \
zroot /dev/nvme0n1p2 /dev/nvme1n1p1

Несколько важных опций:

  • compression=lz4 - практически бесплатное сжатие

  • encryption=aes-256-gcm - встроенное шифрование ZFS

  • keyformat=passphrase - парольная фраза

  • keylocation=prompt - пароль вводится при загрузке

Создаем датасеты:

zfs create -o mountpoint=none zroot/data  
zfs create -o mountpoint=none zroot/ROOT  
zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default  
zfs create -o mountpoint=/home zroot/data/home  

После создания датасетов необходимо заново импортировать пул:

zpool export zroot  
zpool import -d /dev/nvme0n1p2 -R /mnt zroot -N  
zfs load-key zroot  
zfs mount zroot/ROOT/default  
zfs mount -a

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

zpool set bootfs=zroot/ROOT/default zroot

Монтируем EFI раздел для загрузчика:

mkdir -p /mnt/efi  
mkfs.vfat -F32 -n EFI /dev/nvme0n1p1  
mount /dev/nvme0n1p1 /mnt/efi

Ставим базовую систему:

pacstrap /mnt base linux-lts linux-lts-headers neovim base-devel iwd sudo

Генерируем fstab:

genfstab -U -p /mnt > /mnt/etc/fstab

После этого удаляем из /mnt/etc/fstab всё, кроме EFI-раздела. ZFS монтируется самостоятельно.

Чрутимся:

arch-chroot /mnt

Добавляем archzfs репозиторий в /etc/pacman.conf:

[archzfs]  
Server = https://github.com/archzfs/archzfs/releases/download/experimental
Server = https://mirrors.uni-plovdiv.net/archzfs/experimental

Добавляем ключ:

pacman-key --init
pacman-key --recv-keys 3A9917BF0DED5C13F69AC68FABEC0A1208037BE9
pacman-key --lsign-key 3A9917BF0DED5C13F69AC68FABEC0A1208037BE9

Ставим ZFS:

pacman -S zfs-utils zfs-dkms

ZFS модули привязаны к определённой версии ядра. Если при обновлении ядра модули не собираются, ядро необходимо откатить и подождать, пока обновятся модули.
Альтернатива - использовать репозитории CachyOS, где есть ядра со встроенной поддержкой ZFS. Последние полгода я использую linux-cachyos-zfs.

Редактируем /etc/mkinitcpio.conf.
Добавляем модуль:
MODULES=(zfs)
Правим HOOKS:
HOOKS=(base udev ... keyboard zfs filesystems)

Пересобираем initramfs:

mkinitcpio -P

Важно:

  • zfs должен идти перед filesystems

  • keyboard - перед zfs

  • если используется systemd, его нужно заменить на base udev

Базовая настройка системы:

echo "en_US.UTF-8 UTF-8" > /etc/locale.gen  
locale-gen  
echo "LANG=en_US.UTF-8" > /etc/locale.conf  
echo "KEYMAP=us" > /etc/vconsole.conf  
echo "somename" > /etc/hostname    
zgenhostid $(hostid)

Только ZFSBootMenu умеет нормально грузить ядро с ZFS, так что выбор загрузчика очевиден.

Скачиваем загрузчик:

mkdir -p /efi/EFI/zbm
wget https://get.zfsbootmenu.org/latest.EFI -O /efi/EFI/zbm/zfsbootmenu.EFI

Создаём EFI-запись:

efibootmgr --disk /dev/nvme0n1 --part 1 --create --label "ZFSBootMenu" --loader '\EFI\zbm\zfsbootmenu.EFI' --unicode "spl_hostid=$(hostid) zbm.timeout=3 zbm.prefer=zroot zbm.import_policy=hostid" --verbose

Важно:
--disk /dev/nvme0n - диск, где находится загрузчик
--part 1 - номер раздела на этом диске

Параметры загрузки ядра:

zfs set org.zfsbootmenu:commandline="noresume init_on_alloc=0 rw spl.spl_hostid=$(hostid) zswap.enabled=0" zroot/ROOT

Параметр zswap.enabled=0 нужен если планируется использовать zram.

Проверяем:

zfs get org.zfsbootmenu:commandline zroot/ROOT

Включаем сервисы ZFS:

systemctl enable zfs.target  
systemctl enable zfs-import.target  
systemctl enable zfs-volumes.target  
systemctl enable zfs-import-scan.service

Настраиваем zfs-mount-generator:

mkdir /etc/zfs/zfs-list.cache  
ln -s /usr/lib/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d  
systemctl enable zfs-zed.service  
touch /etc/zfs/zfs-list.cache/zroot

Создаём пароль root:

passwd

Создаём пользователя:

useradd -m -G wheel username  passwd username

Разрешаем sudo. Добавляем в /etc/sudoers:

%wheel ALL=(ALL) ALL

Завершаем установку:

exit  
umount /mnt/efi  
zfs umount -a  
zpool export zroot

Настройка после установки.
Чтобы не вводить пароль дважды при загрузке, можно добавить ключ в initramfs.

Создаём файл ключа:

echo '' > /etc/zfs/zroot.key  
chmod 000 /etc/zfs/zroot.key
zfs set keylocation=file:///etc/zfs/zroot.key zroot

Добавляем ключ в /etc/mkinitcpio.conf:

FILES=(/etc/zfs/zroot.key)

Пересобираем initramfs:

mkinitcpio -P

Проверяем:

zfs get keylocation,keyformat zroot

Комментарии (22)


  1. nagibat0r
    14.03.2026 12:05

    При всём уважении, stripe (а это RAID0) в ZFS означает отсутствие избыточности, а Вы целенаправленно выстреливаете себе в ноги, и ещё другим советуете. Любой один диск умирает - пул дохнет, для корневой файловой системы это означает мгновенную потерю системы. Зачем такое делать?


    1. snarkrans Автор
      14.03.2026 12:05

      Так и знал что кто-то это спросит ) Для избыточности у меня есть zfs raid на файловом сервере. Здесь другая задача. На ноутбуке мне нужно место и удобство. stripe нужен для того чтобы не раскидывать директории по разным дискам, и не бегать по дискам в поиске нужных данных, не более того.


      1. nagibat0r
        14.03.2026 12:05

        Ну то есть, переустановка системы в случае отказа одного диска из stripe, это норма? Если так, то ок, но мне всегда казалось, что лучше сделать один раз, чтобы работало исправно)
        Тогда непонятен смысл ZFS. Хочется костыля в виде stripe, подойдет обычный mdadm. ZFS в этом сценарии не дает преимуществ, потому что его сильные стороны - именно целостность и избыточность: mirror, raidz, scrubbing, self-healing. stripe-vdev лишает систему главного свойства ZFS - устойчивости к отказу диска, остается только второстепенное: checksums, snapshots, send/receive, но для корневой системы ноутбука это обычно не оправдывает усложнение стека (zpool, bootloader интеграция, recovery процедуры). Итого технически это выглядит как избыточная сложность. ZFS используется как файловая система поверх конфигурации, где его ключевая архитектурная идея - отказоустойчивые vdev - намеренно сломана. mdadm RAID0 + ext4/xfs дает тот же результат проще и с меньшим количеством точек отказа.


        1. snarkrans Автор
          14.03.2026 12:05

          для этого есть бекап сервер, система и все важное бекапится.


          1. nagibat0r
            14.03.2026 12:05

            И таки, остаётся непонятным, зачем тут нужен ZFS =)


            1. snarkrans Автор
              14.03.2026 12:05

              Да все затем же ) Я должен знать что на сервер улетают не поврежденные файлы а на севре есть избыточность. snapshots, send/receive это тоже не мало. Я не против избыточности, просто место в данном случае важней. Если заменю диски на побольше, можно бдует подумать о зеркале.


            1. snarkrans Автор
              14.03.2026 12:05

              Не убедил? )


              1. nagibat0r
                14.03.2026 12:05

                Нет. С этой схемой при повреждении блока ZFS обнаружит corruption, но исправить его будет нечем. Stripe убирает самую сильную сторону ZFS - self-healing при чтении. Выглядит как ZFS ради ZFS. Mdadm + btrfs или даже просто btrfs могли бы дать те же snapshots и checksums без разрушения модели хранения


                1. snarkrans Автор
                  14.03.2026 12:05

                  Mdadm + Btrfs + LUKS то уже 3х этажный костыль ) С ZFS это делается проше.


                  1. nagibat0r
                    14.03.2026 12:05

                    Прочтите ниже


                1. snarkrans Автор
                  14.03.2026 12:05

                  Еше один аргумент впользу stripe. Ноут я вечно ношу с собой, ноут можно потерять, ноуты вороют так что бекапить все важно на север в любом случае нужно. Зачем тогда избыточность, если всеравно бекапить?


                  1. nagibat0r
                    14.03.2026 12:05

                    Зачем тогда вообще все эти ZFS и прочее?)


                    1. snarkrans Автор
                      14.03.2026 12:05

                      а зачем мне btrfs на ноуте если на сервере zfs? send/rsecive не будет работать )


                      1. nagibat0r
                        14.03.2026 12:05

                        Ну вот это единственная причина. И всё равно весьма странно вот так вот использовать ZFS без одной из его главных киллер-фич =)


              1. nagibat0r
                14.03.2026 12:05

                Собственно, я к чему веду. Всё, что в статье сделано, можно реализовать на одном btrfs, и даже без mdadm. И тем более, без ZFS.

                Btrfs умеет объединять несколько дисков в одну фс. Профиль хранения можно поставить single - это фактически тот же stripe без избыточности.

                Есть checksums блоков, как в ZFS. Есть снапшоты. Есть send/receive для репликации снапшотов. Есть инкрементальные отправки.

                Единственная принципиальная разница - философия реализации и зрелость некоторых механизмов (и то, под вопросом). Но для такой конфигурации (без избыточности, с репликацией на сервер) btrfs покрывает весь функционал. Более того, в Вашем случае btrfs даже логичнее архитектурно, потому что он изначально проектировался как single-node filesystem без обязательной избыточности, тогда как ZFS исторически строится вокруг модели vdev и redundancy.

                Итого, ZFS в этой схеме не дает дополнительных возможностей по сравнению с btrfs, по части self-healing они в этой конфигурации одинаковы (обнаружение есть, восстановления нет), но добавляет более сложную модель хранения и более тяжелый recovery. Поэтому выглядит как использование ZFS ради ZFS


                1. snarkrans Автор
                  14.03.2026 12:05

                  Я в начале статьи упоминал что сначала пробовал btrfs. Но эта чудовищная конструкция из btrfs, raid и luks2 у меня просто не завелась )


        1. SuperSuslik312
          14.03.2026 12:05

          Mdadm RADI0 насколько я знаю не поддерживает диски разных размеров, условно 256Гб+1000Гб. Диск большего объема в этом случае будет ограничен объемом меньшего, тобишь 256Гб, остальные 700+Гб будут неиспользованы. Не знаю как у автора статьи, но в этом сценарии проще именно ZFS stripe использовать, т.к. он такую конфигурацию поддерживает из коробки.


  1. K0Jlya9
    14.03.2026 12:05

    К бтрфс можно пришить второй диск. То есть надо просто установить систему на бтрфс на первый диск, а потом пришить второй. Делается элементарно просто, никаких проблем ни с какими загрузчиками и инсталяторами, будет работать даже на дебиане.

    Я бтрфс использую вообще без всяких фич(снапшотов, сжатия) просто потому что она позволяет такое делать, размеры менять в любом направлении на ходу, диски подключать и отключать, иноды считать не надо, это просто удобнее чем ext4.


    1. snarkrans Автор
      14.03.2026 12:05

      Нужно шифрование и ядро на btrfs, тут просто добавить диск не получится.


      1. 13werwolf13
        14.03.2026 12:05

        не вижу никаких проблем, добавляй шифрованный luks. я так делал, всё работает отлично


        1. snarkrans Автор
          14.03.2026 12:05

          при случае попробую


  1. 13werwolf13
    14.03.2026 12:05

    /boot/efi - mdadm raid1
    / - btrfs raid1
    swap - mdadm raid1
    всё прекрастно работает без извращений с dkms