Установка CentOS на ZFS в UEFI

fcc619ae4bb7418980f542ed02978583.png

Решил тут на днях попробовать 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 тб каждый, я хочу их разметить таким образом, что бы в итоге на каждом оказалось по три раздела:

  1. efi ( fat16 / 100мб ) — здесь будут хранится файлы конфигурации и сам загрузчик
  2. boot ( ext4 / 412мб ) — эти разделы со всех трех дисков мы объеденим в програмный RAID1, здесь будут лежать ядра и минимальные образы для загрузки системы.
  3. 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

© Habrahabr.ru