Якщо ви використовуєте ZFS у production, оновлення ядра — це не «поставити патчі, перезавантажитися і готово». Це — «поставити патчі, перевірити все підключення, а потім перезавантажитися». Тому що ZFS — це не просто ще одна файлова система: це щільна взаємозалежність між модулем ядра, користувацькими утилітами, поведінкою initramfs, припущеннями завантажувача та сумісністю фіч-прапорців пулу.
Режим відмови завжди однаковий: ви впевнено перезавантажуєтеся і повертаєтеся до хоста, який не може імпортувати пул, не може змонтувати корінь або зависає в initramfs з почуттям зради. Ось чекліст, який вбереже вас від такої наради.
Ментальна модель: що може зламатися і де
Невдача при оновленні ядра ZFS рідко пов’язана з однією помилкою. Вона походить з припущення. Зазвичай вашого. «Оновлення ядра» насправді — це узгоджена зміна у наступних компонентах:
- Зміни ABI ядра (навіть дрібні), які вимагають відповідного модуля ZFS.
- DKMS або попередньо зібрані kmod-пакети, що будують модуль під час інсталяції.
- Вміст initramfs: чи включені туди модулі й скрипти ZFS, щоб система могла імпортувати пули під час завантаження.
- Конфігурація завантажувача: чи можна швидко обрати старіше ядро, якщо щось піде не так.
- Прапорці функцій пулу: чи зможе пул, створений або оновлений на одній машині, бути імпортованим на іншій (включно в rescue-режимі).
- Версії користувацьких утиліт: невідповідності, що не завжди зупиняють завантаження, але можуть робити операції оманливими.
Ваше завдання — довести, перед перезавантаженням, що:
- Модуль ZFS збудується (або вже збудований) для нового ядра.
- Модуль завантажиться без помилок.
- initramfs містить усе необхідне для імпорту й монтування.
- Пули достатньо здорові, щоб перезавантаження не перетворило «трохи деградований» в «неможливо імпортувати під тиском».
- Ви можете швидко відкотитися без дистанційного доступу або довгого простою.
Цитата, яку варто приклеїти на монітор:
«Надія — це не стратегія.» — Gene Kranz
Ця цитата більше стосується оновлень ядра, ніж космічних польотів. Космічні кораблі не запускають DKMS. А ви — так.
Цікаві факти та історія, що важливі в операційній практиці
Це не тривіальності; вони пояснюють, чому оновлення ZFS відчуваються інакше, ніж оновлення ext4.
- ZFS спроектовано так, щоб володіти стеком зберігання. Воно поєднує управління томами і семантику файлової системи, тому помилки можуть торкатися і шару «відкриття дисків», і шару «монтування» одночасно.
- Прапорці функцій OpenZFS замінили «версію пулу». Прапорці дозволяють пулу еволюціонувати без одного суцільного номера версії, але це також створює тонкі пастки сумісності в rescue-середовищах.
- Linux ZFS знаходиться поза деревом ядра. Це означає, що оновлення ядра може зламати збірку модуля або поведінку завантаження навіть якщо саме ядро в порядку.
- DKMS придумали, щоб зменшити ручну біль при збірці. Він допомагає — поки не зламається під час безлюдних оновлень, залишивши вас з новим ядром і без модуля.
- Завантаження root-on-ZFS сильно залежить від скриптів initramfs. Якщо скрипти або модулі не включені, ядро може завантажитися, але не знайти корінь.
- ZFS кешує відображення пристрій→vdev. Це добре для швидкості, але застарілі кеш-файли або змінені імена пристроїв ускладнюють імпорт під час раннього завантаження.
- Існує hostid з причини. ZFS використовує його, щоб запобігти одночасному імпорту на спільному сховищі; невірний або відсутній hostid може змінити поведінку імпорту несподівано.
- Стиснення і контрольні суми — завжди увімкнені поняття в моделі ZFS. Це робить цілісність даних відмінною, але також означає, що «просто змонтувати» відлагодження менш поблажливе, коли метадані ушкоджені.
- Enterprise-дистрибутиви часто агресивно патчать ядро. «Дрібне» оновлення все ще може змінити ABI для зовнішніх модулів.
Швидкий план діагностики (коли ви вже хвилюєтеся)
Це для моменту після перезавантаження, коли щось не монтується, або ZFS не імпортує, або ви дивитесь на initramfs-проンプт. Не імпровізуйте; ви витратите бюджет простою на занепокоєння.
По-перше: доведіть, чи існує модуль ZFS і чи можна його завантажити
- Питання: Чи присутній модуль ядра ZFS для цього ядра?
- Чому: Якщо його немає, інші кроки ще не мають значення.
cr0x@server:~$ uname -r
6.5.0-28-generic
cr0x@server:~$ modinfo zfs | sed -n '1,8p'
filename: /lib/modules/6.5.0-28-generic/updates/dkms/zfs.ko
version: 2.2.3-1ubuntu1
license: CDDL
description: ZFS filesystem
author: OpenZFS
srcversion: 1A2B3C4D5E6F7A8B9C0D
depends: znvpair,zcommon,zunicode,zzstd,icp,spl
Рішення: Якщо modinfo завершується з «not found», ви у світі відсутніх модулів. Завантажте старіше ядро або перебудуйте/встановіть ZFS для цього ядра. Якщо модуль є, спробуйте завантажити його і прочитайте помилку.
cr0x@server:~$ sudo modprobe zfs
modprobe: ERROR: could not insert 'zfs': Unknown symbol in module, or unknown parameter (see dmesg)
cr0x@server:~$ dmesg | tail -n 15
[ 12.841234] zfs: disagrees about version of symbol module_layout
[ 12.841250] zfs: Unknown symbol spl_kmem_cache_alloc (err -22)
Рішення: «Unknown symbol» зазвичай означає несумісність ABI: неправильна збірка модуля для цього ядра або застарілі модулі. Перебудуйте DKMS або встановіть відповідний kmod-пакет для працюючого ядра. Не намагайтеся «примусово імпортувати». Для відсутніх символів немає прапорця force.
По-друге: доведіть видимість пулу проти його імпортопридатності
cr0x@server:~$ sudo zpool import
pool: tank
id: 1234567890123456789
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
mirror-0 ONLINE
sda3 ONLINE
sdb3 ONLINE
Рішення: Якщо пул перелічений, ZFS працює і бачить vdev. Якщо його немає в списку, ви маєте проблему в виявленні пристроїв (відсутні драйвери, неправильне підключення, помер HBA, неправильні /dev шляхи) або ZFS не запущений.
По-третє: якщо root-on-ZFS, перевірте припущення initramfs
Якщо ви в initramfs без кореня, найшвидше питання: чи включив initramfs ZFS і потрібні скрипти?
cr0x@server:~$ lsmod | grep -E 'zfs|spl'
zfs 6209536 0
spl 163840 1 zfs
Рішення: Якщо ZFS не завантажено в initramfs, ймовірно ви випустили битий initramfs. Завантажте старе ядро/initramfs з GRUB і правильно перебудуйте initramfs.
Жарт №1 (короткий, по суті): Оновлення ядра без плану відкату — як парашут з назвою «v2» у імені файлу: технічно краще, духовно лячно.
Префлайт перед перезавантаженням: задачі з командами, виводом і рішеннями
Далі — набір нудних перевірок, які запобігають драматичним простоям. Кожна задача містить: команду, приклад виводу, що це означає і яке рішення прийняти.
Примітка по сфері: Команди нижче припускають Debian/Ubuntu-подібне середовище з OpenZFS on Linux. Логіка узагальнюється на інші дистрибутиви; деталі пакування — ні.
Задача 1: Підтвердіть, яке ядро зараз і яке ви збираєтесь завантажити
cr0x@server:~$ uname -r
6.2.0-39-generic
cr0x@server:~$ ls -1 /boot/vmlinuz-* | tail -n 3
/boot/vmlinuz-6.2.0-39-generic
/boot/vmlinuz-6.5.0-28-generic
/boot/vmlinuz-6.5.0-31-generic
Що це означає: У вас встановлено декілька ядер; добре. Зазвичай найновіше стане за замовчуванням залежно від конфігурації GRUB.
Рішення: Якщо встановлено лише одне ядро — зупиніться. Встановіть принаймні одне відоме робоче попереднє ядро перед ризиком перезавантаження.
Задача 2: Перевірте узгодженість версій користувацьких утиліт ZFS і пакету модуля
cr0x@server:~$ zfs --version
zfs-2.2.3-1ubuntu1
zfs-kmod-2.2.3-1ubuntu1
Що це означає: Версії утиліт користувача і пакету модуля співпадають. Це не гарантує, що модуль збудований для нового ядра, але дає базову перевірку здорового глузду.
Рішення: Якщо версії дуже розходяться — очікуйте сюрпризів. Вирівняйте їх через пакетний менеджер перед перезавантаженням.
Задача 3: Перевірте статус DKMS для ZFS щодо встановлених ядер
cr0x@server:~$ dkms status | grep -i zfs
zfs/2.2.3, 6.2.0-39-generic, x86_64: installed
zfs/2.2.3, 6.5.0-31-generic, x86_64: installed
Що це означає: DKMS зібрав ZFS для обох — поточного і цільового ядер.
Рішення: Якщо цільового ядра тут немає — не перезавантажуйте. Виправте збірку DKMS поки система ще працює.
Задача 4: Примусова перевірка збірки для нового ядра (бо DKMS іноді мовчить)
cr0x@server:~$ sudo dkms autoinstall -k 6.5.0-31-generic
Sign command: /lib/modules/6.5.0-31-generic/build/scripts/sign-file
Signing key: /var/lib/shim-signed/mok/MOK.priv
Public certificate (MOK): /var/lib/shim-signed/mok/MOK.der
zfs.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/6.5.0-31-generic/updates/dkms/
depmod...
Що це означає: Збірка вдалася; модуль встановлено; depmod запущено.
Рішення: Якщо ви бачите помилки компіляції, відсутні заголовки або «bad return status» — вважайте це критичною перешкодою. Перезавантаження перетворить помилку збірки на простій.
Задача 5: Підтвердіть наявність заголовків для нового ядра
cr0x@server:~$ dpkg -l | grep -E 'linux-headers-6.5.0-31-generic'
ii linux-headers-6.5.0-31-generic 6.5.0-31.31~22.04.1 amd64 Linux kernel headers for version 6.5.0 on 64 bit x86 SMP
Що це означає: Заголовки встановлено, отже DKMS має шанс.
Рішення: Якщо заголовків немає — встановіть їх зараз і повторіть перевірку збірки DKMS.
Задача 6: Перевірте підпис модулів при Secure Boot (якщо застосовано)
cr0x@server:~$ mokutil --sb-state
SecureBoot enabled
cr0x@server:~$ sudo modprobe zfs
modprobe: ERROR: could not insert 'zfs': Key was rejected by service
Що це означає: Модуль є, але не завантажується, бо не підписаний ключем, якому довіряє система (MOK/UEFI).
Рішення: Або підпишіть модуль ZFS відповідним чином і зареєструйте ключ, або вимкніть Secure Boot, якщо політика дозволяє. «Потім розберемося після перезавантаження» — не план, а пастка.
Задача 7: Перевірте здоров’я пулу і лічильники помилок (перезавантаження — не церемонія лікування)
cr0x@server:~$ sudo zpool status -x
all pools are healthy
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
scan: scrub repaired 0B in 00:17:21 with 0 errors on Thu Dec 12 03:27:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda3 ONLINE 0 0 0
sdb3 ONLINE 1 0 0
errors: No known data errors
Що це означає: Навіть якщо пул ONLINE, принаймні один пристрій має помилку читання. Це жовте світло.
Рішення: Якщо будь-який пристрій показує зростання READ/WRITE/CKSUM помилок — розберіться перед перезавантаженням. Під час перезавантаження маргінальні диски можуть вирішити стати перформанс-арту.
Задача 8: Статус scrub і час: чи нещодавно ви валідували пул?
cr0x@server:~$ sudo zpool get -H -o name,value,source autotrim tank
tank on local
cr0x@server:~$ sudo zpool status tank | sed -n '1,12p'
pool: tank
state: ONLINE
scan: scrub repaired 0B in 00:17:21 with 0 errors on Thu Dec 12 03:27:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
Що це означає: У вас був недавній scrub з 0 помилок — це найближче до «відомо доброго», що пропонує ZFS.
Рішення: Якщо останній scrub давній і машина важлива — запустіть його перед вікном обслуговування. Якщо немає часу на повний scrub — принаймні усвідомте, що ви перезавантажуєтеся «в темряві».
Задача 9: Перевірте прапорці функцій, щоб уникнути «працює тут — ламається в rescue»
cr0x@server:~$ sudo zpool get -H -o name,property,value all tank | grep -E 'feature@|compatibility' | head -n 12
tank feature@async_destroy enabled
tank feature@spacemap_histogram enabled
tank feature@extensible_dataset enabled
tank feature@bookmarks enabled
tank feature@embedded_data active
tank feature@device_removal enabled
tank feature@obsolete_counts enabled
tank feature@zstd_compress active
Що це означає: Деякі фічі в стані «active» (використовуються). Rescue-середовище зі старішим OpenZFS може відмовлятися імпортувати або імпортувати лише для читання з попередженнями.
Рішення: Перед оновленнями уникайте випадкового включення нових прапорців пулу. Якщо потрібно — переконайтеся, що rescue-носії та хости для відкату можуть імпортувати пул.
Задача 10: Перевірте, чи сервіси ZFS стартуватимуть чисто під час завантаження
cr0x@server:~$ systemctl status zfs-import-cache.service --no-pager
● zfs-import-cache.service - Import ZFS pools by cache file
Loaded: loaded (/lib/systemd/system/zfs-import-cache.service; enabled)
Active: active (exited) since Thu 2025-12-26 01:12:09 UTC; 2h 11min ago
cr0x@server:~$ systemctl status zfs-mount.service --no-pager
● zfs-mount.service - Mount ZFS filesystems
Loaded: loaded (/lib/systemd/system/zfs-mount.service; enabled)
Active: active (exited) since Thu 2025-12-26 01:12:11 UTC; 2h 11min ago
Що це означає: Ваш поточний шлях завантаження адекватний: пуоли імпортовані, датасети змонтовані.
Рішення: Якщо ці сервіси відключені або падають — виправте це до зміни ядра. Оновлення ядра не час виявляти, що ваш метод імпорту ZFS — «хтось робить це вручну».
Задача 11: Підтвердіть метод імпорту: cachefile vs by-id шляхи
cr0x@server:~$ sudo zpool get cachefile tank
NAME PROPERTY VALUE SOURCE
tank cachefile /etc/zfs/zpool.cache local
cr0x@server:~$ ls -l /etc/zfs/zpool.cache
-rw-r--r-- 1 root root 2270 Dec 26 01:12 /etc/zfs/zpool.cache
Що це означає: Система використовує cachefile для пришвидшення імпорту та збереження відображення пристроїв. Добре — якщо він актуальний.
Рішення: Якщо ви переміщуєте диски/HBA або клонували VM, регенеруйте cachefile свідомо. Застарілі кеш-файли можуть спричинити заплутану поведінку імпорту під час завантаження.
Задача 12: Перегляньте вміст initramfs на предмет модулів і скриптів ZFS (особливо для root-on-ZFS)
cr0x@server:~$ lsinitramfs /boot/initrd.img-6.5.0-31-generic | grep -E 'zfs|spl|zpool' | head -n 12
usr/sbin/zpool
usr/sbin/zfs
usr/share/initramfs-tools/scripts/zfs
usr/share/initramfs-tools/hooks/zfs
lib/modules/6.5.0-31-generic/updates/dkms/zfs.ko
lib/modules/6.5.0-31-generic/updates/dkms/spl.ko
Що це означає: Initramfs включає утиліти користувача ZFS, скрипти та модулі для цього ядра.
Рішення: Якщо ZFS-частини відсутні в initramfs — перебудуйте його зараз і перевірте знову. Інакше ви збираєтесь завантажити ядро, яке не зможе змонтувати потрібні файлові системи.
Задача 13: Перебудуйте initramfs після змін модулю ZFS/ядра
cr0x@server:~$ sudo update-initramfs -u -k 6.5.0-31-generic
update-initramfs: Generating /boot/initrd.img-6.5.0-31-generic
Що це означає: Initramfs згенеровано для цільового ядра.
Рішення: Завжди перебудовуйте initramfs після збірок DKMS або оновлень пакетів ZFS на системах з root-on-ZFS. Розглядайте це як частину інсталяції модуля, а не як опціональний додаток.
Задача 14: Переконайтеся, що GRUB має записи принаймні для одного попереднього ядра
cr0x@server:~$ grep -n "menuentry 'Ubuntu" -n /boot/grub/grub.cfg | head -n 6
148:menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-11111111-2222-3333-4444-555555555555' {
166:menuentry 'Ubuntu, with Linux 6.5.0-31-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-31-generic-advanced-11111111-2222-3333-4444-555555555555' {
184:menuentry 'Ubuntu, with Linux 6.5.0-28-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-28-generic-advanced-11111111-2222-3333-4444-555555555555' {
Що це означає: Меню завантаження містить декілька ядер.
Рішення: Якщо старіших ядер немає в GRUB — додайте їх зараз. Під час аварії ваші пальці забудуть, як вводити «chroot». Вибір через GRUB — швидший вихід.
Задача 15: Зафіксуйте «відомо хороший» стан системи для пізнішого порівняння
cr0x@server:~$ sudo zpool status > /root/pre-reboot-zpool-status.txt
cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint > /root/pre-reboot-zfs-list.txt
Що це означає: Тепер у вас є «до/після» знімки реальності.
Рішення: Завжди фіксуйте це на системах, які доведеться налагоджувати пізніше. Це перетворює «вчора було добре» на доказ.
Задача 16: Перевірте, що властивості рутового датасету і boot pool розумні
cr0x@server:~$ sudo zfs get -o name,property,value -H mountpoint,canmount,readonly -r rpool/ROOT | head -n 10
rpool/ROOT mountpoint / local
rpool/ROOT canmount off local
rpool/ROOT/ubuntu mountpoint / local
rpool/ROOT/ubuntu canmount noauto local
rpool/ROOT/ubuntu readonly off default
Що це означає: Ви використовуєте поширений шаблон root-on-ZFS: батьківський датасет з canmount=off і дочірній рутовий датасет.
Рішення: Якщо mountpoint або прапорці canmount неконсистентні — виправте це перед перезавантаженням. Оновлення ядра їх зазвичай не ламає, але воно виявляє проблеми порядку завантаження, які вже ховалися.
Задача 17: Підтвердіть стабільність hostid (щоб уникнути плутанини при спільному сховищі або клонуванні)
cr0x@server:~$ hostid
7f000001
cr0x@server:~$ sudo zgenhostid -i
/etc/hostid: 7f000001
Що це означає: hostid існує і стабільний.
Рішення: Якщо ви клонували VMs, що можуть бачити одні й ті ж пуоли — забезпечте унікальний hostid. Часто оновлення ядра — це момент, коли клоновані шаблони стають «реальними серверами», а ZFS це запам’ятовує.
Задача 18: Зробіть цільовий snapshot перед зміною ядер (для конфігів і швидких відкатів)
cr0x@server:~$ sudo zfs snapshot -r rpool/ROOT/ubuntu@pre-kernel-upgrade
cr0x@server:~$ sudo zfs list -t snapshot | grep pre-kernel-upgrade | head -n 3
rpool/ROOT/ubuntu@pre-kernel-upgrade 0B -
Що це означає: Ви створили snapshot рутового датасету. На системах з механізмом boot environments це може стати швидким відкатом.
Рішення: Якщо не можете зробити snapshot root (дивна розмітка, політика) — принаймні зробіть резерв /etc і конфігів завантаження. «У нас є бекапи» занадто абстрактно під час інциденту.
Задача 19: Перевірте вільне місце (так, це важливо для оновлень і поведінки ZFS)
cr0x@server:~$ sudo zfs list -o name,used,avail,usedbysnapshots,mountpoint tank
NAME USED AVAIL USEDBYSNAPSHOTS MOUNTPOINT
tank 18.2T 1.14T 3.55T /tank
Що це означає: У вас є резерв. ZFS не любить жити на межі 100%; виділення метаданих і продуктивність псуються.
Рішення: Якщо пул тісний — почистіть спочатку. Оновлення ядра — не найкращий час дізнатися, що пул заповнений і не може коректно виконувати транзакції.
Задача 20: Репетиція доступу через віддалений доступ і консоль як запасний варіант
cr0x@server:~$ sudo systemctl is-active ssh
active
cr0x@server:~$ sudo systemctl is-enabled serial-getty@ttyS0.service
enabled
Що це означає: SSH запущено; серійна консоль налаштована (якщо є). Це не розкіш — це засіб відновлення.
Рішення: Якщо у вас немає OOB-консолі, будьте надзвичайно консервативні: залиште старі ядра, потренуйте відкат і плануйте вікна перезавантажень, коли люди можуть дістатися до машини фізично.
Три корпоративні міні-історії (дуже по суті)
Міні-історія 1: Інцидент через неправильне припущення
У них була невелика ферма аналітичних вузлів. Нічого витонченого: кілька Linux-серверів, кожен з дзеркальною парою для завантаження і великим пулом ZFS для даних. Команда ставилася до оновлень ядра як до рутини — бо роками так і було.
Одного тижня дистрибутив випустив нову лінійку ядер і CI-пайплайн почав її розгортати. Оновлення виглядало чистим. Пакети встановлені, DKMS виводив заспокійливі повідомлення, вікно обслуговування було коротким. Вони перезавантажували вузол за вузлом.
Перший вузол повернувся… в initramfs. Він бачив диски, але не міг імпортувати пул. Паніка пройшла традиційними стежками: хтось сказав «ZFS зламався», хтось — «це HBA», а третя людина почала шукати старі руководства, що припускали ext4.
Реальна проблема була простішою і соромнішою: модуль ZFS збудувався для нового ядра, але Secure Boot відхилив його. Ніхто не перевірив завантаження модуля на хості з увімкненим Secure Boot після ротації ключів. «Неправильне припущення» було не технічним, а процедурним: вони припустили, що середовище незмінне, бо сервери не змінювались.
Відновлення зайняло більше часу, ніж могло б, бо довелося завантажити старіше ядро, зареєструвати правильний ключ, а потім повторно виконати оновлення. Висновок, який лишився: додайте перевірку modprobe zfs як ворота перед перезавантаженням. З ядром, що відмовляється приймати неподписаний код, сперечатися марно.
Міні-історія 2: Оптимізація, що повернулася бумерангом
Інша організація мала культуру продуктивності. Не та, що корисна. Та, де в Slack постять iostat-знімки як спортивні фото. Вони хотіли швидше перезавантаження, швидші імпорти, все швидше.
Хтось помітив, що сканування пристроїв при імпорті пулів «повільне», тому вони примусово ввели імпорт за cachefile скрізь і вимкнули все, що виглядало як зайве. Також вони обрізали initramfs, щоб зменшити розмір, бо менший initramfs має бути швидшим. Так працює логіка в конференц-залах.
Через місяці вони оновили ядра на вузлі зберігання. Саме оновлення пройшло нормально. Але перезавантаження змінило порядок енумерації пристроїв — ще раніше застосували оновлення прошивки HBA. Cachefile досі посилався на старі /dev імена. Раннє завантаження намагалося імпортувати за застарілим відображенням, і через те, що вони обрізали скрипти, fallback-сканування не спрацювало.
Сервер не імпортував пули автоматично. Оператор руками імпортував з -d /dev/disk/by-id, все піднялося, і всі погодилися, що це «дивно». Дивність повторилася на наступному вузлі. «Оптимізація» позбавила стійкості.
Вони виправили це, почавши ставитися до шляхів імпорту як до конфігураційного дрейфу: або покладатися на стабільні by-id шляхи і тримати fallback-сканування увімкненим, або свідомо регенерувати cachefile при зміні апаратури. «Швидше завантаження» — не KPI, що вартий дзвінка вночі.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Велика корпоративна платформа даних. Кілька середовищ. Багато зацікавлених сторін. Команда зі зберігання не була коханою, але її поважали — різниця зазвичай у паперах.
У них був чекліст для оновлень ядра з ZFS. Нічого витонченого. Жорсткий. Він включав «перевірити статус DKMS для цільового ядра», «підтвердити, що initramfs містить zfs.ko», і «перевірити, що GRUB має старий запис ядра». Ніхто не міг його пропустити через «терміновість».
Однієї ночі з’явилося оновлення ядра, що ламало збірки DKMS через невідповідність toolchain у тому образі. Їхній пайплайн це впіймав, бо префлайт включав dkms autoinstall -k як крок валідації. Збірка впала голосно поки система ще працювала, і вузол ніколи не перезавантажився в зламаний стан.
Виправлення було прозаїчне: встановити потрібні заголовки і пакети toolchain, потім перебудувати. Героїчного нічого не було — нікому не довелося бути героєм. Кластер залишився здоровим, вікно обслуговування пройшло тихо, і оновлення вранці було «успішно завершено».
Секрет цієї команди не в експертизі. Він у вимозі робити нудні перевірки завжди, особливо коли все здається простим.
Чеклісти / покроковий план
Користуйтеся цим як ранбуком. Не «адаптуйте вживу». Адаптуйте один раз — у спокійну хвилину — а потім дотримуйтеся.
Покроковий план: безпечна послідовність перезавантаження
- Виберіть ядро для відкату. Переконайтеся, що старіше ядро встановлене і вибирається в GRUB. Якщо не можете його вказати — його немає.
- Перевірте здоров’я пулу.
zpool status -xмає бути чистим або зрозумілим. Будь-який активний resilver, відсутній пристрій або зростаючі лічильники помилок мають відкласти перезавантаження. - Перевірте останній scrub. Якщо система важлива і останній scrub давній — запустіть його перед зміною.
- Встановіть ядро + заголовки. Не розділяйте їх. Ядро без заголовків — рулетка DKMS.
- Підтвердіть збірки DKMS для цільового ядра. Використайте
dkms statusі потім примусовоdkms autoinstall -k. - Протестуйте завантаження модуля на поточній системі (якщо можливо). Ви не зможете завантажити модуль, збудований для іншого ядра, але зможете виявити проблеми Secure Boot/підпису і поточну поведінку модуля.
- Перегенеруйте initramfs для цільового ядра. Потім перевірте його через
lsinitramfs, щоб підтвердити наявність ZFS. - Зробіть snapshot рутових датасетів. Особливо якщо у вас є механізм boot environments. Snapshots дешеві; простий — дорогий.
- Збережіть стани «до». Збережіть
zpool status,zfs listіjournalctl -bдля попередніх завантажень, якщо ви шукаєте інтермітентні проблеми. - Перезавантажте один вузол, спостерігайте, потім продовжуйте. Якщо у вас є кілька машин — зробіть канарку. Якщо ні — ваша канарка — це ви, що дієте обережно.
Мінімальний чекліст «в мене є п’ять хвилин» (використовуйте тільки коли blast radius малий)
zpool status -xчистийdkms status | grep zfsпоказує цільове ядроlsinitramfs /boot/initrd.img-<target> | grep zfs.koзнаходить модуль- GRUB має запис старого ядра
- Ви маєте консольний доступ
Жарт №2 (короткий, по суті): Якщо ваш план відкату — «ми SSH підключимося і виправимо» — ваш план відкату також «ми віримо в магію».
Поширені помилки: симптом → корінна причина → виправлення
1) Завантаження падає в initramfs, рутовий пул не імпортується
Симптом: Ви отримуєте оболонку initramfs. Повідомлення згадують відсутню кореневу файлову систему, помилку імпорту ZFS або «cannot mount rpool».
Корінна причина: initramfs не містить модулів/скриптів ZFS для нового ядра, або модуль ZFS не завантажився (Secure Boot, ABI mismatch).
Виправлення: Завантажте старіше ядро з GRUB. Перебудуйте DKMS для цільового ядра, виконайте update-initramfs -u -k <target>, перевірте через lsinitramfs, потім перезавантажтеся знову.
2) Модуль ZFS існує, але не завантажується: «Unknown symbol»
Симптом: modprobe zfs не вдається; dmesg показує unknown symbols або module_layout mismatch.
Корінна причина: Модуль збудовано проти іншого ядра, застарілі модулі не замінено або часткове оновлення залишило неконсистентні файли у /lib/modules.
Виправлення: Перебудуйте ZFS для того ж ядра: dkms autoinstall -k $(uname -r) (або встановіть правильний kmod). Запустіть depmod -a. Якщо упаковка зламана — перевстановіть пакети ZFS чисто.
3) Завантаження модуля не вдається: «Key was rejected by service»
Симптом: Модуль ZFS не завантажується на системах з Secure Boot.
Корінна причина: Модуль непідписаний або ключ підпису не довірений.
Виправлення: Зареєструйте Machine Owner Key (MOK) і забезпечте підписування модулів DKMS, або вимкніть Secure Boot (якщо політика дозволяє). Перевірте заздалегідь, тестуючи завантаження модуля після перебудови.
4) Пул імпортується вручну, але не автоімпортується при завантаженні
Симптом: Після перезавантаження сервіси піднімаються, але датасети відсутні, поки хтось не виконає zpool import.
Корінна причина: Сервіси zfs-import відключені, cachefile відсутній/застарілий або метод імпорту не відповідає середовищу (наприклад, імена пристроїв змінились).
Виправлення: Увімкніть сервіси імпорту, регенеруйте /etc/zfs/zpool.cache шляхом контролюваного export/import, і віддавайте перевагу стабільним шляхам типу /dev/disk/by-id для імпорту в нетипових середовищах.
5) Пул не імпортується в rescue-середовищі, але імпортується на хості
Симптом: Rescue ISO не може імпортувати; хост може.
Корінна причина: Використовуються прапорці функцій пулу новіші, ніж підтримка rescue-середовища.
Виправлення: Оновлюйте rescue-середовища, щоб вони відповідали вашим прапорцям пулу. Уникайте ввімкнення нових фіч, якщо ви не перевірили інструменти відновлення.
6) Перезавантаження пройшло, але продуктивність впала і зросла затримка
Симптом: Після оновлення ядра зросла затримка введення/виведення; змінилася поведінка ARC; зросло завантаження CPU.
Корінна причина: Нова версія ядра/модуль ZFS по-іншому взаємодіє з обмеженнями пам’яті, cgroup або налаштуваннями. Іноді зміна реальна; іноді моніторинг переїхав.
Виправлення: Порівняйте /proc/spl/kstat/zfs/arcstats до/після, перевірте обмеження пам’яті і налаштування, та відкотіть експерименти з тунінгом. Під час інциденту не оптимізуйте — стабілізуйте.
FAQ
1) Чи справді потрібно перебудовувати initramfs, якщо DKMS каже, що ZFS встановлено?
На системах root-on-ZFS або на будь-яких, що імпортують пули на ранньому етапі завантаження: так. Те, що DKMS збудував модуль, не гарантує, що initramfs його містить. Перевірте через lsinitramfs.
2) Який найкращий індикатор, що перезавантаження пройде успішно?
Для root-on-ZFS: цільовий initramfs містить модулі й скрипти ZFS, і ви можете обрати попереднє ядро в GRUB. Для непотрібного root: DKMS зібрав модуль для цільового ядра і пули здорові.
3) Чи варто вмикати нові прапорці функцій пулу під час рутинного обслуговування?
Не робіть цього без вагомої причини. Прапорці зазвичай односторонні. Вмикайте їх, коли маєте причину і перевірили, що середовища відновлення можуть імпортувати пул.
4) Що безпечніше: використовувати дистро-prebuilt ZFS kmods чи DKMS?
Попередньо зібрані kmod-и можуть бути передбачуванішими, якщо дистро їх добре підтримує. DKMS гнучкий, але додає крок збірки, який може впасти в найгірший момент. Вибирайте за надійністю вашого середовища, не за ідеологією.
5) Як зрозуміти, чи пул ймовірно не імпортується після перезавантаження?
Якщо zpool status показує відсутні пристрої, триваючий resilver, зростаючі checksum-помилки або ви мали нещодавні проблеми з живленням — відкладіть перезавантаження і стабілізуйте систему.
6) Якщо я використовую ZFS тільки для data pool, а не для root — чи все ще це стосується мене?
Система завантажиться навіть якщо ZFS зламається, що приємно. Але ваші застосунки не побачать дані. Чекліст все одно застосовується: перевірте збірку/завантаження модуля і автозапуск сервісів імпорту.
7) Чому зміна імен пристроїв має значення, якщо ZFS використовує GUID?
ZFS відслідковує пристрої за GUID, але поведінка імпорту і записи cachefile все ще можуть залежати від шляхів. На ранньому етапі завантаження або в обмежених rescue-середовищах стабільні шляхи зменшують сюрпризи.
8) Чи можна просто лишити старе ядро назавжди і уникнути проблем?
Можете, поки не змусять — оновлення безпеки, підтримка устаткування та строки підтримки зрештою змусать вас оновлюватися. Стійкий підхід — зробити оновлення прісними, а не уникати їх.
9) Який найшвидший відкат, якщо нове ядро не може імпортувати пули?
Перезавантажте і виберіть попереднє ядро в GRUB. Ось чому ви його тримаєте встановленим і протестованим. Якщо ви не можете дістатися до GRUB — вам потрібен був консольний доступ учора.
10) Чи експортувати пули перед перезавантаженням?
Зазвичай — ні, для локальних дисків на одному вузлі; це може підвищити ризик, якщо сервіси очікують монтування під час завершення роботи. Але на спільному сховищі або з багатопутовими конфігураціями контрольований експорт може зменшити неоднозначність «пул був у використанні». Робіть це свідомо, а не з суєвір’я.
Висновок: практичні наступні кроки
Оновлення ядра ZFS йде не так, коли ви ставитесь до нього як до простого оновлення ОС, а не як до зміни стеку зберігання. Стратегія виживання — послідовна:
- Доведіть, що модуль ZFS існує для цільового ядра (статус DKMS плюс примусова збірка).
- Доведіть, що initramfs містить усе необхідне для завантаження (інспектуйте, не робіть припущень).
- Доведіть, що ваші пули достатньо здорові, щоб пережити стрес (status, свіжість scrub, лічильники помилок).
- Доведіть, що ви можете відкотитися без героїзму (записи GRUB, консоль, snapshots).
Наступного разу, коли плануєте вікно перезавантаження, виконайте префлайт-кроки в порядку, збережіть виводи і ставте будь-який червоний прапорець як стоп. Мета не мужність. Мета — впевненість, підтверджена паперами.