Оновлення Ubuntu 24.04 зламали модулі ядра: правильно перебудуйте initramfs (випадок №28)

Було корисно?

Ви перезавантажуєтеся після «звичайного оновлення безпеки», і сервер відповідає тим же — кидає в оболонку initramfs,
відмовляється змонтувати корінь або засипає вас помилками modprobe, наче за кожну помилку платять гроші.
Продакшн впав, хтось питає «це апаратка?», а ви дивитесь на ядро, яке вже не впізнає власні модулі.

В Ubuntu 24.04 найпоширеніша причина нудна і виправна: ваш initramfs застарів, неповний або збудований під невідповідне ядро,
тож раннє середовище завантаження не може підвантажити потрібні модулі для дисків/мережі. Лікування не містичне.
Це дисциплінована перебудова з перевіркою і з правильним уявленням про те, що initramfs фактично робить.

Як проявляється ця помилка (і чому вона вводить в оману)

«Модулі зламались» — це лінива діагностика, але зазвичай саме це підказує консоль.
В Ubuntu 24.04 варіанти відмов зосереджені навколо раннього завантаження: моменту, коли ядро запущено,
але справжня коренева файловa система ще не змонтована.

Поширені шаблони симптомів

  • Переходить в оболонку initramfs (BusyBox) з повідомленням «ALERT! /dev/… does not exist».
    Ядро не може підвантажити драйвер для зберігання (NVMe, virtio, RAID HBA, dm-crypt, LVM, ZFS) з образу initramfs.
  • Завантаження відбувається, але мережа мертва до пізнього етапу — або назавжди.
    Відсутній модуль NIC або прошивка в initramfs може блокувати root через мережу або iSCSI, або ламати ранні мережеві вимоги.
  • NVIDIA / ZFS / WireGuard / модулі вендора перестали завантажуватись.
    Зазвичай DKMS не збудував модулі для нового ядра або Secure Boot відхиляє неподписані модулі.
  • «Unknown symbol» / «invalid module format» в dmesg.
    Це невідповідність: модуль зібрано під інше ядро, або vermagic не сходиться.
  • Systemd-сервіси падають після завантаження через відсутні модулі, які «колись були».
    Якщо система завантажується з відкатного ядра, а пакети модулів оновлюються до «нового», невідповідність зберігається і проявляється як помилки під час роботи.

Плутанина походить від таймінгу. Коли ви в середовищі initramfs, у вас маленький файловий образ
з мінімальним набором бінарів і модулів ядра. Якщо цей образ неправильний, ядро може бути в порядку, але все одно не дістатися до userspace.
Зазвичай виправлення — перегенерувати образ так, щоб у ньому були потрібні модулі й конфігурація для ядра, з яким ви збираєтесь завантажуватись.

Жарт №1: Initramfs — це як парашут: більшість днів ви забуваєте про нього, але в день, коли він потрібен, хочеться, щоб він був складений правильно.

Корисні факти та контекст (щоб поведінка стала зрозумілою)

Кілька конкретних фактів допоможуть перестати гадати і почати діагностувати. Це не дрібниці — вони пояснюють, чому «вчора працювало» правдоподібно.

  1. initramfs замінило initrd як основний механізм раннього завантаження в Linux.
    Перехід (кілька років тому) важливий, бо initramfs — це cpio-архів, який розпаковується в RAM-файлову систему; він гнучкий і скриптоподібний.
  2. Стандартний інструментарій Ubuntu — це initramfs-tools.
    Деякі дистрибутиви віддають перевагу dracut, але в Ubuntu 24.04 зазвичай працюють з update-initramfs і хуками в /etc/initramfs-tools.
  3. Сумісність модулів ядра прив’язана до «vermagic».
    Якщо vermagic модуля не збігається з запущеним ядром, ви отримаєте «invalid module format» і модуль не завантажиться.
  4. DKMS — це система збірки, а не магічний клей.
    Вона компілює out-of-tree модулі проти встановлених заголовків ядра. Якщо заголовків немає або збірка не вдається, для нового ядра не буде модуля.
  5. Secure Boot може в тіні перетворити завантаження модулів на політичне рішення.
    Якщо Secure Boot увімкнено, неподписані модулі можуть бути відхилені. Ви можете правильно перебудувати initramfs і все одно впасти, якщо підписи не відповідають політиці.
  6. Деякі стекі зберігання потрібні до того, як монтується корінь.
    LVM, dm-crypt, MD RAID, NVMe, virtio-blk/scsi і ZFS можуть знадобитися всередині initramfs. Якщо вони відсутні, ви не дійдете до справжньої файлової системи.
  7. Оновлення мікрокоду CPU можуть змінити поведінку раннього завантаження.
    Мікрокод CPU може бути включений в initramfs; його оновлення здатне змінити таймінги і виявити гонки або залежності від прошивки.
  8. Ubuntu за замовчуванням зберігає кілька ядер встановленими.
    Цей страховий механізм часто дозволяє завантажитись з старішого ядра і відремонтувати initramfs для нового ядра з робочого середовища.
  9. Формати стиснення initramfs різні (gzip, zstd).
    Якщо ви копіюєте образи між системами або експериментуєте зі стисненням, можна отримати помилку «unpacking initramfs failed», яка виглядає як проблема з модулями.

Одна ідея, перефразована від John Allspaw (операції/надійність): Надійність приходить від вивчення того, як системи насправді ламаються, а не від ілюзії, що вони не зламаються.
Ось про що йдеться: перестаньте трактувати initramfs як чорний ящик.

Швидкий план діагностики (перший/другий/третій)

Коли завантаження ламається, ваша мета — не «полагодити все». Мета — знайти вузьке місце в ланцюжку завантаження.
Думайте шарами: прошивка → завантажувач → ядро → initramfs → справжній корінь → сервіси.
Проблеми з модулями зазвичай живуть на рівнях 3–5.

Перший крок: визначте, яке ядро насправді завантажується

  • Якщо ви маєте оболонку, перевірте uname -r.
  • Якщо ні — перевірте GRUB і завантажте старіше ядро, щоб отримати робоче середовище.
  • Рішення: якщо старіше ядро завантажується, у вас є шлях відновлення без рятувальних медіа.

Другий крок: вирішіть, чи це «initramfs не може змонтувати корінь» або «після завантаження відсутні модулі»

  • Якщо ви опинились в initramfs BusyBox з відсутнім пристроєм кореня, це раннє завантаження: вміст/конфіг initramfs або відсутній модуль/прошивка для зберігання.
  • Якщо система завантажується, але окремі модулі відмовляють, це зазвичай DKMS, підписи модулів або невідповідні заголовки ядра.
  • Рішення: для проблем раннього завантаження потрібно перебудувати initramfs для цільового ядра; проблеми часу виконання можуть вимагати перебудови модулів DKMS, а потім регенерації initramfs за потреби.

Третій крок: перевірте невідповідність модуля чи його відсутність

  • «Invalid module format» → невідповідність (неправильна збірка, інше ядро, невідповідні заголовки).
  • «Module not found» → відсутність (не встановлено, не збудовано, не включено в initramfs).
  • Рішення: невідповідність спрямовує до перебудови DKMS/встановлення заголовків; відсутність — до інсталяції пакета і хук-налаштувань для initramfs.

Четвертий крок: перед тим, як витрачати час, перевірте Secure Boot

  • Secure Boot увімкнено + модулі сторонніх постачальників = підписи мають значення.
  • Рішення: або зареєструвати ключ/підписати модулі, або відключити Secure Boot відповідно до політики хоста.

Найшвидший шлях майже завжди: завантажитись з відомо робочого ядра, відремонтувати пакети/заголовки/DKMS, регенерувати initramfs для ядра, яке ви хочете, оновити GRUB і перезавантажитись один раз.
Не перезавантажуйтесь по кілька разів у надії. Це не інженерія; це забобони з додатковими кроками.

Практична модель: ядро, модулі, initramfs, DKMS

Ось модель, яка збереже вас від дорогих припущень.

Ядро і модулі

Образ ядра (vmlinuz) — це основний виконуваний файл. Більшість підтримки обладнання та функцій знаходиться в модульних файлах у
/lib/modules/<kernel-version>/. Ці модулі тісно пов’язані зі збіркою ядра.
Ця прив’язка забезпечується vermagic і версіями символів.

initramfs — це не ваша коренева файлова система

initramfs — це ранній образ файлової системи. Ядро розпаковує його в RAM і запускає /init,
а цей скрипт монтує справжню кореневу файлову систему (ваш диск, RAID, LUKS, ZFS dataset тощо).
Якщо ви не можете завантажити модуль, який говорить з вашим сховищем, ви не зможете змонтувати корінь і зупинитеся на цьому.

Чому оновлення це тригерить

Оновлення ядра зазвичай встановлює:
linux-image-…, linux-modules-… і можливо linux-modules-extra-….
Воно також викликає хуки для регенерації initramfs.
Якщо будь-який із цих кроків не відбувся (закінчився простір, помилка в хуку, збій DKMS, відсутні заголовки, перерваний апгрейд),
ви можете отримати ядро, яке на диску є, але initramfs не містить того, що потрібно для завантаження.

DKMS — типовий підозрюваний

DKMS збирає модулі, такі як ZFS, NVIDIA, VirtualBox, деякі драйвери NIC/RAID вендорів і різні спеціалізовані модулі.
Після оновлення ядра DKMS повинен автоматично скомпілювати модулі для нового ядра.
Але «повинен» — найнебезпечніше слово в оперуванні. Якщо збірка падає, ви можете перезавантажитись у новому ядрі і виявити, що нічого не підвантажується.

Чому допомагає перебудова initramfs (коли зроблена правильно)

Правильна перебудова виконує три речі:

  • Гарантує, що метадані залежностей модулів вірні (вивід depmod відповідає модульній дереву ядра).
  • Гарантує, що потрібні модулі та прошивки включені в образ initramfs для цього ядра.
  • Гарантує, що записи завантажувача вказують на відповідну пару ядро+initramfs.

Якщо ви перебудуєте initramfs для неправильного ядра, або перебудуєте, поки DKMS ще зламаний, ви отримаєте красивий, але абсолютно неправильний артефакт.
Саме так люди потрапляють у цикли перезавантажень.

Практичні завдання: команди, значення виводу, рішення

Цей розділ — суттєва частина. Реальні команди, що ви маєте побачити, і рішення, які потрібно прийняти за результатом.
Використовуйте його як посібник для діагностики. Виконуйте команди від root там, де потрібно.

Завдання 1: Визначити запущене ядро (і чи ви на відкаті)

cr0x@server:~$ uname -r
6.8.0-49-generic

Значення: Це ядро, яке зараз працює. Якщо ви усуваєте помилку завантаження нового ядра,
можливо, ви завантажились зі старішого через GRUB.
Рішення: Збережіть це значення. Ви перебудовуватимете initramfs для ядра, в яке збираєтесь завантажитись, а не обов’язково для того, що працює зараз.

Завдання 2: Перелічити встановлені ядра (щоб знати цільові)

cr0x@server:~$ dpkg -l | awk '/^ii  linux-image-[0-9]/{print $2}' | sort -V
linux-image-6.8.0-49-generic
linux-image-6.8.0-50-generic

Значення: Ці образи ядра встановлені. Ваш зламаний запуск ймовірно пов’язаний з найновішим.
Рішення: Оберіть версію ядра, яку ви хочете виправити (зазвичай останню встановлену).

Завдання 3: Підтвердити наявність образів initramfs для цільового ядра

cr0x@server:~$ ls -lh /boot/initrd.img-6.8.0-50-generic /boot/vmlinuz-6.8.0-50-generic
-rw-r--r-- 1 root root  98M Dec 30 10:12 /boot/initrd.img-6.8.0-50-generic
-rw------- 1 root root  14M Dec 30 10:11 /boot/vmlinuz-6.8.0-50-generic

Значення: Артефакти ядра та initramfs існують. Якщо initrd відсутній або дуже маленький, у вас помилка пакування або хука.
Рішення: Якщо відсутній або підозріло малий — перебудуйте initramfs і перевірте логи хуків.

Завдання 4: Перевірити, чи /boot повний (класичний мовчазний вбивця)

cr0x@server:~$ df -h /boot
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       974M  942M     0 100% /boot

Значення: Немає вільного місця. Оновлення ядра можуть «встановитись», але не записати initramfs, або записати обрізані образи.
Рішення: Звільніть простір перед перебудовою: видаліть старі ядра або збільшіть /boot. Перебудуйте після звільнення місця.

Завдання 5: Знайти останні помилки побудови initramfs в логах

cr0x@server:~$ journalctl -b -1 -u systemd-update-done.service --no-pager
Dec 30 09:58:12 server systemd[1]: Finished Wait for System Update to Complete.
cr0x@server:~$ grep -R "update-initramfs" -n /var/log/apt/term.log | tail -n 20
Log started: 2025-12-30  09:54:18
Setting up linux-image-6.8.0-50-generic (6.8.0-50.51) ...
update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic
W: Possible missing firmware /lib/firmware/i915/skl_dmc_ver1_27.bin for module i915

Значення: Логи APT показують, чи було згенеровано initramfs і чи були попередження про прошивку.
Рішення: Попередження не завжди фатальні, але якщо бачите помилки (I/O errors, місця немає, збій хуків), виправте їх спочатку.

Завдання 6: Перевірити, чи існує каталог модулів для ядра

cr0x@server:~$ ls -ld /lib/modules/6.8.0-50-generic
drwxr-xr-x 6 root root 4096 Dec 30 10:10 /lib/modules/6.8.0-50-generic

Значення: Модулі для цього ядра встановлені.
Рішення: Якщо відсутній — перевстановіть пакети linux-modules-* для цього ядра.

Завдання 7: Перевірити depmod на помилки (метадані залежностей)

cr0x@server:~$ sudo depmod -a 6.8.0-50-generic

Значення: Відсутність виводу — добре. Помилки тут означають, що дерево модулів неконсистентне.
Рішення: Якщо depmod скаржиться на відсутні файли, перевстановіть пакети модулів ядра перед перебудовою initramfs.

Завдання 8: Підтвердити наявність потрібного модуля (приклад для драйвера зберігання)

cr0x@server:~$ modinfo -k 6.8.0-50-generic nvme | sed -n '1,6p'
filename:       /lib/modules/6.8.0-50-generic/kernel/drivers/nvme/host/nvme.ko.zst
license:        GPL
description:    NVM Express block device driver
author:         Matthew Wilcox <willy@linux.intel.com>
alias:          pci:v0000106Bd00002001sv*sd*bc*sc*i*

Значення: Модуль існує на диску для цього ядра.
Рішення: Якщо modinfo не вдається, встановіть відсутній пакет модулів (часто linux-modules-extra) або виправте вибір ядра.

Завдання 9: Перевірити стан DKMS (модулі поза деревом ядра)

cr0x@server:~$ dkms status
zfs/2.2.2, 6.8.0-49-generic, x86_64: installed
zfs/2.2.2, 6.8.0-50-generic, x86_64: built
nvidia/550.90.07, 6.8.0-50-generic, x86_64: install failed

Значення: DKMS-модулі можуть не бути встановлені для нового ядра.
Рішення: Виправте помилки DKMS перед перебудовою initramfs, якщо раннє завантаження залежить від цих модулів (наприклад, ZFS root).

Завдання 10: Підтвердити стан Secure Boot (політика підписів модулів)

cr0x@server:~$ mokutil --sb-state
SecureBoot enabled

Значення: Secure Boot увімкнено. Несторонні модулі можуть не завантажитись.
Рішення: Якщо ваш проблемний модуль — сторонній (NVIDIA, модулі вендора, ZFS DKMS в деяких налаштуваннях), плануйте підписування/реєстрацію ключа MOK або відключення Secure Boot (політичне рішення).

Завдання 11: Переглянути вміст initramfs щодо конкретного модуля

cr0x@server:~$ lsinitramfs /boot/initrd.img-6.8.0-50-generic | grep -E '/nvme\.ko|/zfs\.ko|/virtio_blk\.ko' | head
usr/lib/modules/6.8.0-50-generic/kernel/drivers/nvme/host/nvme.ko.zst

Значення: Initramfs включає модуль. Якщо його немає, раннє завантаження може не побачити пристрій.
Рішення: Якщо потрібні модулі відсутні — змусьте їх включення (конфіг initramfs-tools) і регенеруйте образ.

Завдання 12: Перевірити відображення пристрою кореня (UUID проти імен пристроїв)

cr0x@server:~$ findmnt -no SOURCE /
/dev/mapper/vg0-root
cr0x@server:~$ cat /etc/fstab | sed -n '1,8p'
# /etc/fstab: static file system information.
UUID=8b7f5f4a-2f15-4e5a-a6b3-7c9e0c03c7b0 / ext4 defaults 0 1

Значення: Ви використовуєте UUID (добре). Якщо /etc/fstab використовує сирі імена пристроїв (як /dev/sda3),
завантаження може зламатися при зміні нумерації.
Рішення: Використовуйте UUID/LABELs і переконайтесь, що initramfs має модулі, потрібні для знаходження цих пристроїв.

Завдання 13: Перебудувати initramfs для конкретного ядра (основне виправлення)

cr0x@server:~$ sudo update-initramfs -u -k 6.8.0-50-generic
update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic
W: Possible missing firmware /lib/firmware/amdgpu/gc_11_0_0_mes.bin for module amdgpu

Значення: Образ був перегенерований. Попередження про прошивку можуть бути прийнятними, залежно від апаратури і того, чи потрібен драйвер під час завантаження.
Рішення: Якщо бачите помилки (не попередження) — зупиніться й виправляйте. Якщо прошивка потрібна (наприклад для консолі GPU на деяких системах) — встановіть пакет прошивки.

Завдання 14: Перебудувати всі образи initramfs (корисно після системних виправлень)

cr0x@server:~$ sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-6.8.0-49-generic
update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic

Значення: Всі встановлені ядра отримали свіжі образи initramfs.
Рішення: Використовуйте це після виправлення DKMS або прошивки, щоб і «поточне», і «відкатне» ядро були консистентні.

Завдання 15: Оновити записи GRUB (щоб уникнути завантаження невідповідних артефактів)

cr0x@server:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-50-generic
Found initrd image: /boot/initrd.img-6.8.0-50-generic
Found linux image: /boot/vmlinuz-6.8.0-49-generic
Found initrd image: /boot/initrd.img-6.8.0-49-generic
done

Значення: GRUB бачить відповідні пари ядро і initrd.
Рішення: Якщо GRUB не бачить ваш initrd-образ, ви завантажуєтесь без того, що намагаєтесь виправити. Поверніться до цілісності /boot і іменування.

Завдання 16: Перевірити помилки завантаження модулів у логах ядра

cr0x@server:~$ dmesg -T | egrep -i 'invalid module format|Unknown symbol|module verification failed|failed to load' | tail -n 20
[Mon Dec 30 10:22:41 2025] nvidia: module verification failed: signature and/or required key missing - tainting kernel
[Mon Dec 30 10:22:41 2025] nvidia: loading out-of-tree module taints kernel.

Значення: Це вказує на політику підпису і «заплямування» ядра. Якщо Secure Boot нав’язливий, воно може відмовити в завантаженні замість того, щоб просто заплямувати.
Рішення: Вирішіть, підписувати модулі (бажано для флотів з Secure Boot) або змінити політику Secure Boot для цього класу хостів.

Правильна перебудова initramfs (за сценарієм)

Сценарій A: Система завантажується зі старішого ядра, але найновіше ядро ламається

Це кращий випадок. У вас є стабільний userland для ремонту.
Не «виправляйте» видаленням нового ядра, якщо ви дійсно не в безвихідній ситуації; ви просто відкладете проблему на наступне вікно оновлення.

  1. Звільніть простір у /boot якщо потрібно. Це крок нуль, а не сім.
  2. Переконайтесь, що заголовки для цільового ядра встановлені (особливо якщо задіяний DKMS).
  3. Відремонтуйте DKMS-модулі для цільового ядра.
  4. Перегенеруйте initramfs для цього ядра.
  5. Оновіть GRUB і перезавантажтеся один раз.
cr0x@server:~$ sudo apt-get update
Hit:1 Ubuntu noble InRelease
Reading package lists... Done
cr0x@server:~$ sudo apt-get install -y linux-headers-6.8.0-50-generic
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  linux-headers-6.8.0-50-generic
Setting up linux-headers-6.8.0-50-generic (6.8.0-50.51) ...

Значення: Заголовки присутні. DKMS має шанс успішно збудуватись.
Рішення: Якщо заголовки відсутні, очікуйте раніше виниклих помилок DKMS. Повторіть збірку DKMS зараз.

cr0x@server:~$ sudo dkms autoinstall -k 6.8.0-50-generic
Sign command: /usr/bin/kmodsign
Signing key: /var/lib/shim-signed/mok/MOK.priv
Public certificate (MOK): /var/lib/shim-signed/mok/MOK.der
Installing module zfs/2.2.2 for kernel 6.8.0-50-generic

Значення: DKMS збудував/встановив модулі для цільового ядра. Якщо налаштовано підписування, воно підписує їх.
Рішення: Якщо DKMS падає — читайте лог збірки і виправляйте. Не перебудовуйте initramfs поки DKMS зламаний, якщо від нього залежить раннє завантаження.

cr0x@server:~$ sudo update-initramfs -u -k 6.8.0-50-generic
update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic
cr0x@server:~$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-50-generic
Found initrd image: /boot/initrd.img-6.8.0-50-generic
done

Сценарій B: Опинились в initramfs BusyBox, не вдається змонтувати корінь

Якщо ви вже в підказці initramfs, це обмежене середовище. Мета — зібрати достатньо сигналу, щоб вирішити:
«відсутній модуль/прошивка» чи «неправильний параметр root=» чи «пошкодження файлової системи».

На підказці initramfs перевірте, що ядро бачить і що воно може підвантажити.

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0-50-generic root=UUID=8b7f5f4a-2f15-4e5a-a6b3-7c9e0c03c7b0 ro quiet splash

Значення: Root вказаний за UUID. Добре. Тепер перевірте, чи цей UUID є серед блочних пристроїв.
Рішення: Якщо root вказаний як /dev/sdX і буква змінилась, виправте GRUB/cmdline і fstab, щоб використовувати UUID.

cr0x@server:~$ ls /dev/disk/by-uuid | head
2c1f9b55-0a69-4b59-9c4d-2b0a7dc3c77a

Значення: Якщо ваш root UUID відсутній тут, ядро не бачить диск або таблицю розділів.
Рішення: Це вказує на відсутній драйвер зберігання, відсутню прошивку або апаратну проблему. Перебудуйте initramfs з робочого ядра або використайте рятувальне середовище.

cr0x@server:~$ modprobe nvme
modprobe: module nvme not found in modules.dep

Значення: Initramfs не містить модуля nvme або метаданих залежностей.
Рішення: Потрібно завантажити інше ядро (або рятувалку), переконатись, що linux-modules встановлені, і регенерувати initramfs з включеним nvme.

У цьому сценарії не намагайтесь робити «хитрі» правки в зламаному initramfs, якщо не точно знаєте, що робите.
Зазвичай швидше перезавантажитися в старіше ядро або в режим відновлення, виправити, перебудувати і перезавантажитись.

Сценарій C: ZFS root або «корінь на екзотичному сховищі» відмовляє після оновлення

ZFS — частий випадок, бо часто покладається на out-of-tree модулі (через DKMS) і потрібен ще до того, як монтується корінь.
Якщо модулі ZFS відсутні в initramfs, завантаження зупиниться рано.

Порядок пріоритетів:
стан DKMS → наявність модулів → регенерація initramfs → перевірити, що initramfs містить ZFS → перезавантажитись.

cr0x@server:~$ dkms status | grep -i zfs
zfs/2.2.2, 6.8.0-50-generic, x86_64: installed
cr0x@server:~$ lsinitramfs /boot/initrd.img-6.8.0-50-generic | grep -E '/zfs\.ko|/zcommon\.ko' | head
usr/lib/modules/6.8.0-50-generic/updates/dkms/zfs.ko
usr/lib/modules/6.8.0-50-generic/updates/dkms/zcommon.ko

Значення: Модулі ZFS вбудовано. Якщо їх немає, завантаження перестане до імпорту пулів.
Рішення: Якщо відсутні — переконайтесь, що хуки initramfs-tools для ZFS присутні (стан пакету) і виконайте update-initramfs.

Сценарій D: NVIDIA або інші сторонні модулі відмовляють під час роботи

Для модулів часу виконання initramfs може бути важливим (якщо потрібен ранній KMS, запит LUKS через консоль GPU тощо),
але здебільшого це питання DKMS/підписів.

cr0x@server:~$ dkms status | grep -i nvidia
nvidia/550.90.07, 6.8.0-50-generic, x86_64: installed
cr0x@server:~$ modprobe nvidia
modprobe: ERROR: could not insert 'nvidia': Key was rejected by service

Значення: Відмова за політикою підпису (поширено з Secure Boot). Модуль існує, але йому не довіряють.
Рішення: Підписати модуль з зареєстрованим ключем, зареєструвати MOK або відключити Secure Boot для цієї машини.

Жарт №2: Secure Boot — чудова річ, доки вона не вирішить, що ваш ретельно зібраний модуль «неавторизований», ніби швейцар у клубі ядра.

Три корпоративні історії з практики

1) Інцидент через невірне припущення: «initramfs завжди перебудовується під час оновлення»

Середня компанія керувала флотом Ubuntu-серверів для CI-раннерів і кешів артефактів.
Нічого екзотичного — поки не виявилось, що їхній «стандартний образ» має маленький розділ /boot, успадкований з макету 2018 року.
Він працював роками, бо ядра оновлювались рідко й ніхто не стежив за використанням /boot.

В один вівторок unattended upgrade витягнув нове ядро. Встановлення пакета пройшло, але /boot досяг 100% під час генерації initramfs.
Процес інсталяції зафіксував помилки, але пайплайн апгрейду не позначив це як фатальне. Сервери продовжували працювати на старому ядрі.
Все виглядало зеленим.

Наступне вікно перезавантажень прийшло. Машини перезавантажилися в ядро, для якого initramfs був відсутній або обрізаний.
Половина флоту впала в initramfs BusyBox з відсутніми кореневими пристроями. Інша половина завантажилась тільки через випадковий вибір старого ядра з GRUB.
Інцидент-менеджер припустив «це не initramfs; скрипти пакета виконались».

Виправлення було непримітним: розширити /boot в базовому образі, впровадити перевірку успішності генерації initramfs і зберігати хоча б одне старе ядро як відкат.
Вони також змінили автоматизацію перезавантажень: тепер вона перевіряє наявність пар /boot/vmlinuz і /boot/initrd для дефолтного запису перед рестартом.

Неправильне припущення не було технічною неосвіченістю. Це була операційна лінь: плутання «скрипти пакета виконались» з «отримано валідний артефакт».
В опсах вам не зарахують намір перебудувати initramfs.

2) Оптимізація, яка відгукнулась бумерангом: «Обрізати initramfs заради швидшого завантаження»

Інша організація вела latency-sensitive робочі навантаження і мала звичку скорочувати мілісекунди скрізь, де можна.
Хтось помітив розмір initramfs і вирішив, що це «надмірність». Вони відредагували конфіги initramfs-tools, ставши агресивними:
менше модулів, менше хуків і віра, що udev знайде все пізніше.

На їхньому основному апаратному забезпеченні це працювало деякий час. Час завантаження трохи зменшився. Зміни розгорнули по флоту без гучних обговорень.
Трюк, звісно, у тому, що флот ніколи не однорідний, а реальність любить крайні випадки.

Прибули нові сервери з іншим контролером зберігання, який вимагав модуль, що не входив у вбудоване ядро.
Обрізаний initramfs його не включав. Машини не змогли змонтувати корінь і ніколи не дісталися до конфігураційного менеджменту.
Вони не могли самі вилікуватись, не могли витягнути виправлення і навіть не могли зателефонувати додому.

Постмортем був болісним, бо «оптимізація» була правильною на старому залізі і неправильною на новому.
Урок не в «ніколи не оптимізувати». Він у тому: якщо оптимізуєте ранні артефакти завантаження, має бути апаратно-орієнтований профіль або включати широкі драйвери для зберігання за замовчуванням.
Коректність завантаження важливіша за швидкість. Завжди.

3) Нудна, але правильна практика, що врятувала день: «завжди тримайте відомо робочий шлях завантаження»

Фінансова організація керувала Ubuntu-хостами з зашифрованим коренем і дорогим віддаленим доступом.
Їхнє правило було старої школи: ніколи не видаляти попереднє ядро, поки нове не завантажиться успішно хоча б раз,
і тестувати доступ до консолі щоквартально. Нудно. Передбачувано. Зовсім не гламурно.

Одного циклу оновлення DKMS-модуль не збудувався для найновішого ядра через невідповідність тулчейну.
Initramfs для нового ядра згенерували, але він не містив потрібний модуль для їхнього стеку кореня.
Наступний рестарт перетворив би машину на цеглину.

Але вони не перезавантажувались сліпо. Процес змін включав попередню перевірку:
перевірити стан DKMS для цільового ядра, переконатися, що initramfs містить потрібні модулі, перевірити простір /boot,
і перевірити, що GRUB вказує на відповідну пару ядро+initrd. Попередня перевірка провалилася, тож рестарт відклали.

Вони виправили проблему збірки DKMS, перегенерували initramfs і перезавантажились у контрольованому вікні.
Ніякого простою. Ніяких героїчних дій. Жодної war room. Найкращий інцидент — це той, якого не сталося.

Поширені помилки: симптом → причина → виправлення

1) Переходить в initramfs shell: «ALERT! UUID=… does not exist»

Причина: Драйвер зберігання відсутній в initramfs або initramfs збудований для іншого ядра.
Іноді це відсутній бінар прошивки для пристрою зберігання/NIC.

Виправлення: Завантажтесь у відоме робоче ядро, переконайтесь, що встановлені правильні пакети linux-modules, потім update-initramfs -u -k <target> і update-grub.
Перевірте через lsinitramfs, що потрібний модуль присутній.

2) «Invalid module format» при завантаженні модуля

Причина: Модуль збудовано для іншої версії ядра/параметрів збірки (несумісність vermagic) або є застарілі артефакти DKMS.

Виправлення: Встановіть відповідні заголовки, перебудуйте DKMS-модуль для цільового ядра, запустіть depmod -a <kernel>, потім перебудуйте initramfs.

3) «Key was rejected by service» для NVIDIA/ZFS/модулів вендора

Причина: Secure Boot примусово застосовує політику підпису модулів; модуль неподписаний або підписаний незасвідченим ключем.

Виправлення: Оберіть: зареєструвати Machine Owner Key і підписувати модулі (дружньо для флоту), або відключити Secure Boot (простішої, але політично залежної шлях).
Перебудуйте initramfs, якщо раннє завантаження потребує того модуля.

4) Ядро встановлено, але initrd відсутній або дуже малий

Причина: /boot повний, перерваний апгрейд, помилки файлової системи або збої скриптів хука.

Виправлення: Звільніть місце, запустіть перевірку файлової системи за потреби, заново виконайте update-initramfs. Підтвердіть розмір артефакту й часові позначки.

5) Завантаження працює тільки зі старішим ядром після оновлення

Причина: DKMS не збудувався для нового ядра або відсутній пакет linux-modules-extra для нового ядра.

Виправлення: Відновіть стан DKMS, встановіть відсутні пакети, регенеруйте initramfs і оновіть GRUB.

6) «unpacking initramfs failed» або ранній kernel panic

Причина: Пошкоджений образ initramfs (недостатньо місця при записі, погане сховище або ручні правки), або несумісне програмне забезпечення стиснення.

Виправлення: Створіть initramfs з нуля за допомогою update-initramfs -c -k <kernel>, і перевірте стан файлової системи /boot та наявність вільного місця.

7) Корінь змонтований, але пристрої зникають пізніше

Причина: Невідповідність пакетів модулів або відсутній пакет прошивки; initramfs не був перебудований після змін модулів/прошивки.

Виправлення: Встановіть необхідні пакети прошивки, запустіть update-initramfs -u -k all, перезавантажтеся.

Чеклисти / поетапний план

Чеклист 1: Правила «не зробити гірше»

  • Не видаляйте єдине робоче ядро. Тримайте принаймні один відомо робочий запис, поки нове ядро не завантажиться.
  • Не перебудовуйте initramfs, коли /boot повний.
  • Не припускайте, що DKMS успішний, бо APT повернув 0. Перевіряйте стан DKMS.
  • Не змінюйте політику Secure Boot в середині інциденту без фіксації рішення і шляху відкату.
  • Не діагностуйте модулі без підтвердження, яке ядро ви завантажили.

Чеклист 2: Поетапне відновлення, коли можна завантажитись зі старішого ядра

  1. Підтвердьте поточне ядро:

    cr0x@server:~$ uname -r
    6.8.0-49-generic
    

    Рішення: Якщо ви вже на найновішому ядрі, проблема скоріш за все runtime/DKMS/підписування, а не initramfs для іншого ядра.

  2. Визначте цільове ядро, яке хочете завантажити:

    cr0x@server:~$ dpkg -l | awk '/^ii  linux-image-[0-9]/{print $2}' | sort -V | tail -n 2
    linux-image-6.8.0-49-generic
    linux-image-6.8.0-50-generic
    

    Рішення: Ціль зазвичай — найновіше встановлене.

  3. Перевірте простір /boot:

    cr0x@server:~$ df -h /boot
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda2       974M  620M  305M  68% /boot
    

    Рішення: Якщо використання >90%, почистіть старі ядра перед регенерацією.

  4. Переконайтесь, що дерево модулів існує:

    cr0x@server:~$ test -d /lib/modules/6.8.0-50-generic && echo ok
    ok
    

    Рішення: Якщо не ok — перевстановіть пакети модулів ядра.

  5. Переконайтесь, що заголовки є, якщо задіяний DKMS:

    cr0x@server:~$ dpkg -l | awk '/^ii  linux-headers-6.8.0-50-generic/{print $2, $3}'
    linux-headers-6.8.0-50-generic 6.8.0-50.51
    

    Рішення: Якщо відсутні, встановіть заголовки і перезапустіть DKMS.

  6. Відремонтуйте DKMS і перевірте стан:

    cr0x@server:~$ sudo dkms autoinstall -k 6.8.0-50-generic
    Installing module zfs/2.2.2 for kernel 6.8.0-50-generic
    

    Рішення: Якщо з’являються помилки, відкрийте лог збірки DKMS і виправте компіляцію/підписування перед рухом далі.

  7. Перегенеруйте initramfs для цільового ядра:

    cr0x@server:~$ sudo update-initramfs -u -k 6.8.0-50-generic
    update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic
    

    Рішення: Якщо бачите помилки — не перезавантажуйтесь. Виправте помилку. Попередження потребують судження.

  8. Перевірте, що потрібні модулі в initramfs:

    cr0x@server:~$ lsinitramfs /boot/initrd.img-6.8.0-50-generic | grep -E '/(nvme|virtio_blk|dm_crypt|zfs)\.ko' | head
    usr/lib/modules/6.8.0-50-generic/kernel/drivers/nvme/host/nvme.ko.zst
    

    Рішення: Якщо модуль, потрібний для кореня, відсутній — змінюйте конфіг initramfs-tools або встановіть відсутні пакети.

  9. Оновіть конфіг завантажувача:

    cr0x@server:~$ sudo update-grub
    Found linux image: /boot/vmlinuz-6.8.0-50-generic
    Found initrd image: /boot/initrd.img-6.8.0-50-generic
    done
    

    Рішення: Якщо GRUB не бачить initrd — виправте іменування /boot і згенеруйте ще раз.

  10. Перезавантажтесь один раз і підтвердіть:

    cr0x@server:~$ sudo reboot
    ...connection closed...
    

    Рішення: Після завантаження перевірте uname -r і логі модулів на помилки.

Чеклист 3: Якщо треба перебудувати initramfs з рятувального середовища

Використовуйте це, коли не вдається завантажити будь-яке встановлене ядро. Загальні кроки однакові:
змонтуйте root, змонтуйте /boot, зробіть bind-mount для /dev /proc /sys, chroot, потім перебудуйте.
Деталі залежать від вашого стеку зберігання, але дисципліна — та сама.

cr0x@server:~$ sudo mount /dev/mapper/vg0-root /mnt
cr0x@server:~$ sudo mount /dev/sda2 /mnt/boot
cr0x@server:~$ for i in dev proc sys run; do sudo mount --bind /$i /mnt/$i; done
cr0x@server:~$ sudo chroot /mnt /bin/bash
cr0x@server:/# update-initramfs -u -k 6.8.0-50-generic
update-initramfs: Generating /boot/initrd.img-6.8.0-50-generic
cr0x@server:/# update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-50-generic
Found initrd image: /boot/initrd.img-6.8.0-50-generic
done

Рішення: Якщо update-initramfs падає всередині chroot, виправляйте стан пакетів (заголовки, модулі, DKMS) всередині chroot, а не в rescue-OS.

Питання й відповіді (FAQ)

1) Використовувати update-initramfs -u -k all чи націлитися на одне ядро?

Націлюйтесь на одне ядро у режимі інциденту, щоб зменшити кількість змінних.
Використовуйте -k all після виправлення системних проблем (DKMS, прошивки), коли хочете узгодженості між fallback-ядрами.

2) У чому різниця між -u і -c для update-initramfs?

-u оновлює існуючий образ initramfs; -c створює новий з нуля.
Якщо підозрюєте корупцію або поганий інкрементальний результат, використовуйте -c для цільового ядра.

3) Я перебудував initramfs, але він все ще не знаходить корінь. Що далі?

Перевірте, чи модуль присутній в initramfs (lsinitramfs | grep), перевірте, чи UUID кореня існує в /dev/disk/by-uuid в оболонці initramfs,
і перевірте командний рядок ядра (/proc/cmdline). Якщо UUID відсутній — ви не маєте драйвера зберігання/прошивки або є реальна апаратна проблема.

4) DKMS показує «built», але не «installed». Чи має це значення?

Так. «Built» означає, що модуль скомпільовано; «installed» означає, що його помістили саме туди, звідки ядро його завантажить, і виконали інтеграцію depmod.
Для критичних модулів завантаження (ZFS root) ви хочете бачити «installed» для цільового ядра.

5) Як визначити, потрібен чи ні linux-modules-extra?

Якщо модуль, якого ви очікуєте (файлова система, драйвер зберігання, рідкісний NIC) відсутній в /lib/modules/<kernel>,
він може жити в пакеті «extra» залежно від пакування Ubuntu.
Перевірте через modinfo -k <kernel> <module>; якщо не вдається — встановіть пакет extra для цього ядра.

6) Чи фатальні попередження про прошивку під час генерації initramfs?

Не автоматично. Вони стають фатальними, якщо прошивка потрібна для ініціалізації обладнання, необхідного для завантаження (деякі диски/NIC).
Якщо система падає рано й попередження згадує ваше сховище або критичний NIC, вважайте це ймовірно релевантним.

7) Я використовую LUKS + LVM. Що перевірити в initramfs?

Переконайтесь, що dm-crypt і утиліти LVM присутні, і що initramfs містить відповідні хуки.
Практично: перевірте, що модулі і бінарні файли є в initramfs і що /etc/crypttab правильний.
Потім регенеруйте initramfs для цільового ядра.

8) Чи можу я зафіксувати старе ядро і ігнорувати нове?

Тимчасово — так, як міра стримування. Операційно це «боргове бомба».
Вам все одно потрібно виправити ланцюжок збірки (DKMS, заголовки, простір /boot, підписування) або ви повторите відмову пізніше в гірших умовах.

9) Що робити, якщо GRUB завантажує неправильне ядро навіть після оновлення?

Підтвердіть, що GRUB вважає дефолтним потрібний запис, регенеруйте конфіг з update-grub і впевніться, що вказаний initrd існує.
Також перевірте ручні правки в /etc/default/grub, які можуть фіксувати старе ядро.

10) Чому це відбувається «випадково» після оновлень?

Це не випадково. Зазвичай це одне з: заповнений /boot, перервані апгрейди, збій збірки DKMS, політика Secure Boot, відсутні заголовки,
або збій хука initramfs. Це детерміновані проблеми з шумними симптомами.

Наступні кроки, які варто виконати

Якщо ви тут, бо продакшн щойно впав, зробіть дисципліноване виправлення:
завантажтесь в відоме робоче ядро, підтвердіть, що /boot має місце, перевірте заголовки і стан DKMS для цільового ядра,
перебудуйте initramfs для цього ядра, переконайтесь, що потрібні модулі вбудовані, оновіть GRUB, перезавантажтесь один раз.
Нічого зайвого. Нічого менше.

Потім запобігайте повторенню. Додайте перевірки в процеси оновлення і рестарту:
оповіщення про використання /boot, трактування помилок генерації initramfs як фейлів, перевірка стану DKMS для кожного ядра,
і тримання принаймні одного відкатного ядра доти, доки нове не доведено. Нудні практики не гламурні,
але вони дешевші за простій і менш захопливі, ніж нічні сесії біля консолі.

← Попередня
Сплески затримки диска в Debian/Ubuntu: доведіть, що справа в сховищі, а не в додатку (інструменти + виправлення)
Наступна →
Ubuntu 24.04: SSH працював вчора, тепер «Permission denied» — виправте 5 найпоширеніших причин

Залишити коментар