[Из песочницы] ZFS on CentOS: работа над ошибками

Так как я довольно давно использую ZFS (ещё со времён OpenSolaris), и очень доволен данной ФС в Linux, несмотря на её «неправославную» лицензию, то естественно прочитал свежую статью об установке данной ФС на CentOS.

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

Работа над ошибками, и некоторые полезные советы под катом.
1. Устанавливать ZFS поверх mdadm массива — это излишнее расточительство ресурсов ЦПУ и излишний дисковый ввод-вывод. ZFS сама прекрасно создаст RAID-0/1/5/6(z2)/z3.

2. При использовании GRUB2 совершенно нет никакого смысла в отдельном разделе для /boot. GRUB2, с указанным в статье фиксом, прекрасно грузит ОС, расположенную на ZFS, а также без всяких проблем может прочитать содержимое директории /boot, расположенной в корневой файловой системе.

О том, как это делается

На дисках (предположим, что их два) вам потребуется всего две партиции: одна для GRUB2, одна для дискового пула. Пример разбивки дисков (GPT без UEFI, если будете использовать UEFI, то тип партиции выставляйте соответственно):

Диск 1:

/dev/sda1    2048     206847     204800   100M BIOS boot
/dev/sda2  206848 1953525134 1953318287 931,4G FreeBSD ZFS


Диск 2:

/dev/sdb1    2048     206847     204800   100M BIOS boot
/dev/sdb2  206848 1953525134 1953318287 931,4G FreeBSD ZFS


Создание пула (зеркало):

$ zpool create -o ashift=12 diskpool mirror /dev/sda2 /dev/sdb2


Где diskpool — имя пула, естественно название можно выбрать по вкусу/схеме именования пулов.

Проверяем созданный pool так:

$ zpool status disкpool


Увидим среди прочего:

        NAME        STATE     READ WRITE CKSUM
        diskpool       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda2    ONLINE       0     0     0
            sdb2    ONLINE       0     0     0



Если дисков много (например 4-е), и Вам важна производительность, можно создать RAID-10:

$ zpool create -o ashift=12 diskpool mirror /dev/sda2 /dev/sdb2 mirror /dev/sdc2 /dev/sdd2


При проверке статуса пула увидим:

        NAME        STATE     READ WRITE CKSUM
        diskpool       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda2    ONLINE       0     0     0
            sdb2    ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdc2    ONLINE       0     0     0
            sdd2    ONLINE       0     0     0


Если у вас много дисков и вам нужен более ёмкий RAID:

Примечание

raidz — RAID-5. Oдна P-сумма — по xor

raidz2 — RAID-6. Oдна P-сумма — по xor, одна Q-сумма — код рида-соломона на GF(2^8). GF не честное, оптимизировано для производительности, поэтому содержит 0 и не имеет право называться RAID-6, однако raidz2 рассчитывает Q сумму в 8 раз быстрее, чем RAID-6.

raidz3 — с тройной чётностью (ни разу не заглянул в исходники, чтобы проверить, что используется для создания 3-й суммы)

Создадим RAID5 на 4-х дисках:

$ zpool create -o ashift=12 diskpool raidz /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 



При проверке пула увидим:

        NAME        STATE     READ WRITE CKSUM
        diskpool       ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sda2     ONLINE       0     0     0
            sdb2     ONLINE       0     0     0
            sdc2    ONLINE       0     0     0
            sdd2    ONLINE       0     0     0


Создадим RAID6 на 5-ти дисках:

$ zpool create -o ashift=12 diskpool raidz2 /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 /dev/sde2 


Создадим RAID-50 на 12-ти дисках:

$ zpool create -o ashift=12 diskpool raidz /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 /dev/sde2 /dev/sdf2  raidz /dev/sdh2 /dev/sdi2 /dev/sdj2 /dev/sdk2 /dev/sdl2 /dev/sdm2


Принцип очевиден — любые комбинации доступны. Можете в одном пуле комбинировать разные типы RAID, но никакого смысла в этом естественно нет, a есть ограничения:

1. ARC2 SSD cashe недоступен для пулов, в которых есть зеркало.
2. Смешение разного типа RAID-ов в одном пуле гарантирует непредсказуемость производительности пула (в самом худшем смысле — бутербродом вниз).

Раз уж я упомянул о SSD ARC2 cache:

#/dev/sdf - SSD диск
$ zpool create -o ashift=12 diskpool raidz1 /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 /dev/sde2 cache /dev/sdf


При проверке пула увидим:

        NAME        STATE     READ WRITE CKSUM
        diskpool       ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sda2     ONLINE       0     0     0
            sdb2     ONLINE       0     0     0
            sdc2    ONLINE       0     0     0
            sdd2    ONLINE       0     0     0
        cache
          sdf       ONLINE       0     0     0


При создании пула можно указать дополнительные опции так:

$ zpool create -o ashift=12 -o listsnapshots=on diskpool raidz /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 


Все опции кроме ashift и некоторых feature@ вы сможете поменять уже после создания пула.

Внимание! Если вы используете zfs версии 0.6.5 и выше, то обязательно при создании пула отключите следующие фичи:

feature@spacemap_histogram feature@enabled_txg feature@hole_birth feature@extensible_dataset feature@embedded_data feature@bookmarks feature@filesystem_limits feature@large_blocks

Если они будут включены, то GRUB2 загрузиться с такой ФС пока не сможет. Это новые плюшки, о которых GRUB2 пока ничего не известно.

Итак, создадим пул со всеми нужными нам параметрами:

$ zpool create -o ashift=12 -o listsnapshots=on \
  -о feature@spacemap_histogram=disabled\
  -о feature@enabled_txg=disabled\
  -о feature@hole_birth=disabled\
  -о feature@extensible_dataset=disabled\
  -о feature@embedded_data=disabled\
  -о feature@bookmarks=disabled\
  -о feature@filesystem_limits=disabled\
  -о feature@large_blocks=disabled\
 diskpool raidz /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2 


Также можно указать сразу опции для создаваемых в последствии файловых систем с ключом -O (о них позже).

Теперь необходимо:

1. Создать файловые системы правильно
2. Указать пулу основную корневую систему и при желании альтернативную (очень удобная штука)
3. Установить GRUB2 на все диски пула
4. Прочее

После создания пула у вас по умолчанию есть файловая система, ассоциированная с пулом:

$ zfs list 

NAME                          USED  AVAIL  REFER  MOUNTPOINT
diskpool                       471G   442G   136K  legacy

Если команда zfs list в колонке MOUNTPOINT для этой ФС содержит не «legacy», то это нужно немедленно исправить:

$ zfs set mountpoint=legacy diskpool


Вообще это и есть корневая файловая система, но использовать её мы не будем, а создадим отдельную виртуально-корневую ФС так:

$ zfs create -o utf8only=on -o compression=lz4 -o atime=off -o relatime=on -o acltype=posixacl -o mountpoint=legacy -o xattr=on diskpool/ROOT


Эта ФС тоже не имеет точки монтирования, а также содержит ряд полезных опций, которые будут унаследованы всеми созданными в последствии ФС (если вы не укажете других опций).

Используемые опции
Опции atime=off и relatime=on значительно повысят производительность ФС, соответственно пожертвовав метками времени доступа к файлам.

Опция compression=lz4 включит на ФС «очень производительную» версию алгоритма сжатия lzjb. Где-то даже есть тесты, и, помнится, меня они впечатлили. Включать компрессию или нет — дело не только вкуса, но и комфорта в работе, а также очень сильно зависит от назначения ФС. Об этом, возможно, напишу в последующей статье.

Хотите поддержки utf8 в именах файлов и отсутствие неприятностей с мултиязычHblми наименованиями? Лучший выбор — опция utf8only=on.

Ну и поддержка xattr нужна однозначно (xattr=on). Появление поддержки POSIX ACL (опция acltype=posixacl) в ZFSonLinux я лично встретил как праздник (убейте, но не помню в какой версии добавили эту фичу).


Далее укажем пулу, что это и есть наша загрузочная ФС:

$ zpool set bootfs=diskpool/ROOT


Далее следуем инструкциям оригинальной статьи, в разделе инсталляции OS, со следующими отличиями:

1. Не создаём отдельную ФС /boot и ничего в каталог /boot не монтируем
2. Никаких /etc/fstab пока не используем
3. Выполнение установки GRUB2 на диски стоит изменить следующим образом:

$ grub2-install --modules=zfs  --boot-directory=/boot /dev/sda
$ grub2-install --modules=zfs  --boot-directory=/boot /dev/sdb
$ grub2-mkconfig -o /boot/grub/grub.cfg


4. Перед тем как начнёте пересобирать initramfs, обязательно удалите /mnt/etc/zfs/zpool.cache.

Далее опять всё по инструкции.

Примечания

Использовать алиасы дисковых устройств из каталогов /dev/disk/by-* вовсе не обязательно (каждый диск знает состав пула по wwn). Вы также можете отредактировать /etc/zfs/vdev_id.conf и дать дискам собственные названия с помощью опции alias:

alias disk1      wwn-0x5000c50045957af3-part2
alias disk2      wwn-0x50004cf20b0d7fa0-part2


Если используете multipath, в том же файле добавьте следующие опции:

multipath yes

#       PCI_ID  HBA PORT  CHANNEL NAME
channel 85:00.0 1         A
channel 85:00.0 0         B
channel 86:00.0 1         A
channel 86:00.0 0         B

Естественно, заменив PCI ID для HBA на свой собственный.

Если честно, то установку ZFS на enterprise-дистрибутивы никогда не делал. Причины очевидны. Подвиг kvaps в этом деле также очевиден. Респект.

© Habrahabr.ru