В прошлом году потребовалось мне создать инструкцию по установке операционной системы Ubuntu 18.04. К слову, ничего сложного в установке Ubuntu нет, но есть нюанс: я хотел использовать файловую систему ZFS как базовую. С одной стороны, Ubuntu поддерживает ZFS на уровне ядра, но инсталятора под неё еще нет, но есть инструкция, да:
https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS
Последовательность действий в этой инструкции в целом правильная, но некоторые моменты требуют корректировки. Так что далее не прямой перевод инструкции, а вольный с учетом исправлений, моего опыта работы с ZFS и прочего. Так же я не рассматриваю вопросы шифрования диска и используем MBR загрузчик. Мою же инструкцию по установке можно получить здесь.
0. Подготовка сервера
Первое, что пропущено в инструкции и никак не рассматривается, это то что ZFS не очень хорошо работает с аппаратными RAID массивами, в частности это связано с Write cache, что понятно: файловая система ZFS — журналируемая и требует полного контроля над операциями записи. Так же при использовании готового аппаратного RAID массива теряются возможности ZFS в части Cache, Spare и прочего. Поэтому, все диски требуется перевести в HBA Mode, а при невозможности оного — сделать для каждого диска сделать отдельный RAID и отключить Write Cache контроллера.
Так же, при использовании агрегации сетевых портов можно их отключить на этапе установки, что бы её не усложнять (все дальнейшие операции я произвожу без bonding).
1. Подготовка среды установки
1.1. LiveCD
Как было сказано ранее, к сожалению, еще нет готового установщика Ubuntu с использованием root on ZFS, поэтому установка осуществляется с помощью LiveCD диска:
Качаем отсюда: http://releases.ubuntu.com/18.04/ubuntu-18.04.1-desktop-amd64.iso
При этом я с коллегами пробовал использовать различные образы дисков так как не очень хотелось использовать графическую оболочку, но это ни к чему хорошему не привело.
Загружаемся с LiveCD, выбираем Try Ubuntu и открываем терминал (Ctrl+Alt+T).
1.2. Обновляем и устанавливаем репозитории
'sudo apt-add-repository universe
sudo apt update
Вот тут нас ждет первый облом если сетевые настройки сервера не определяются DHCP. Обновление репозиториев работать не будет, поэтому настроим сеть.
Смотрим сетевые интерфейсы и находим тот через который будем соединятся:
sudo ip a
Настраиваем сетевой интерфейс:
sudo echo "auto {{ NAME }}" >> /etc/network/interfaces
sudo echo "iface {{ NAME }} inet static" >> /etc/network/interfaces
sudo echo " address {{ IP }}" >> /etc/network/interfaces
sudo echo " netmask {{ NETMASK }}" >> /etc/network/interfaces
sudo echo " gateway {{ GATEWAY }}" >> /etc/network/interfaces
sudo service networking restart
И DNS resolver:
sudo echo 'nameserver 8.8.8.8' >> /etc/resolv.conf
Обновляем репозитории:
sudo apt update
1.3. SSH сервер (опционально)
Для удобства установки можно поднять OpenSSH сервер и все дальнейшие операции производить через SSH клиент
Задаем пароль для пользователя ubuntu:
passwd
Это важно! Так как иначе доступ по ssh будет осуществляться без пароля с правами sudo. При этом нельзя устанавливать простой пароль.
Устанавливаем и запускаем OpenSSH:
sudo apt install openssh-server
sudo service ssh start
И в терминале рабочей станции:
ssh ubuntu@{{ ip server }}
1.4. Становимся root
sudo -s
1.5. Устанавливаем поддержку ZFS в среде LiveCD
apt install --yes debootstrap gdisk zfs-initramfs
2. Разметка и форматирование жестких дисков
2.0. Определяем дисковые массивы
В основной инструкции отсутствует важный момент о том — каким образом определять дисковые массивы.
Обычно на серверах количество дисков такое:
- 2 диска;
- 4 диска;
- много дисков;
1 диск не рассматриваем ибо это вообще аномалия.
2.0.1. 2 диска
Тут все просто, один массив MIRROR (RAID1). Если есть еще один третий диск, то можно его поставить в горячий резерв (SPARE) либо собрать RAIDZ массив (RAID5). Но 3 диска в сервере, очень большая редкость.
2.0.2. 4 диска
Если все диски у нас одинаковы, вариантов тут всего три (четвертый RAID0 я в принципе не рассматриваю):
- MIRROR + MIRROR — аналог RAID10 точнее RAID01, так как в ZFS это mirror + mirror. 50% доступного дискового пространства;
- RAIDZ — аналог RAID5. 75% доступного дискового пространства;
- RAIDZ2 — аналог RAID6. 50% доступного дискового пространства;
На практике я использую MIRROR + MIRROR массив, при этом очевидно, что наиболее выгоден RAIDZ массив, так как предоставляет большее дисковое пространство, но есть нюансы
В части отказоустойчивости массивы располагаются в таком порядке (от лучшего к худшему):
- RAIDZ2 — могут быть утеряны два диска, без потери данных;
- MIRROR + MIRROR — может быть утерян один диск без потери данных, и с 66% вероятностью может быть потерян второй диск без потери данных;
- RAIDZ — может быть потерян только один диск без потери данных;
В части скорости работы массивы располагаются в таком порядке:
- MIRROR + MIRROR — как в части записи так и в части чтения;
- RAIDZ — в части записи медленнее, так как кроме записи требуется рассчитать контрольную сумму;
- RAIDZ2 — в части записи еще медленней так как требует расчета более сложных контрольных сумм;
В части скорости работы массива при деградации одного диска:
- MIRROR + MIRROR — при выпадении одного диска по сути теряется только параллельное чтение с одного зеркала, второе зеркало работает без деградации производительности;
- RAIDZ2 — деградация по снижению производительности выше так как требует обратного перерасчета блока из контрольной суммы для 1/4 данных + поиск блока;
- RAIDZ — деградация сильно больше, так как требует обратного перерасчета блока из контрольной суммы для 1/3 данных + поиск блока;
Сравнение характеристик субъективное, но достаточно отражает мой выбор как золотую середину.
При этом надо понимать, что “медленней” и “еще медленней” — это не в разы, а всего на 10-20 % в худшем случае, поэтому, если у вас не оптимизирована база или приложение для работы с дисками, то падение скорости вы в принципе не заметите. Фактор скорости записи следует учитывать только тогда, когда вам действительно это нужно.
2.0.2. Много дисков
Основная проблема заключается в том, что если у нас много дисков и мы хотим сделать один общий массив для всего, то нам потребуется каждый диск размечать с загрузочным сектором либо немного делать финт ушами. На практике, для многодисковых платформ я стараюсь собирать такую конфигурацию:
- 2 SSD диска — делаем зеркало и как основной загрузочный массив с операционной системой и ZFS кешом для второго дискового массива;
- Остальное забиваем SATA или SAS дисками и без разметки собираем ZFS дисковый массив;
Это равно же относится и к 4-х дисковым серверам если мы хотим получить достаточно универсальную платформу;
В случае если диски все одинаковы, и выделить два диска под отдельный массив бессмысленно (например 6 дисков по 8 Tb), то можно сделать загрузочными диски первой группы массива. То есть если вы собираетесь делать массив как: MIRROR + MIRROR + MIRROR или RAIDZ + RAIDZ, то загрузочный сектор размечаем только для первой группы. В принципе, можно разметить вообще только один диск даже для MIRROR и RAIDZ, а остальное подставить в “сыром” виде, ZFS сделает массив по меньшему элементу сам, но в таком случае, при сбое первого диска, вы теряете единственный загрузочный диск, поэтому не стоит так делать.
Важно понимать, что в файловой системе ZFS — stripe это не совсем RAID0, и работает он немного по-другому и не требует одинаковых размеров дисков, поэтому выделение небольшого пространства под загрузочный сектор погоды особо не сделает, главное указать в BIOS правильный диск с которого загружаться.
2.1. Подготовка к разметке и очистка диска
Для разметки диска используется пакет mdadm, ставим его:
apt install --yes mdadm
Смотрим, какие диски у нас в наличии:
lsblk
И чистим их:
sgdisk --zap-all /dev/{{ disk name }}
2.2. Разметка диска
Собственно, загрузочный раздел:
sgdisk -a1 -n1:34:2047 -t1:EF02 /dev/{{ disk name }}
Основной раздел.
Вот тут могут быть вариации: если у вам требуется выделить дополнительный раздел SSD дисков, например, для ZFS Cache или для Aerospike, то основной раздел делаете ограниченного объема:
sgdisk -n2:0:+100GB -t2:BF01 /dev/{{ disk name }}
sgdisk -n3:0:0 -t2:BF01 /dev/{{ disk name }}
Если же используем все пространство, то просто создаем раздел на все оставшееся место:
sgdisk -n2:0:0 -t2:BF01 /dev/{{ disk name }}
Не забываем проверить, как что получилось:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
+-sda1 8:1 0 1007K 0 part
L-sda2 8:2 0 1.8T 0 part
sdb 8:16 0 1.8T 0 disk
+-sdb1 8:17 0 1007K 0 part
L-sdb2 8:18 0 1.8T 0 part
...
2.3. Создание ZFS массива
zpool create -o ashift=12 -O atime=off -O canmount=off -O compression=lz4 -O checksum=fletcher4 -O normalization=formD -m legacy -R /mnt -f tank mirror /dev/{{ disk a part 2}} /dev/{{ disk b part 2}}
Первые же грабли на которые сразу наступил один мой знакомый админ, это то что при создании ZFS массива требуется указывать не диск а раздел на диске, если он специально для этого создан.
Далее, по порядку:
- ashift=12 — использовать размер блока в 4К, в принципе я до сих пор не понимаю, почему зачастую в операционных системах размер блока по умолчанию 512 байт когда как таких дисков уже практически нет;
- atime=off — отключить одновление даты доступа к файлам, всегда выключаю так как эта информация мне никогда особо не требовалась и нагружать лишний раз ядро для этого не требуется;
- canmount=off — запретить возможность монтирования корневого раздела;
- compression=lz4 — включить компрессию данных алгоритмом LZ4. Этот параметр рекомендуется включать не только для экономии дискового пространства, но и для снижения количества операций ввода-вывода. При этом для этого аглоритма сжатия крайне низкая утилизация CPU;
- checksum=fletcher4 — алгоритм контрольных сумм по-умолчанию и так fletcher4 просто лишний раз уточнить стоит;
- normalization=formD — используется для улучшения работы с UTF-8, по факту ограничивая возможность использования имен файлов не UTF-8. Тут уж каждый рашает сам, мы в своей работе всегда используем только кодировку UTF-8;
- xattr=sa — Ускорение работы с расширенными атрибутами. Я не использую эту опцию по причине того, что при использовании этой опции отключается совместимость с другими реализациями OpenZFS (например: FreeBSD). А совместимость с Windows и прочим, нам мне нужна. Тем более что эту опцию можно включить на конечном разделе;
- -m legacy — точка монтирования в никуда, и монтировать корневой раздел не надо;
- -R /mnt — временный префикс монтирования разделов для установки ядра;
- -f — форсировать создание массива. Если до этого на дисках был собран ZFS массив, то команда create не сработает, мало ли, может вы ошиблись и хотите важные данные перетереть;
Имя корневого системного дискового массива я по привычке указываю как tank, хотя в данный момент в среде Linux предпочитают использовать имя rpool (root pool). В своей практике я вообще использую такое именование массивов:
- tank — основной системный массив;
- store — дополнительный массив с большими дисками для хранения данных;
- cache — дополнительный массив из SSD дисков, если основной раздел находится не на них;
И вообще, я крайне рекомендую сразу выработать практику именования чего либо что бы не путаться.
3. Установка системы
3.1. и 3.2. Создание корневой файловой системы
Я специально объединил пункты 3.1. и 3.2. так как считаю, что указание корневого раздела на третьем уровне абсолютно излишне. Вот правда, за несколько лет работы с ZFS мне ни разу не потребовалось производить какие-нибудь манипуляции с корневым разделом. Тем более, есть же снимки, с помощью которых можно делать контрольные точки. Поэтому корневым разделом у меня является tank/root:
zfs create -o mountpoint=/ tank/root
При этом в исходной инструкции обнаруживается первая фатальная ошибка, а именно отсутствие указания загрузочного раздела для дискового массива:
zpool set bootfs=tank/root tank
3.3. Создание дополнительных разделов
В этой части из основной инструкции можно все выкинуть и забыть. Парни явно перестарались с дроблением и опциями из-за чего по ходу дела пришлось кое-что исправлять. Правда, помогло не очень. Так как в дальнейшем проявляются снова проблемы и в конце выясняется что это все-равно не работает, поэтому в пункте 4.11. это еще раз исправляется.
Совсем уж эпично выглядит выделение отдельного радела для /var/games. Мне не жалко, но это явно перебор.
То, что в ZFS разделы создаются просто и поддерживают иерархию, это не значит что следует отказываться от классических директорий. Простой пример: у меня однажды на группе серверов было более 4K ZFS разделов, так было нужно, но перезагрузка сервера замедлялась на несколько минут из-за монтирование этих разделов.
Начнем с чистого листа.
Есть статичные и динамические файловые разделы.
К статичным файловым разделам относятся разделы с программами и их настройками, они наполняются один раз и в процессе работы не изменяются. При этом ранее статичные разделы подразделялись на системные и пользовательские (/usr), но в данный момент в операционных системах семейства Linux они перемешались и разделять их смысла нет никакого, да и не получится.
К динамичным файловым разделам относятся разделы в которых хранятся:
- Временные данные — eq.: tmp, swap;
- Журналы работы — eq.: var/log;
- Пользовательские данные — eq.: home;
- Данные — eq.: var/db и как повезет;
- Прочие результаты работы программ в виде файлов;
В семействах Linux к динамическим разделам относятся /tmp и /var, но это не точно, так как в /var/lib могут попасть, программы и библиотеки, в общем, все смешалось, но тем не менее…
Для начала требуется решить, создавать раздел /tmp на диске или же в памяти как tmpfs. Если создаем на диске, то тогда для него создаем отдельный раздел:
zfs create -o mountpoint=legacy tank/tmp
Опции com.sun:auto-snapshot=false setuid=off ну как бы погоды не сделают, не надо усложнять. А вот со SWAP сделаем позже в п.7.
Выделяем отдельно раздел var:
zfs create -o mountpoint=legacy tank/var
И пользовательские разделы:
zfs create -o mountpoint=/home tank/home
zfs create -o mountpoint=legacy tank/home/root
Пользовательские разделы имеет смысл выделять, так как на практике они периодически забиваются разными артефактами и что бы проще было их мониторить лучше создавать для них отдельные разделы, как и домашнюю директорию пользователя root (особенно для любителей работать под root). Использование квот на пользовательских директориях не только не помогает не засорять дисковое пространство, но и мешает, так как в таких случаях пользователи начинают оставлять артефакты где попало и найти их потом бывает достаточно сложно. Это не лечится, поэтому требуется только контролировать и бить по рукам.
точка монтирования tank/home/root указана как legacy, а не как /root. Это правильно, та как монтирование этого раздела осуществляется в п.4.11
Теперь требуется временно примонтировать наши динамические разделы в /mnt:
cd /mnt/
mkdir var tmp root
mount -t zfs tank/var /mnt/var/
mount -t zfs tank/tmp /mnt/tmp/
mount -t zfs tank/home/root /mnt/root/
3.4 Устанавливаем ядро
В основной инструкции еще пара ненужных команд, не обращаем внимание, видимо артефакты экспериментов:
debootstrap bionic /mnt
В итоге должны получить примерно такую картину:
zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 213M 1.76T 96K legacy
tank/home 208K 1.76T 96K /mnt/home
tank/home/root 112K 1.76T 112K legacy
tank/root 147M 1.76T 147M /mnt
tank/tmp 96K 1.76T 96K legacy
tank/var 64.6M 1.76T 64.6M legacy
Размер пустого раздела 96К соответственно у нас пустым остался только tank/tmp, а в остальные при установке ядра была произведена запись, значит монтирование разделов было осуществлено правильно.
4. Конфигурация системы
4.1. Настраиваем hosts и hostname
echo HOSTNAME > /mnt/etc/hostname
echo “127.0.0.1 localhost” > /mnt/etc/hosts
echo “127.0.0.1 HOSTNAME” >> /mnt/etc/hosts
4.2. Настраиваем сетевой интерфейс
Таки да, у нас тут уже netplan:
nano /mnt/etc/netplan/setup.yaml
network:
version: 2
renderer: networkd
ethernets:
eno2:
dhcp4: no
dhcp6: no
addresses: [ {{ IP }}/{{ netmask }}, ]
gateway4: {{ gateway IP }}
nameservers:
addresses: [8.8.8.8]
4.3. Настраиваем apt репозитории
nano /mnt/etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu/ bionic main restricted universe
deb http://security.ubuntu.com/ubuntu/ bionic-security main restricted universe
deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe
src — не нужны в основном
4.4. Монтируем виртуальные файловые разделы LiveCD и «заходим» в новую систему
mount --rbind /dev /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys /mnt/sys
chroot /mnt /bin/bash --login
требуется использовать именно —rbind, а не —bind
Мы уже в новой системе…
4.5. Настраиваем базовую среду
ln -s /proc/self/mounts /etc/mtab
chmod 1777 /tmp
apt update
Локаль и время:
dpkg-reconfigure locales
* en_US.UTF-8
* ru_RU.UTF-8
dpkg-reconfigure tzdata
И дополнительные редакторы, кому что нравится:
apt install --yes vim nano
4.6. Устанавливаем поддержку ZFS
apt install --yes --no-install-recommends linux-image-generic
apt install --yes zfs-initramfs
4.8. Устанавливаем загрузчик
Как сказано ранее, я использую устаревший MBR:
apt install --yes grub-pc
Во время установки загрузчика требуется выбрать все наши диски которые мы определили как загрузочные, при этом установщик ругнется на все остальные диски кроме первого, соглашаемся и делаем п.5 (непонятно почему остальное оставили на потом):
4.8.1. (5.1) Проверяем что корневая файловая система распознается:
grub-probe /
zfs
4.8.2. (5.2) Обновляем initrd
update-initramfs -u -k al
4.8.3. (5.3) Упрощаем отладку GRUB
vi /etc/default/grub
...
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="console"
...
4.8.4. (5.4.) Обновляем конфигурацию загрузчика
update-grub
4.8.5. (5.5.) Устанавливаем загрузчик на каждый диск которые разметили как загрузочные
grub-install /dev/sda
grub-install /dev/sdb
...
Важно что бы эти команды отработали корректно. Если честно, я не смог хоть раз получить обратное, поэтому не знаю что делать, но скорее всего, если у вас ошибка значит вы при разметке диска (п.2.2.) скорее всего что-то сделали неправильно.
4.8.6. (5.6.) Проверяем, что модуль ZFS установлен
ls /boot/grub/*/zfs.mod
/boot/grub/i386-pc/zfs.mod
4.10. Задаем пароль пользователя root (сложный!)
passwd
И да, поставим сразу openssh, иначе получим сюрприз после рестарта, если работаем удаленно:
apt install --yes openssh-server
Не забываем при этом поправить конфигурацию sshd:
vi /etc/ssh/sshd_config
...
PermitRootLogin yes
...
PasswordAuthentication yes
...
4.11. Исправление монтирования файловых систем
Вот добрались до самого интересного. Дело в том, что монтирование ZFS разделов происходит после старта некоторых демонов (ZFS_INITRD_ADDITIONAL_DATASETS в /etc/default/zfs мы тоже шатали, но безуспешно), которые, в свою очередь самостоятельно создают некоторую структуру в /var начинают заполнять системные журналы. Когда же настает время монтирования ZFS разделов выясняется что точки монтирования не пустые и смонтировать ничего не получается, данные рассыпаются, все плохо. Поэтому требуется указать точки монтирования в /etc/fstab так как systemd в первую очередь ориентируется на них при обращении к папке:
vi /etc/fstab
tank/var /var zfs noatime,nodev 0 0
tank/tmp /tmp zfs noatime,nodev 0 0
tank/home/root /root zfs noatime,nodev 0 0
Остальное до п.6. уже сделано
6. Первая перезагрузка
6.1. Делаем снимок корневого раздела
zfs snapshot tank/root@setup
Толку от него никакого, на практике я ни разу не не шатал корневой раздел системы и ни разу не использовал снимки этого раздела, но тем не менее пусть лежит, может пригодится
6.2. Выходим из chroot
exit
6.3. Отмонтируем разделы LiveCD и экспортируем ZFS массив
cd
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
umount /mnt/root
umount /mnt/var
umount /mnt/tmp
zpool export tank
Экспорт дискового массива требуется для очистки кеша zfs
6.4 Перезагрузка
Перезагрузку лучше делать в терминале LiveCD, так как если вы работает через ssh клиент, перезагрузка через него может привести к «зависанию» сервера.
reboot
Если все-таки что-то пошло не так и сервер в перезагрузку не ушел, то перезагрузку можно делать любым способом, так как ZFS массив экспортирован и повредить его сложно.
6.5. Ждем перезагрузки и заходим как root
6.6. Создаем учетную запись своего пользователя
zfs create tank/home/{{ LOGIN }}
useradd -u {{ UID }} -G adm,sudo -d /home/{{ LOGIN }}/ -s /bin/bash {{ LOGIN }}
cp -a /etc/skel/.[!.]* /home/{{ LOGIN }}
chown -R {{ LOGIN }}:{{ LOGIN }} /home/{{ LOGIN }}
Добавляем публичный ssh ключ пользователю и задаем ему пароль:
su - {{ LOGIN }}
mkdir .ssh
chmod 0700 .ssh
vi .ssh/authorized_keys
exit
passwd {{ LOGIN }}
В OpenSSH убираем возможность авторизоваться root и парольную авторизацию:
vi /etc/ssh/sshd_config
...
PermitRootLogin no
...
PubkeyAuthentication yes
...
PasswordAuthentication no
...
service ssh restart
6.7. 6.8. Уже не требуется
7. Настройка swap
7.1. Создаем раздел ZFS
zfs create -V 32G -b $(getconf PAGESIZE) -o compression=zle -o logbias=throughput -o sync=always -o primarycache=metadata -o secondarycache=none tank/swap
- -V 32G — Размер нашего SWAP, можно определить тот который требуется реально;
- -b $(getconf PAGESIZE) — размер блока (4K c ashift=12);
- compression=zle — выбираем минимальный по ресурсоёмкости алгоритм сжатия, по сути так как размер блока у нас 4К, то сжатия как таковое не даст утилизации по вводу-выводу, но при этом можно будет сэкономить на нулевых блоках;
- logbias=throughput — установка пропускной способности для оптимизации синхронных операций;
- sync=always — всегда синхронизировать запись. Это несколько снижает производительность, но полностью гарантирует достоверность данных;
- primarycache=metadata — кешировать только метаданные, так как из swap не будет производится множественное чтение одного и того же блока;
- secondarycache=none — вторичный кеш вообще отключить по причинам указанным выше;
7.2. Настраиваем раздел подкачки
mkswap -f /dev/zvol/tank/swap
echo /dev/zvol/tank/swap none swap defaults 0 0 >> /etc/fstab
echo RESUME=none > /etc/initramfs-tools/conf.d/resume
7.3. Включаем swap
swapon -av
Далее по инструкции мало чего интересного, так как сильно зависит от предпочтений конкретных администраторов и задач сервера в целом, кроме одного момента, а именно: “Аварийная загрузка”
И не забываем поставить FireWall
R. Аварийная загрузка
Выполняем подготовку среды установки (п.1.)
Во время подготовки происходит импорт ZFS массива, поэтому требуется его переимпортировать, но с правильной точкой монтирования:
zpool export -a
zpool import -N -R /mnt tank
zfs mount -a
Тут, конечно, забыли в исходной инструкции про то, что у нас некоторые разделы монтируются через fstab, но исправим эту ошибку:
mount -t zfs tank/var /mnt/var/
mount -t zfs tank/tmp /mnt/tmp/
mount -t zfs tank/home/root /mnt/root/
Далее, если это требуется, можно сделать chroot как в п.4.4., но не забыть в последствии размонтировать все как в п. 6.3.
D. Динамические разделы
В пункте 3.3. мы рассмотрели вопросы дополнительных разделов и упростили работу с ними относительно исходной инструкции. Это обусловлено в первую очередь тем, что у меня другая практика использования динамических разделов: так, журналы приложений я сохраняю в разделе /spool, а данные храню в разделе /data. Причем при наличии второго дискового массива ZFS эти разделы создаются именно там.
Резюме
- Если вы хотите использовать файловую систему ZFS то сейчас, это ничего не мешает сделать, нужно только немного поработать руками;
- Если у вас мало опыта работы с ZFS, то я бы не рекомендовал сильно усложнять работу с ней в части опций и излишнего дробления разделов, не стоит впадать в крайности. Возможности и функции ZFS — это не замена каких либо классических вещей, а дополнительная возможность;
- Мою инструкцию установки можно получить здесь.
Комментарии (41)
amarao
12.02.2019 14:40Все приличные аппаратные рейды с батарейкой предоставляют полный контроль за кешированием, включая поддержку SYNCHRONIZE CACHE (10), во-вторых, сами рейды следят за батарейкой и в случае проблемы с оной выключают writeback. За многие годы я ни разу не слышал про повреждение данных из-за ребутов на рейдах с wb и батарейкой. Скорее, можно говорить, что из-за периодической проверки батарейки будут неожиданные деградации производительности (из-за включения wt на время теста).
Далее, вы не понимаете, почему многие используют 512 байт. Причина проста — для 512 байт гарантируется атомарность. Если вы сделаете запись в 4к размером на устройство, которое внутри имеет 512-байтные блоки, то если будет авария в середине, вы можете получить partial update, что почти катастрофа для большинства блочных протоколов.
phoinixrw Автор
12.02.2019 14:55Использовать или не использовать аппаратный рейд — дело предпочтений каждого админа, я его не использую так как:
— resilvering на zfs делается быстрее;
— собирать и разбирать пулы можно без перезагрузки сервера;
— не все RAID контроллеры поддерживают сложные массивы или требуются дополнительные лицензии на них;
То что у ZFS периодически возникают проблемы с WriteCache аппаратного контроллера — да бывает и да зависит от контроллера. Как-то работал с контроллером который как бы поддерживал HBA режим, но при этом при перезагрузке сервера менял их порядок, да пришлось включать аппаратный RAID.
В общем, не суть, и публикация не об этом.
Хотите использовать аппаратный RAID на ZFS — используйте, но тогда потеряете часть функционала ZFS по управлению дисками.
Что касается 512 байт — идем сюда: en.wikipedia.org/wiki/Disk_sector
И читаем:
… Newer HDDs use 4096-byte (4 KiB) sectors, which are known as the Advanced Format (AF).
Если у вас старое железо, то да, используйте ashift=9. Но я в своей работе уже не помню когда сталкивался с подобными дисками, все как-то на новом оборудовании развлекаюсь.
kolu4iy
12.02.2019 14:57Кстати, про ssd cache на уровне контроллера… Есть в такой конфигурации сервер под вин, роль обычного файлового сервера. Батарейка конечно есть на контроллере. Так вот: перегруз pdu недавно привел к аварийному выключению стойки в рабочее время, т.е. интенсивность операций чтения-записи была велика. Конкретно в этой конфигурации у нас первый раз в жизни не испортились индексы на антикварном dbf от foxpro. В предыдущих аварийных ситуациях они портились всегда вообще — хлипкие создания. Я прям зауважал хп после этого...
amarao
12.02.2019 15:00… Я несколько раз перечитывал, пока не понял о чём речь. Дополнительный кеш на ssd-устройствах…
… Потому что у ssd есть свой кеш и большинство производителей мамой клянётся, что там батарейка и ничего не потеряется. А выключение writeback на уровне ssd превращает 15к IOPS в 400 (worst case, 4k random, fsync).phoinixrw Автор
12.02.2019 15:17[phoinix@db01 ~]$ gstat dT: 1.043s w: 1.000s L(q) ops/s r/s kBps ms/r w/s kBps ms/w %busy Name 0 1438 156 1419 0.4 1281 26988 0.2 18.4| mfisyspd0 0 1483 161 1082 0.4 1322 29383 0.3 20.5| mfisyspd1 0 2067 178 1034 0.2 1889 29234 0.2 19.4| mfisyspd2 0 2033 144 774 0.3 1889 29234 0.2 21.4| mfisyspd3
Мне сложно сказать что у вас там во что превращается, видимо у вас своя магия…
PERC H730 Mini
4xSSD SAMSUNG 900Gbamarao
12.02.2019 15:26Как увидеть сотни иопсов вместо тысяч на SSD?
hdparm -W 0 /dev/sdx
- mkfs (по вкусу) на него.
- mount /mnt /dev/sdx
fio --name
hostname--blocksize=4k --ioengine=libaio --iodepth=32 --direct=1 --buffered=0 --fsync=1 -- rw=randwrite --filename=/mnt/test --size=1G
Ключевое тут — hdparm -W0 и --fsync=1. Даже топовые nvme'шки сваливаются с сотен kiops в жалкие полторы тысячи.
phoinixrw Автор
12.02.2019 16:03Вы уже определитесь:
>… превращает 15к IOPS в 400
или
>… сваливаются с сотен kiops в жалкие полторы тысячи
Сколько таки IOPS на SSD?
Потому как у меня на fio с Вашими параметрами выдало:
…
iops: min= 3313, max=19582, avg=13246.67, stdev=3838.41, samples=39
…
Это жалкие 13K iops или все таки далеко не 400?
P.S. На разброс особо смотреть не стоит, сервер рабочий и у него своих дел хватает помимо моих тестов.amarao
12.02.2019 16:22Плохо читаете. Я говорил, что обычные ssd — в сотни, топовые nvme — в полторы тысячи (с сотен тысяч).
Ваша конфигурация — это чистые SSD или за ними там батарейка с RAM? Что про него говорит hdparm -W /dev/sdx (если это SSD) или nvme id-ctrl /dev/nvme0 (поле vwc)?phoinixrw Автор
12.02.2019 16:48На чем тестировал, Dell R220 без дополнительного контроллера. Встроенный работает в HBA режиме.
Нету там ни батарейки на RAM.
diskinfo -t /dev/ada0 /dev/ada0 512 # sectorsize 480103981056 # mediasize in bytes (447G) 937703088 # mediasize in sectors 4096 # stripesize 0 # stripeoffset 930261 # Cylinders according to firmware. 16 # Heads according to firmware. 63 # Sectors according to firmware. INTEL SSDSC2BB480G6R # Disk descr. PHWA62960295480FGN # Disk ident. Yes # TRIM/UNMAP support 0 # Rotation rate in RPM Not_Zoned # Zone Mode Seek times: Full stroke: 250 iter in 0.013101 sec = 0.052 msec Half stroke: 250 iter in 0.011557 sec = 0.046 msec Quarter stroke: 500 iter in 0.021420 sec = 0.043 msec Short forward: 400 iter in 0.012800 sec = 0.032 msec Short backward: 400 iter in 0.009990 sec = 0.025 msec Seq outer: 2048 iter in 0.051259 sec = 0.025 msec Seq inner: 2048 iter in 0.051538 sec = 0.025 msec Transfer rates: outside: 102400 kbytes in 0.288353 sec = 355120 kbytes/sec middle: 102400 kbytes in 0.206200 sec = 496605 kbytes/sec inside: 102400 kbytes in 0.206625 sec = 495584 kbytes/sec
P.S. hdparm не дам, т.к. это не Ubuntuamarao
12.02.2019 17:04Ну так вы кеш в SSD выключали или нет? Я ж говорил, что разница между
/dev/sdb: write-caching = 1 (on)
и
/dev/sdb: write-caching = 0 (off)
Разница примерно 20-30 раз.
fsync, write-through сквозь все кеши — и ssd показывают свою реальную производительность, мало затронутую фирмварными ухищрениями.
PS Судя по Rotation rate in RPM = 0, у вас с той стороны не SCSI/SATA SSD, а какое-то гибридное устройство. У обычных SSD rotation должно быть 1.
phoinixrw Автор
12.02.2019 17:18Так, видимо мы говорим о разных вещах.
Write Cache отключается на контроллере, а не на диске.
Отключать Write Cache на диске это прямо моветон.
Видимо требуется дополнительно это указать, поправлю статью.amarao
12.02.2019 17:24Прочитайте что я писал:
… Потому что у ssd есть свой кеш и большинство производителей мамой клянётся, что там батарейка и ничего не потеряется. А выключение writeback на уровне ssd превращает 15к IOPS в 400 (worst case, 4k random, fsync).
А в дополнение скажу, что при работе с одним вендором после жалобы на плохую производительность под ceph'ом, их инженер сильно заинтересовался проблемой (они проигрывали самсунгам в тестах) и… они это поправили. Устроства этого вполне известного вендора стали работать ничуть не хуже самсунгов. Когда я очень удивился и мы разговорились, всё стало понятно. Они сделали «как самсунг». Как именно? Разумеется, writeback, и (что ещё веселее), trimback, т.е. асинхронный trim.
На вопрос «а что станет с устройством» они сказали, что есть конденсатор и они уверены, что успеют скинуть кеши при отключении питания.
Они скидывают кеши при:
а) Исчезновение линка на шине (sata/ssd)
б) Исчезновение ввода питания
в) Прилетающем reset на L1 по SAS/SATA/PCI-E.
При этом они _уверены_, что успеют скинуть. Но тестов на скидывание кеша у них нет.
Другими словами, это такая лотерея, причём лотерея в которой я больше верю производителям рейда. У них хоть батарейка и точно известный протокол по скидыванию горячего кеша при включении устройства (… осложняющимся тем, что диски могли к этому времени быть заменены).phoinixrw Автор
12.02.2019 17:35Мы ушли далеко от темы, да действительно, вендоры обещают что заряда конденсатора хватит, но
Диски находятся в зеркале, то есть заряда конденсатора должно не хватить у обоих.
Мы обсуждаем сферического коня в вакууме, если да кабы.
Публикация не об этом, а о том как установить ZFS на загрузочный раздел.
Для обсуждения вопросов «ZFS pool vs. Raid Controller» тут на Habr наверняка есть отдельная ветка.amarao
12.02.2019 17:46Я к тому, что верить в конденсатор и не верить в батарейку странно. То есть:
либо выключать ВСЕ кеши (тогда мы имеем гарантии записи, если только вендор SSD не *удак и не игнорирует настройки — я такое видел), и тогда наслаждаемся 400 IOPS на средней SSD,
либо я не вижу причины не любить рейды с батарейкой. Делать многотомными их смысла нет, но сделать wb-raid0 на один диск — милое дело. И SSD легче, и деньги за железку тогда не зря уплочены.phoinixrw Автор
12.02.2019 17:56Я ни слова не сказал, что не люблю контроллеры с батарейкой.
Речь о том, что:
"… ZFS не очень хорошо работает с аппаратными RAID массивами, в частности это связано с Write cache..."
И это факт. С какими-то контроллерами хуже, с какими-то лучше. ZFS журналируемая файловая система и отдавать гарантию записи на откуп кому-то еще не хочет по понятным причинам.
И мое мнение относительно того что мне нравится, а что не нравится — фиолетово, либо будет segfault во время записи, либо нет.amarao
12.02.2019 17:59+1Да, именно. Но почему, из всех writeback'ов, наезд только на raid-controller? Если ZFS не хочет отдавать консистентность на откуп сегфолту в чужой фирмвари, то почему тогда мы имеем влюченный writeback на SSD устройствах?
phoinixrw Автор
12.02.2019 17:24$ camcontrol identify ada0 ... media RPM non-rotating ... write cache yes yes ...
RPM = 0 — логично, так как не крутится, с чего ему даже быть 1
А write cache диска действительно включен.amarao
12.02.2019 17:44rpm=0 было зарезервировано за композитными устройствами (типа рейдов и внешних СХД с блочным интерфейсом, iscsi и т.д.), так что для SSD сделали 1.
… Я попытался найти источник… Я не прав, эта штука linux-specific (он использует rpm=1 для обозначения ssd).
По INQUIRY/EVDP ничего такого не видно (пример ниже)
Spoiler headerUnit serial number VPD page:
Unit serial number: S3R0NF0JB22312K
Device Identification VPD page:
Addressed logical unit:
designator type: vendor specific [0x0], code set: ASCII
vendor specific: S3R0NF0JB22312K
designator type: T10 vendor identification, code set: ASCII
vendor id: ATA
vendor specific: Samsung SSD 850 EVO 250GB S3R0NF0JB22312K
designator type: NAA, code set: Binary
0x5002538d42749602
ATA information VPD page:
SAT Vendor identification: linux
SAT Product identification: libata
SAT Product revision level: 3.00
Device signature indicates SATA transport
ATA command IDENTIFY DEVICE response summary:
model: Samsung SSD 850 EVO 250GB
serial number: S3R0NF0JB22312K
firmware revision: EMT03B6Q
Block limits VPD page (SBC):
Write same non-zero (WSNZ): 0
Maximum compare and write length: 0 blocks
Optimal transfer length granularity: 1 blocks
Maximum transfer length: 0 blocks
Optimal transfer length: 0 blocks
Maximum prefetch length: 0 blocks
Maximum unmap LBA count: 0
Maximum unmap block descriptor count: 0
Optimal unmap granularity: 1
Unmap granularity alignment valid: 0
Unmap granularity alignment: 0
Maximum write same length: 0x3fffc0 blocks
Maximum atomic transfer length: 0
Atomic alignment: 0
Atomic transfer length granularity: 0
Maximum atomic transfer length with atomic boundary: 0
Maximum atomic boundary size: 0
Block device characteristics VPD page (SBC):
Non-rotating medium (e.g. solid state)
Product type: Not specified
WABEREQ=0
WACEREQ=0
Nominal form factor: 2.5 inch
ZONED=0
BOCS=0
FUAB=0
VBULS=0
Logical block provisioning VPD page (SBC):
Unmap command supported (LBPU): 0
Write same (16) with unmap bit supported (LBWS): 1
Write same (10) with unmap bit supported (LBWS10): 0
Logical block provisioning read zeros (LBPRZ): 0
Anchored LBAs supported (ANC_SUP): 0
Threshold exponent: 0
Descriptor present (DP): 0
Minimum percentage: 0
Provisioning type: 0
Threshold percentage: 0
kolu4iy
12.02.2019 15:19Криво написал, извините. Собственно, я вот про это: https://m.habr.com/ru/company/hpe/blog/277285/
gecube
12.02.2019 17:59Я дополню, что автор статьи рассказывает небылицы про 512КБ сектора, путая размер с обозначением 512К дисков (т.е. для тех, кто пропустил — есть старые диски с 512 байт сектора, новые диски с 4КБ секторами и переходная модель, которая 4КБ физические сектора, но логически == 512 байт для целей совместимости со старыми ОСями).
amarao
12.02.2019 18:02Я думаю, это опечатка.
Кстати, его уверенность в 4k очень интересная. Я вот открыл первую попавшуюся SSD и вижу:
cat max_hw_sectors_kb
32767
https://www.kernel.org/doc/Documentation/block/queue-sysfs.txt
max_hw_sectors_kb (RO) ---------------------- This is the maximum number of kilobytes supported in a single data transfer.
Так что, почему 4k?
phoinixrw Автор
12.02.2019 19:01512K — Да, это конечно опечатка, спасибо, исправил.
Вопрос про 4K кроме размера блока на диске находится еще в ядре Linux в котором размер блока по-умолчанию 4K.
То что некоторые диски поддерживают размер блока больше, это прекрасная новость, но что бы поддержка стала полной требуется еще немного пересобрать ядро Linux.amarao
12.02.2019 19:57Ох, расскажите мне про это. Первый раз слышу про «пересборку ядра» в контексте размера блоков для блочных устройств. Я всю жизнь считал, что это определяется исключительно клиентом. Мои наблюдения за blktrace и трейсером scsi так же это подтверждали. Я что-то упустил?
DaemonGloom
13.02.2019 07:06Они, кстати, 512e называются, не 512k. Обозначение произошло из-за их значения «512 emulation».
Kozel-007
12.02.2019 15:45-1Так хочется вставить картинку с троллейбусом. Написали бы хоть полслова о том, зачем это всё вообще нужно? Чтобы partition под root не отводить?
phoinixrw Автор
12.02.2019 15:55Если я напишу хоть пол слова на тему: зачем это нужно, набежит стая «хомячков» которые будут объяснять всем: зачем это не нужно.
Каждый волен сам решать, нужно это ему или нет, и если он решит, что это ему нужно то он может воспользоваться данным документом.gecube
12.02.2019 18:06В любом случае, спасибо за статью. Я просто диву даюсь, что до сих пор есть настоящие мужчины в сёлах. Я, честно скажу, не осилил бы такой алгоритм и сломался бы где-то посередине. Реально — ОЧЕНЬ много действий, что доказывает ещё раз, что система zfs не то, чтобы не пригодна к эксплуатации, но ее распространение убито именно этой излишней сложностью. И по ashift — это тоже мощно. Правильно ли я понимаю, что это количество битов для сдвига, чтобы определить размер блока? А разработчики не могли сделать человеческие параметры. Ну, там ashift=4k, чтобы сразу понимать результат, а не ломать мозг?
phoinixrw Автор
12.02.2019 19:08Очень много действий только по причине того, что инсталлятор не поддерживает возможность использования ZFS.
Если вы возьмете тот же Proxmox, то установка с root ZFS у вас займет несколько кликов.
С другой стороны, что мне сильно не понравилось, что исходная инструкция в некоторых местах не корректна, и да вы бы сломались где-то в середине, причем не от усталости а от ошибки.
Однако же, данная инструкция достаточно полезна для понимания особенностей установки в целом.
VitalKoshalew
13.02.2019 04:14RAIDZ — в части записи медленнее, так как кроме записи требуется рассчитать контрольную сумму;
RAIDZ2 — в части записи еще медленней так как требует расчета более сложных контрольных сумм;
Это — результаты замеров или вам так кажется? Суть любой WAFL-системы, не в последнюю очередь, в практической бесплатности RAIDZ2/RAID-DP/RAID-6. Нагрузкой на CPU для расчёта контрольных сум в 2019 году можно пренебречь, тем более что ZFS в любом случае контрольную сумму считает для каждого сектора всегда.
На мой вкус — использовать WAFL-систему с зеркалом — стрелять из пушки по воробьям.
RAIDZ2 — деградация по снижению производительности выше так как требует обратного перерасчета блока из контрольной суммы для 1/4 данных + поиск блока;
RAIDZ — деградация сильно больше, так как требует обратного перерасчета блока из контрольной суммы для 1/3 данных + поиск блока;
Какой «поиск блока»? Это же WAFL, сектора с одним и тем же номером из всех дисков столбца участвуют в создании контрольной суммы, никаких дополнительных seek не должно быть в общем случае.
7. Настройка swap
sync=always — всегда синхронизировать запись. Это несколько снижает производительность, но полностью гарантирует достоверность данных;
Достоверность данных в swap после некорректной перезагрузки? Зачем нам после перезагрузки предыдущий swap?VitalKoshalew
13.02.2019 04:58Под WAFL я имею в виду теоретическую систему размещения данных, а не только оригинальную WAFL® от NetApp®.
Grey4ip
13.02.2019 12:01Спасибо. Интересная статья.
Что насчёт поддержки Trim для SSD у ZoL?
Надо ли проводить дополнительные настройки для уменьшения SSD Write Amplification на разных типах ZFS RAIDZ?phoinixrw Автор
13.02.2019 12:04ZOL у нас сейчас в опытной эксплуатации пока, и сейчас сказать более детально по поддержке чего-либо не могу.
С одной установкой возились неделю.
kolu4iy
Обычно я начинаю немного предвзято относиться к сочетанию слов "сервер", "аппаратный рейд контроллер", "отключите кеш".
Допустим, у меня p420i на hp gen8, есть необходимые лицензии, а также массив собран в конфигурации 6х1тб 15к + ssd cache 480 gb (hp так умеет посредством самого контроллера) + 2gb cache 25/75 на самом контроллере.
Будет ли zfs заметно вкуснее для меня? Если да, то чем?
kolu4iy
Да, 6х1тб в рейд 10, забыл указать
amarao
Быстрее не будет, это точно. У zfs есть несколько крайне важных функций, включая чексумминг данных, которые могут быть интересны для критического хранения, но в целом, zfs — это почти секта. Авторы не хотят его видеть в Linux, Linux пожимает плечами, и только отдельная группа усиленно работает над попыткой притащить одно в другое.
phoinixrw Автор
Да, секта свидетелей ZFS. :-)
BTRFS тоже разрабатывала секта раскольников ZFS
> Авторы не хотят его видеть в Linux, Linux пожимает плечами, и только отдельная группа усиленно работает над попыткой притащить одно в другое.
Авторы чего не хотят видеть это в linux? Авторы zfsonlinux?
Вы вообще в курсе почему ZFS долго не портировалась в Linux?
Почитайте на досуге про лицензии того и другого и суть проблем, а потом высказывайте свое «экспертное» мнение.
amarao
btrfs делалась с прицелом на замену zfs, да. В какой-то момент выдохлась, и хотя сейчас её стабильность сильно выше, чем раньше, я бы сказал, что они ещё не вышли на пик.
Насчёт того, что авторы ZFS (не путать с ZOL) не хотят в Linux — тут sfconservancy.org/blog/2016/feb/25/zfs-and-linux
К сожалению, не могу найти тред, где обсуждалась позиция Linux (комьюнити) про поддержку функций, нужных ZFS. Спор был о том, надо ли в Linux менять что-то, что сделало бы жизнь ZoL легче, и консенсус был, что если авторы ZFS не хотят в Linux, то прикладывать специальные усилия для затаскивания его туда через shim'ы и прочий технолегалайз — это идти прямо против воли авторов ZFS.
phoinixrw Автор
Все меняется в этом мире:
www.opennet.ru/opennews/art.shtml?num=49815
Обсуждение в комментариях лучше не читать :-)
amarao
Я плохо слежу за bsd, но вот в этом треде есть несколько другие мнения на тему «не совсем так». lwn.net/Articles/777717
phoinixrw Автор
С точки зрения скорости работы — сложно сказать будет ли вкуснее или нет, все зависит от целого ряда факторов:
— сколько памяти будет выделяться для кеша ZFS;
— будет ли использоваться SSD кеш на обычном дисковом пуле;
— какие данные будут храниться на дисках, да это важно, так как степень сжатия этих данных будет сильно влиять на IO;
В общем, сравнивать «в лоб» — занятие абсолютно бесполезное, тем более что ZFS это не только программный контроллер дисков, а в первую очередь таки журналируемая файловая система.
kolu4iy
Я вас понял, это действительно вопрос религии: должна ли файловая система только обеспечивать сохранность данных, или что то ещё. Для себя я ответ на вопрос услышал, большое спасибо.