Решил тут на днях попробовать ZFS, а подробного и простого мануала как это осуществить на CentOS не нашел, решил исправить ситуацию. К тому же хотелось установить все это в режиме EFI. — не стоять же на месте? И заодно понять для себя как работает DKMS, а так же аспекты ручной установки RPM-based дистрибутивов.
ZFS был выбран тоже не случайно, так как на этой машине планировалось развернуть гипервизор и использовать zvol для хранения образов виртуальных машин. Мне хотелось нечто большего чем програмный рейд + lvm или простое файловое хранение образов, что-нибудь на подобии ceph, но для одного хоста это слишком жирно. Забегая вперед скажу, что я остался очень доволен этой файловой системой, ее производительностью и всеми ее фишками.
Подготовка
Для начала возьмем LiveCD образ CentOS, например из облака yandex, нужен именно live а не netinstall или minimal, так как для установки нам потребуется полностью рабочая система linux. Запишем образ на болванку или флешку и згрузимся с нее. Грузится нужно в efi режиме, в противном случае не получится сохранить загрузочную запись в efi.
Установим epel и zol репозитории:
yum -y install epel-release
yum -y localinstall http://archive.zfsonlinux.org/epel/zfs-release.el7.noarch.rpm
Установим пакет с kernel headers:
yum -y install kernel-devel
Дальше провернем некий финт ушами, без которого zfs попросту не соберется на нашем LiveCD:
rm -f /lib/modules/$(uname -r)/build
ln -s /usr/src/kernels/$(uname -r) /lib/modules/$(uname -r)/build
Теперь можно устанавливать пакет zfs:
yum -y install zfs
После установки пакета проверим установился ли модуль, и если все ок, то загрузим его:
dkms autoinstall
modprobe zfs
Разметка дисков
В моем случае имеется три диска по 2 тб каждый, я хочу их разметить таким образом, что бы в итоге на каждом оказалось по три раздела:
- efi ( fat16 / 100мб ) — здесь будут хранится файлы конфигурации и сам загрузчик
- boot ( ext4 / 412мб ) — эти разделы со всех трех дисков мы объеденим в програмный RAID1, здесь будут лежать ядра и минимальные образы для загрузки системы.
- data ( zfs / все остальное ) — на этих разделах со всех трех дисков мы создадим zpool с RAIDZ, в котором создадим нужные нам разделы с точками монтирования в /, /home и /var и т.д., и установим на них систему.
Приступаем к разметке:
parted /dev/sda
mklabel gpt
mkpart ESP fat16 1MiB 101MiB
set 1 boot on
mkpart boot 101MiB 513MiB
mkpart data 513MiB 100%
Поаторяем тоже самое для /dev/sdb и /dev/sdc. Создаем файловую систему для efi-раздела:
mkfs.msdos -F 16 /dev/sd{a,b,c}1
FAT16 используется не случайно, т.к. размер минимального раздела с FAT32 — 512мб, а это слишком много.
Ок, теперь разбреремся с нашим /boot, создадим програмный RAID из вторых разделов на наших дисках, и сразу же файловую систему на нем:
mdadm --create --verbose /dev/md0 --level=1 --metadata=0.90 --raid-devices=3 /dev/sda2 /dev/sdb2 /dev/sdc2
mkfs.ext4 /dev/md0
Пришло время создать наш zpool, для этой операции рекомендуется обращаться к дискам по ID, вот пример как эта команда выглядела у меня:
zpool create -m none -o ashift=12 rpool raidz /dev/disk/by-id/ata-TOSHIBA_DT01ACA200_74FWM9LKS-part3 /dev/disk/by-id/ata-TOSHIBA_DT01ACA200_74FWMHDKS-part3 /dev/disk/by-id/ata-TOSHIBA_DT01ACA200_74FWR4VKS-part3
Вам только стоит определиться с параметром ashift. Для дисков, размер блока которых равен 512b следует указать параметр ashift=9, для 4k дисков ashift=12. Посмотреть размер блока диска можно командой fdisk -l.
Теперь создадим нужные нам разделы, в zfs это легко:
zfs create -o mountpoint=none rpool/ROOT
zfs create -o mountpoint=/ rpool/ROOT/centos-1
zfs create -o mountpoint=/home rpool/home
zfs create -o mountpoint=/var rpool/var
Готово, диски мы разметили.
Установка системы
Устанавливать будем вручную, так что приступим. Монтируем все наши разделы в /mnt, обратите внимание, что efi раздел мы монтируем только для одного диска, с остальными разберемся позже:
zpool import -o altroot=/mnt rpool
mkdir -p /mnt/boot/efi
mount /dev/md0 /mnt/boot/
mount /dev/sda1 /mnt/boot/efi/
Только что мы подготовили пространство для нашей новой системы. Теперь иницилизируем и установим в нее основной репозиторий, а затем и саму систему с ядром:
rpm --root=/mnt --rebuilddb
curl -O http://mirror.yandex.ru/centos/7/os/x86_64/Packages/centos-release-7-1.1503.el7.centos.2.8.x86_64.rpm
rpm --root /mnt -ivh centos-release-*.rpm
yum -y --installroot=/mnt groupinstall base
yum -y --installroot=/mnt install kernel
Когда гостевая система установится, подключем в нее системные директории хостовой системы и выполняем chroot:
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt /bin/bash --login
Теперь приступим к ее настройке. Запишем DNS-сервер, лучше локальный конечно, что бы заработало разрешение имен:
echo 'nameserver 192.168.225.1' > /etc/resolv.conf
Вновь установим epel и zol репозитории:
yum -y install epel-release
yum -y localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release.el7.noarch.rpm
Да и сам zfs теперь должен установиться без плясок с бубном:
yum -y install kernel-devel zfs
Ок продложаем, установим часовой пояс:
rm -rf /etc/localtime
ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime
Хостнейм, пароль рута:
echo 'one' > /etc/hostname
echo "root:newpass" | chpasswd
Запишем точки монтирования в fstab. Разделы на zfs в fstab добавлять в принципе не нужно:
cat /proc/mounts | grep /boot >> /etc/fstab
Так же необходимо сохранить информацию о нашем рейд-массиве:
mkdir /etc/mdadm
mdadm --examine --scan >> /etc/mdadm/mdadm.conf
Готово, наша система установлена и настроена, теперь разберемся с загрузчиком.
Установка загрузчика
В принципе в случае с efi можно было бы обойтись и без загрузчика т.к. ядро linux уже довольно давно поддерживает EFISTUB (загрузку напрямую через efi без загрузчика), но это не наш случай потому-что: во первых: efi раздел на котором должно будет находится наше ядро нельзя объеденить в програмный рейд а следовательно при каждом обновлении ядра придется копировать этот раздел на остальные диски, во вторых: centos не очень приспособлен к такой загрузке из коробки, рекомендуется все же использовать GRUB2.
Установим GRUB2 для UEFI:
yum -y install grub2-efi
Что бы grub2-install не ругался на zfs-разделы нам нужно скомпировать и установить еще один пакет grub-zfs-fixer:
yum groupinstall "Development Tools"
curl https://codeload.github.com/Rudd-O/zfs-fedora-installer/tar.gz/master | tar xzv
cd zfs-fedora-installer-master/
tar cvzf grub-zfs-fixer.tar.gz grub-zfs-fixer/
rpmbuild -ta grub-zfs-fixer.tar.gz
yum localinstall ~/rpmbuild/RPMS/noarch/grub-zfs-fixer-0.0.3-1.noarch.rpm
Готово, теперь выполним установку GRUB2 и сгенерируем конфиг:
grub2-install
grub2-mkconfig -o /boot/grub/grub.cfg
GRUB2 должен был создать запись в вашем efi, проверим:
efibootmgr -v
Скопируем наш efi-раздел на остальные диски:
dd if=/dev/sda1 of=/dev/sdb1 bs=4M
dd if=/dev/sda1 of=/dev/sdc1 bs=4M
Теперь осталось лишь добавить модуль zfs в initramfs, для этого сделаем:
yum -y install zfs-dracut
dracut -f /boot/initramfs-3.10.0-229.14.1.el7.x86_64.img 3.10.0-229.14.1.el7.x86_64
Обратите внимание, здесь в качестве первого аргумента передается путь к initramfs а в качестве второго версия ядра. Если второй параметр не задать, то образ сгенерируется для текщего запущенного ядра, а так как мы работаем в chroot, его версия будет явно меньше чем установленная в гостевой системе.
На этом все. Выходим из chroot, отмонтируем /mnt. И перезагружаемся в нашу свежеустановленную систему.
exit
umount -R /mnt
reboot
Источники:
HOWTO install Ubuntu to a Native ZFS Root Filesystem
HOWTO install Debian GNU Linux to a Native ZFS Root Filesystem
тема на Google Groups
тема на Hardforum
Комментарии (34)
evg_krsk
13.10.2015 16:37Извиняюсь за глупый вопрос, но правильно ли я понял, что теперь при обновлении grub2-efi потребуется вручную бинарно копировать ESP на два остальных диска? И чем тогда это лучше копирования ядер?
Вы проверяли, что система загружается без каждого из трёх и без двух любых дисков?kvaps
13.10.2015 16:47+2Не совсем, на ESP разделе у вас находится только сам grub (бинарник), а на разделе boot, его конфиг, модули, ядро и initramfs.
При обновлении системы конфиг grub'а обновляется и система грузится с новым ядром.
Копировать раздел ESP на два других нужно только в случае переустановки загрузчика, т.е. выполнения команды grub2-install
Загрузку без диска пока не проверял, без двух работать точно не будет, так как RAID5 позволяет выйти из строя только один диск :)evg_krsk
13.10.2015 17:07mdadm --level=1 это же вроде RAID1 (как и написано в посте), нет? И он то должен выдержать вылет двух дисков из трёх :-)
kvaps
13.10.2015 17:14+1А, вы про mdadm, проверял, только не на этой системе, все грузится и даже работает, mdadm алерты шлет о деградации.
Только в данном случае, без двух дисков загрузка у вас не уйдет дальше initramfs, т.к. все остальное находится уже на RAIDZ (RAID5).
evg_krsk
13.10.2015 17:17Ну и вы уверены, что в этом бинарнике не будет никаких изменений (требующих копирования ESP)? Я почему-то нет.
kvaps
13.10.2015 17:23+1Уверен, в любом другом обычном случае вы grub устанавливаете только 1 раз, при установке самой системы, после этого он у вас не переустановится пока вы не выполните команду grub-install
blind_oracle
13.10.2015 17:27+1Бывает, хоть и редко, что GRUB обновляется. И тогда, если версия в MBR (или EFI) не будет соответствовать тому, что в /boot — можно нарваться на невозможность загрузиться вообще.
evg_krsk
13.10.2015 17:34+1Ну вот на моём дистрибутиве, например, grub-install запускается при каждом обновлении груба (из пост-инстал скриптов). Правда, не в EFI.
Кстати, если будете что-то доставлять в ESP (утилиты диагностики вендора, ещё что...), по хорошему опять не забыть бы скопировать на два диска.kvaps
13.10.2015 17:59Хм, да, похоже что вы правы.
В таком случае, есть идея переопределить grub2-install. Как нибудь так например:
в /usr/local/bin/ создать исполняемый файл grub2-install такого содержания:
#!/bin/bash /usr/sbin/grub2-install ${@} dd if=/dev/sda1 of=/dev/sdb1 bs=4M dd if=/dev/sda1 of=/dev/sdc1 bs=4M
Правда не знаю что из этого выйдет, надо будет попробовать сначала на виртуалке :)evg_krsk
13.10.2015 18:11Дистрибутивно бы как-нибудь такое решать. Даже, пожалуй, кросс-дистрибутивно.
P.S.: наверное, вместо sda1 лучше /dev/disk/by-id/ata-...part1 какой.kvaps
13.10.2015 18:23Разумеется лучше по uuid, я так для примера написал, вообще не факт что это сработает:)
На самом деле крайне жаль, что efi не поддерживает софт-рэйд это решило бы эту проблему. Кстати может быть есть уже где-нибудь такое решение, которое могло бы объединить несколько разделов в софт рэйд, не перезаписывая при этом суперблок — это тоже бы было весьма элегантным решением.
kelevra
13.10.2015 17:25а /boot не получится сделать на ext4? fat16 может очень грустно навернуться в самый неподходящий момент.
blind_oracle
13.10.2015 17:27+2Так у него /boot и так ext4.
А /efi нельзя, т.к. EFI поддерживает только FAT.
ink08
13.10.2015 20:50Держал на соседнем разделе zfs, в один прекрасный момент, пришло обновление на ядро и zfs. После перезагрузки zfs.ko сломался и перестал загружаться.
Nastradamus
14.10.2015 02:22не знаю как в линуксе, но во фре это лечится zpool upgrade, а затем, zfs upgrade. То есть, версии zpool и zfs могли поменяться.
tgz
13.10.2015 21:58Достаточно ли zfs стабилен?
r00tGER
13.10.2015 22:24+1В солярке отлично работает.
На линуксах есть проблемки, как говорили выше, часто вылезают после обновлений.
sudoroot
14.10.2015 08:25с 2008 года в продакшне под FreeBSD, ни одной проблемы, и это меня даже немного напрягает )
BasilioCat
15.10.2015 10:48На FreeBSD большое количество снапшотов приводит к тому, что ядро втыкает, спасает только перезагрузка. Впрочем и 10 снапшотов на сильно загруженной SSD привели к тому же.
Фичи там весьма хороши (особенно репликация), но для максимальной производительности лучше использовать файловые системы попроще.sudoroot
15.10.2015 10:49Можете по подробнее рассказать о проблемах, версии, кол-во снапшотов, coredump?
BasilioCat
15.10.2015 11:01+1Проблема в общем скорее всего звучит так — дедлоки при высокоприоритеной записи. Разместите своп на zvol, и активно им пользуйтесь — получите панику. Версии — 10.0, 10.1, 10.2. Снапшоты — ~80 на zraid2 из 14 sas10k и 10 на страйп из 4х ssd. Кернел был без дебага (продакшен все таки), потому дамп его изучать не было особого смысла.
P.S.: Судя по интернетам, похожие проблемы есть и в zfs on linux
blind_oracle
Один вопрос только — зачем? Зачем ставить CentOS на ZFS?
Разве его не проще поставить на обычную ext4/xfs, а ZFS развернуть рядом?
Если просто потому что можно — тогда вопросов нет :)
kvaps
Вот несколько аргументов:
Это из того что понравилось мне, еще можно выделить такие возможности как подключение отдельного ssd-диска в качестве кэша и т.д.
А вообще вы правы, занялся я этим просто потому что было интересно и просто хотелось переделать свой «уютный маленький сервачек» по человечески. В итоге получилась такая конструкция, что я уверен, если я буду все переделывать еще раз, я сделаю точно так же :)
blind_oracle
По поводу снапшотов соглашусь, в принципе.
В Nexenta, которая являет собой Solaris-ядро + Debian userspace, даже есть утилита apt-clone, которая при обновлении создаёт снапшот корневой ФС на случай чего-то непредвиденного.
kvaps
На своих десктопных компьютерах я сейчас ставлю в основном btrfs, устанавливается из коробки и тоже поддерживает снапштоы, но работать с ней не столь приятно как с zfs. К тому же, в отличии от zfs, она работает только на уровне файловой системы а как следствие жестко привязанна к тому и его размеру. btrfs до zfs к сожалению пока что еще далеко :(
Тем не менее тоже довольно не плохая файловая система…
grossws
Интересен вопрос стабильности btrfs в боевых применениях. У меня пока используется под docker на одном хосте и проблем не было, но этого маловато для оценки)
Ipeacocks
>> в случае обычных фс, может случится необходимость увеличивать размер корневого или любого другого раздела
Ну так сетапать на LVM тогда.
merlin-vrn
Аргумент против: всё это можно сделать в линуксе БЕЗ zfs: lvm — снэпшоты и динамические тома (размер и всё такое), md — raid, luks — шифрование, bcache — кэш ssd. Зато это всё делается слоями, как это принято в unix — каждый слой делает только свою задачу, зато делает её хорошо, а не один универсальный инструмент широкого профиля с миллионом настроек. Так легче за то же время охватить сознанием, «освоить», и как следствие — настроить более надёжно, чем в случае с zfs.