Ви на півдорозі через дзвінок під час інциденту, хтось вставляє лякливий рядок із dmesg,
і раптом розмова перетворюється на теологію: «Ядро tainted».
Половина кімнати вважає, що це означає «дані пошкоджено», інша половина думає «підтримка не допоможе»,
а остання людина тихо перезавантажує не той хост.
У Debian 13 «kernel tainted» — це не моральний вердикт і не автоматичний смертний вирок.
Це діагностична підказка: компактний спосіб для ядра сказати «дякую, налагоджувати мене буде дивно через X».
Іноді варто дуже хвилюватися. Іноді варто просто зробити позначку і рухатися далі.
Що насправді означає «kernel tainted» (і чого це не означає)
Ядро Linux встановлює стан «taint», коли трапляється щось, що може поставити під сумнів
достовірність майбутнього налагодження. Уявіть це як ланцюг збереження доказів.
Якщо ядро згодом «потрапить у біду» (oops, panic, soft lockup), підтримка та SRE хочуть знати:
«Чи працювало ядро в стандартній, підтримуваній конфігурації, чи ми додали інгредієнти, що змінюють поведінку?»
Taint — це бітова маска прапорців. Кожен прапорець відповідає за умову, наприклад:
завантажено пропрієтарний модуль, модуль не пройшов перевірку підпису, ядро зіткнулося з серйозною апаратною помилкою,
або ядро вже oops-нуло. Цей стан видно через /proc/sys/kernel/tainted та в логах.
Чого це не означає:
- Не означає автоматично, що дані пошкоджені. Деякі taint-прапорці — лише маркери «підтримуваності» (наприклад, пропрієтарні модулі).
- Не означає автоматично, що ваше ядро скомпрометовано. Непідписані модулі можуть бути безпечними в лабораторії і проблемними в продакшені. Taint лише вказує на наявність умови.
- Не означає автоматично «перезавантажуйте зараз». Ви перезавантажуєте, коли є операційна причина (ризик повторення, неможливість налагодження або ви вже пом’якшили проблему і хочете чистий стан), а не тому, що слово «tainted» лякає.
Коротке практичне визначення: taint — це дисклеймер, прикріплений до майбутніх звітів про аварії ядра.
Коли дисклеймер включає «proprietary» або «out-of-tree», розробники upstream не зможуть відтворити ваше середовище.
Коли там «hardware error», слід припинити сварки про програмне забезпечення і почати перевіряти апаратну телеметрію.
Чому Linux взагалі відстежує taint
Linux працює скрізь: в хмарних VM, на bare metal, у дивних апаратах, на ноутбуках із blob‑драйверами GPU та в боксах з драйверами від вендорів.
Така різноманітність — дар, поки ви налагоджуєте крах ядра з неповною інформацією.
Taint — це різкий, але ефективний спосіб сказати «поведінка цього ядра може відрізнятися від еталонної».
Тут також є соціальний контракт. Розробники ядра не можуть витрачати нескінченний час на баги, спричинені закритими модулями,
які вони не можуть переглянути. Дистрибутиви не можуть відповідально створювати upstream-звіти, ховаючи ключові факти.
Taint — це спосіб ядра примусити правду потрапити в звіт про баг.
І так, іноді це політичне питання. Але в операціях «політика» — просто гарна назва для «обмежень».
Факти й історія, які знадобляться у war room
- Taint — бітова маска, а не рядок. Ядро зберігає її як ціле число в
/proc/sys/kernel/tainted; інструменти декодують її в літери/слова. - Прапорець «P» (proprietary module) існує тому, що ліцензія має значення для налагодження.
- «O» (out-of-tree module) поширений в корпоративних парках. Vendor HBA, агенти безпеки та модулі файлових систем часто живуть поза деревом ядра.
- Прапорці, пов’язані з непідписаними модулями («E» чи прапорці підпису), стали помітнішими з поширенням Secure Boot. Ви можете запускати непідписані модулі навмисно; ядро все одно позначить це.
- Деякі taint‑прапорці означають «ви вже мали oops». Після oops ядро часто встановлює taint, щоб відобразити цей стан для постмортем‑аналізу.
- Існують taint‑прапорці, пов’язані з апаратурою. Machine Check Exceptions та інші апаратні помилки можуть встановлювати прапорці taint як неоновий знак «перестаньте звинувачувати systemd».
- Числове значення додається. Може бути кілька taint одночасно; щоб зрозуміти, що сталося, потрібно декодувати біти.
- Дистрибутиви й версії ядра трохи відрізняються в відображенні taint. Ідея однакова, але точне відображення та формат логів можуть змінюватися залежно від версії ядра.
- Taint залишається до перезавантаження. Навіть якщо ви вивантажите проблемний модуль, taint лишається, бо стан ядра вже був впливовим.
Де ви побачите taint у Debian 13
На практиці ви зіткнетеся з taint у трьох місцях:
dmesg/ journald логи: рядки, як-отmodule: loading out-of-tree module taints kernelабоTainted: P OE, прикріплені до oops./proc/sys/kernel/tainted: одне ціле число, що представляє бітову маску taint.- Звіти/дампи аварій: якщо ви використовуєте kdump або інструменти на кшталт ABRT, стан taint часто захоплюється з метаданими аварії.
Також: ви можете не помітити taint, поки не станеться щось гучне. Пропрієтарний модуль може завантажитися тихо, позначити ядро,
і ви помітите його лише через тижні, коли не пов’язаний драйвер наткнеться на стан гонки і в oops‑банері з’являться літери taint.
Прапорці taint: важливі у продакшені
Прапорці taint — це біти, визначені ядром. Інструменти декодують їх у літери. Відображення може змінюватися між версіями,
тож сприймайте значення літер як «зазвичай», а потім перевіряйте документацію вашого ядра або вивід tools.
Операційно вам важливіше не точна літера, а категорія:
питання підтримки, цілісність, апаратне забезпечення або вже нестабільний.
1) Завантажено пропрієтарний модуль (червоний прапор для підтримки)
Це класична ситуація з «NVIDIA/стороннім агентом безпеки». Це не доводить, що модуль спричинив інцидент.
Але це означає, що розробники ядра і пакувальники дистрибутива попросять вас відтворити без нього.
У флоті цей прапорець має викликати питання: «Чи є у нас шлях ескалації до вендора та символи для цього модуля?»
2) Завантажено out-of-tree модуль (питання підтримки і ризик регресії)
Out-of-tree не означає «погано». Це означає «не зібрано як частину цього дерева джерел ядра».
ZFS, драйвери vendor NIC і агенти моніторингу частіше трапляються тут.
Ризик не моральний — ви поєднуєте різні цикли змін: оновлення ядра проти оновлень модулів.
3) Непідписаний модуль / проблеми з підписом (сигнал про межу довіри)
Якщо Secure Boot входить у вашу модель загроз, непідписаний модуль — це не академічна нота.
Це повідомлення системи: «хтось може запускати код у ядрі без очікуваного ланцюга довіри».
У лабораторії — це здивування. У регульованих середовищах — це тикет.
4) Примусове завантаження модуля або змінені опції драйвера (ви взяли короткий шлях)
Якщо ви бачите taint, пов’язаний із примусом, зазвичай це корелює з «нам треба було, щоб це працювало в п’ятницю».
Ті п’ятничні виправлення часто стають вівторковими інцидентами.
5) Аппаратні помилки (змінюйте підхід до налагодження)
Якщо taint відображає апаратні помилки, припиняйте розглядати ядро як головного підозрюваного.
Ви все ще збираєте логи, але серед наступних дій повинні бути апаратна телеметрія, лічильники ECC,
декодування MCE, версії прошивок і перевірка, чи локалізовано проблему на вузлі чи вона системна.
6) Виник oops / ядро вже в скомпрометованому стані
Після oops ядро може продовжувати працювати, але його слід вважати «кульгавим».
Пам’ять може бути пошкоджена. Механізми блокувань можуть бути неконсистентні. Наступні кроки зазвичай:
стримування впливу, дамп стану і план контрольованого перезавантаження після збору доказів.
Жарт №1: «tainted kernel» — це не брудний одяг. Це ядро, яке прикріпило запис «якщо я зламаюсь пізніше, не робіть вигляд, що не бачили цього».
Підтримка, звіти про баги і чому taint змінює розмову
Практичний ефект taint — швидкість триажу. За наявності taint часто трапляється одне з наступного:
- Upstream просить відтворити без taint. Якщо не вдається, проблема може бути закрита як «не відтворюється» або «непідтримувана конфігурація».
- Пакувальники Debian зосереджуються на межі проблеми. Вони можуть допомогти ідентифікувати, який модуль позначив ядро та чи додав його Debian, але вони не можуть дебажити blob.
- Підтримка вендора стає основним шляхом. Якщо taint походить від модулю вендора, ескалюйте до цього вендора. Також підтримуйте чистоту доказів: версії, символи, дампи аварій.
Це не жорстокість. Це економіка. Налагодження проблем ядра дороге; taint показує, де не варто витрачати час.
Цитата, яка тут має значення, — це думка Dr. W. Edwards Deming: «Без даних ви просто ще одна людина з думкою».
(ідея перефразована)
Практичні завдання: команди, виводи та рішення (12+)
Це перевірки, які я справді виконую, коли хост каже «Tainted» і хтось хоче відповідь за менше ніж десять хвилин.
Кожне завдання включає: команду, реалістичний вивід, що це означає, і рішення, яке ви приймаєте.
Завдання 1: Перевірити бітову маску taint
cr0x@server:~$ cat /proc/sys/kernel/tainted
4097
Що це означає: Ядро позначене; 4097 вказує щонайменше на два встановлені біти (4096 + 1).
Треба декодувати, які саме прапорці це були; саме число не дає прямого інструктажу.
Рішення: Не сперечайтесь про значення поки не декодуєте. Перейдіть до декодування і знайдіть подію, яка встановила taint.
Завдання 2: Побачити літери taint у контексті останнього логу ядра
cr0x@server:~$ dmesg -T | grep -E "Tainted:|taints kernel|module verification failed" | tail -n 20
[Mon Dec 29 09:12:01 2025] nvidia: module license 'NVIDIA' taints kernel.
[Mon Dec 29 09:12:01 2025] nvidia: module verification failed: signature and/or required key missing - tainting kernel
[Mon Dec 29 09:12:01 2025] CPU: 6 PID: 2319 Comm: modprobe Tainted: P OE 6.12.0-1-amd64 #1 Debian 6.12.6-1
Що це означає: Taint виник під час завантаження nvidia, і є одночасно ліцензійне/пропрієтарне та проблема верифікації підпису,
а також позначення out-of-tree у рядку taint.
Рішення: Якщо цей хост має бути під контролем Secure Boot, це порушення політики. Якщо це GPU‑сервер, ескалюйте по шляху підтримки драйвера GPU.
Завдання 3: Декодувати число taint у біти (швидко і грубо)
cr0x@server:~$ python3 - <<'PY'
taint=int(open("/proc/sys/kernel/tainted").read().strip())
bits=[i for i in range(0,32) if taint & (1<<i)]
print("taint=",taint,"bits=",bits)
PY
taint= 4097 bits= [0, 12]
Що це означає: Встановлені біти 0 і 12. Точна семантика залежить від версії ядра,
але це каже вам «декілька причин». Потрібна ще семантична відповідність.
Рішення: Використайте dmesg/journal, щоб зіставити taint із конкретними подіями і модулями; не робіть висновків лише на основі бітів, поки не підтвердите відображення для вашого ядра.
Завдання 4: Виявити, які модулі завантажені (і які виглядають сторонніми)
cr0x@server:~$ lsmod | head -n 15
Module Size Used by
nvidia_uvm 1724416 0
nvidia_drm 86016 2
nvidia_modeset 1552384 1 nvidia_drm
nvidia 62697472 88 nvidia_uvm,nvidia_modeset
drm_kms_helper 323584 1 nvidia_drm
drm 786432 4 drm_kms_helper,nvidia_drm
i2c_algo_bit 16384 1 drm_kms_helper
Що це означає: Очевидний сторонній драйверний стек завантажено. Навіть якщо поточний інцидент — «затримка диска»,
taint ускладнить налагодження upstream ядра.
Рішення: Визначте, чи дозволено для цього класу хостів мати taint. Якщо так, забезпечте шлях ескалації до вендора і контроль версій для пакетів модулів.
Завдання 5: З’ясувати, якому пакету належить модуль (пакет Debian чи зовнішній)
cr0x@server:~$ modinfo -n nvidia | head -n 1
/lib/modules/6.12.0-1-amd64/updates/dkms/nvidia.ko
Що це означає: Модуль у шляху DKMS updates, а не в in-tree директорії.
Це часто означає «перекомпільовано локально» і потенційно «не узгоджено з очікуванням ABI цього ядра».
Рішення: Для інцидент-реакції зафіксуйте версію ядра і версію пакета DKMS; для виправлення — узгодьте оновлення ядра з пайплайнами перевбудови DKMS.
Завдання 6: Перевірити, чи має очікуватися перевірка підпису модулів
cr0x@server:~$ mokutil --sb-state
SecureBoot enabled
Що це означає: Secure Boot увімкнено. Якщо ви також бачите «required key missing», у вас розрив у цілісності:
або модуль не підписано довіреним ключем, або політика системи неправильно налаштована.
Рішення: Розглядайте це як проблему безпеки. Або правильно підпишіть модуль і заенролюйте ключ, або навмисно вимкніть Secure Boot (і документуйте це). Не живіть у стані «увімкнено, але обійдено».
Завдання 7: Перевірити стан підпису модуля
cr0x@server:~$ modinfo nvidia | egrep -i "signer|sig_key|sig_hashalgo|vermagic" | head -n 10
vermagic: 6.12.0-1-amd64 SMP preempt mod_unload modversions
signer:
sig_key:
sig_hashalgo:
Що це означає: Метадані підпису відсутні (або порожні), що відповідає логам про невдачу верифікації підпису.
Рішення: Якщо Secure Boot важливий, потрібно виправити підписування/енролмент. Якщо ні — зафіксуйте виняток і переконайтеся, що він узгоджений по всьому флоту (щоб налагодження було передбачуваним).
Завдання 8: Знайти першу подію, яка викликала taint, у журналі
cr0x@server:~$ journalctl -k -b | grep -n "taints kernel" | head -n 5
184:Dec 29 09:12:01 server kernel: nvidia: module license 'NVIDIA' taints kernel.
Що це означає: Маєте часову мітку і номер рядка поруч з джерелом taint.
Це золото при кореляції «коли почався taint» з «ми встановили щось» або «ми перезавантажилися в нове ядро».
Рішення: Зіставте з управлінням змінами: встановлення пакетів, перевбудови DKMS або оновлення ядра в той час.
Завдання 9: Перевірити версію ядра і рядок збірки (для підбору символів і відтворюваності)
cr0x@server:~$ uname -a
Linux server 6.12.0-1-amd64 #1 Debian 6.12.6-1 (2025-12-10) x86_64 GNU/Linux
Що це означає: Точна інформація про збірку ядра. Якщо налагоджуєте аварії, це потрібно, щоб відповідали vmlinux символи, інструменти для дампів і матриця сумісності модулів вендора.
Рішення: Зафіксуйте це в тикеті інциденту. Якщо vermagic модуля не відповідає, плануйте виправлення до наступного перезавантаження, щоб не було сюрпризів.
Завдання 10: Перевірити попередні маркери oops/panic (taint може означати «ми вже падали»)
cr0x@server:~$ journalctl -k -b | egrep -i "Oops:|BUG:|panic|soft lockup|hard lockup|Call Trace" | tail -n 20
Dec 29 10:41:22 server kernel: BUG: soft lockup - CPU#6 stuck for 26s! [kworker/6:2:147]
Dec 29 10:41:22 server kernel: CPU: 6 PID: 147 Comm: kworker/6:2 Tainted: P OE 6.12.0-1-amd64 #1 Debian 6.12.6-1
Dec 29 10:41:22 server kernel: Call Trace:
Dec 29 10:41:22 server kernel: <IRQ>
Dec 29 10:41:22 server kernel: __schedule+0x2f3/0x940
Що це означає: Це фактичний режим відмови на рівні ядра (soft lockup). Прапорці taint — це контекст, а не сама причина збою.
Рішення: Вважайте систему під ризиком. Збирайте докази (стек‑трейс, список модулів, навантаження) і плануйте контрольоване перезавантаження, коли сервіс стане досить стабільним.
Завдання 11: Визначити, чи залучена апаратна проблема (MCE, EDAC)
cr0x@server:~$ journalctl -k -b | egrep -i "mce:|Machine check|EDAC|Hardware Error" | tail -n 20
Dec 29 10:03:11 server kernel: mce: [Hardware Error]: CPU 0: Machine Check: 0 Bank 27: b200000000070005
Dec 29 10:03:11 server kernel: mce: [Hardware Error]: TSC 0 ADDR 1ffffffffff MISC d012000100000000 SYND 4d000000 IPID 500b000000000
Що це означає: В гру втягуються апаратні збої. Навіть якщо негайний симптом — «зависання ядра», це змінює пріоритет на апаратний триаж.
Рішення: Залучіть апаратну/інфраструктурну команду. Розгляньте евакуацію навантажень із цього вузла і запуск розширеної діагностики.
Завдання 12: Перевірити, чи працюють сторонні модулі файлових систем (перевірка збереження)
cr0x@server:~$ lsmod | egrep -i "zfs|spl|nvidia|vbox|wireguard" | head -n 20
zfs 6877184 0
spl 131072 1 zfs
Що це означає: ZFS завантажено (часто out-of-tree залежно від способу встановлення). Це може позначити ядро і може також бути центральним для симптомів продуктивності/затримок.
Рішення: Якщо інцидент — затримка сховища, наступний крок — аналіз здоров’я ZFS і IO-шляху; якщо це крах ядра, вирішіть, чи відтворювати без ZFS (часто неможливо) і натомість ескалюйте через канал підтримки упаковки ZFS.
Завдання 13: Інспект DKMS статус (чи залишив оновлення ядра вузол у стані «модулі потокові»?)
cr0x@server:~$ dkms status
nvidia/550.54.14, 6.12.0-1-amd64, x86_64: installed
zfs/2.2.6, 6.12.0-1-amd64, x86_64: installed
Що це означає: DKMS перебудував модулі для запущеного ядра. Це добре, але також означає, що ваше ядро тепер залежить від інструментів DKMS і узгодженості середовища збірки.
Рішення: У продакшені розглядайте успішну перебудову DKMS як шлюз для деплою. Якщо DKMS недетермінований, ви отримаєте «працює на одному вузлі» катастрофи.
Завдання 14: Перевірити, чи запущене ядро відповідає встановленим заголовкам (для налагоджуваності)
cr0x@server:~$ dpkg -l | egrep "linux-image-6\.12|linux-headers-6\.12" | awk '{print $1,$2,$3}'
ii linux-headers-6.12.0-1-amd64 6.12.6-1
ii linux-image-6.12.0-1-amd64 6.12.6-1
Що це означає: Заголовки і образ відповідають. Коли вони не відповідають, перебудови DKMS можуть успішно завершуватись дивними способами або виробляти модулі, які завантажуються, але поводяться некоректно.
Рішення: Якщо неузгодженість, виправте стан пакетів перед тим, як шукати фантомні баги ядра.
Завдання 15: Підтвердити, чи taint зберігається після вивантаження (так)
cr0x@server:~$ sudo modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia
cr0x@server:~$ cat /proc/sys/kernel/tainted
4097
Що це означає: Taint залишаєтсья до перезавантаження. Це зроблено навмисно: стан ядра було вплинено; вивантаження не скасовує це.
Рішення: Якщо вам потрібен чистий стан для налагодження або відповідності, заплануйте перезавантаження в конфігурацію без тригера taint.
Швидкий план діагностики
Коли час підтискає, «kernel tainted» — це підказка, а не ціль. Ось порядок дій, що дозволяє швидко дістатися до вузького місця.
Перший крок: класифікуйте taint за категорією
- Питання підтримуваності (proprietary/out-of-tree/unsigned): ймовірно не безпосередньо причинне, але змінює, хто допомагатиме і наскільки відтворюваним буде баг.
- Аппаратний taint / апаратні помилки в логах: вважайте це потенційною відмовою вузла; прагніть ізолювати і евакуювати.
- Taint, пов’язаний з oops/panic: система може бути нестабільною зараз; пріоритет — збір доказів і контрольований рестарт.
Робіть це за допомогою: рядків taint у dmesg + недавніх ключових слів про помилки.
Другий крок: знайдіть перше запис, що тригерив taint
Перша подія taint підкаже, що змінилося: завантаження модуля, примусова опція, помилка підпису або oops.
Пізніші записи часто повторюють банер «Tainted:», але не кажуть, чому це почалося.
Третій крок: вирішіть, чи taint релевантний інциденту
- Якщо ви налагоджуєте крах ядра: taint релевантний. Це впливає на налагодження і шлях підтримки.
- Якщо ви налагоджуєте продуктивність: taint релевантний лише якщо компонент, що позначив, знаходиться на гарячому шляху (сховище, мережа, GPU compute).
- Якщо ви налагоджуєте помилки в застосунку: taint зазвичай фоновий шум, якщо ви не підозрюєте блокування на рівні ядра або апаратні помилки.
Четвертий крок: оберіть набір доказів за типом відмови
- Крах/зависання: зберіть повний лог ядра, стек‑трейси, список модулів і, якщо можливо, vmcore (kdump).
- Затримка збереження: перевірте планувальник IO, помилки пристрою, multipath, стан файлової системи (ext4/XFS/ZFS) і логи контролера.
- Відпадання мережі: перевірте драйвер NIC, прошивку, ethtool‑статистику, пропуски в кільцевих буферах і affinity IRQ.
- Апаратні помилки: логи MCE/EDAC, SMART/NVMe health, події BMC SEL.
Жарт №2: Прапорець taint ядра схожий на наліпку «змонтовано вендором» на ноутбуці. Це не доводить, що воно зламане, але змінює, кого звинувачувати.
Три корпоративні міні-історії (усі достатньо правдиві, щоб боліти)
Міні-історія 1: Інцидент через неправильне припущення
Середня компанія запускала Kubernetes-кластер на Debian на bare metal.
У них було кілька GPU‑вузлів для пакетних задач і більший пул «звичайних» обчислювальних вузлів.
Інженер побачив oops на звичайному вузлі і помітив Tainted: P OE.
Припущення: «У нас мають бути GPU‑драйвери скрізь; отже, через них ядро й упало».
Команда вважала taint коренем проблеми і почала видаляти пакунки.
Проблема не зникла. Гірше — вони порушили процес розгортання вузлів, бо справжнім джерелом taint був агент безпеки (також out-of-tree).
Вузли почали проходити перевірки на відповідність із помилками і потрапляти в cordon. Аварія розширилась.
Насправді причина була банальною: несправний DIMM давав періодичні виправлені ECC‑помилки.
Коробка могла працювати години, потім зависнути під пам’ятним навантаженням і викидати soft lockup.
Taint був випадковим: сторонній модуль був завантажений місяці тому.
Виправленням стало трактування taint як контексту і слідування доказам:
логи MCE, лічильники EDAC і аналіз «чи унікальний цей вузол?».
Вони замінили DIMM, зависання припинилися, і рядок «tainted kernel» став скоріше приміткою, ніж наративом.
Стале правило: не вважайте taint курящим пістолетом. Вважайте його запискою, прикріпленою до пістолета: «можливо, це не стандартна комплектація».
Міні-історія 2: Оптимізація, яка обернулася проти
Фінансова платформа хотіла зменшити латентність для робочих навантажень на збереженні.
Хтось запропонував оновлення ядра плюс драйвер NVMe від вендора «оптимізований для пропускної здатності».
Драйвер прийшов як пакет DKMS, out-of-tree, підписаний внутрішнім ключем, який не був належно розгорнутий скрізь.
Наполовину флоту модуль завантажився; решта — ні. Вузли «працювали», поки раптом перестали.
Вони почали бачити спорадичні IO‑таймаути під час пікового навантаження. Нічого послідовного для відтворення.
На деяких вузлах ядро показувало taint через невідповідність підпису модуля; на інших модуль не завантажився і in-tree драйвер обробляв пристрій.
Графіки латентності виглядали як сучасне мистецтво.
Провал був не лише в якості драйвера. Це був операційний «split‑brain»:
різні IO‑шляхи, різна обробка помилок, різні налаштування черг і різна поведінка під навантаженням.
Прапорці taint були єдиною очевидною підказкою, що флот більше не однорідний.
Рішення було не героїчним: вони відкотилися до in-tree драйвера, уніфікували версії ядер
і додали шлюз деплою, що блокував просування, якщо dkms status не був узгоджений на канарках.
Пізніше вони повернули драйвер вендора тільки після гарантій підписування і рівномірного увімкнення.
Урок: оптимізації продуктивності, що додають out-of-tree код ядра, ніколи не є «просто пакетом».
Це нова доменна зона відмов. Якщо ви не можете забезпечити узгодженість, у вас не оптимізація — у вас лотерея.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
SaaS‑компанія запускала Debian‑хости з мішаниною пропрієтарних модулів моніторингу і стандартних ядер.
Вони не були ідеальними, але дисциплінованими: кожне оновлення ядра супроводжувалося
знімком uname -a, lsmod, dkms status і перших 500 рядків dmesg після завантаження.
Збережено в тикеті зміни. Кожного разу.
Одного ранку підмножина машин почала несподівано перезавантажуватися під певним навантаженням.
Звіти про крах показували taint. Передбачувано, перша реакція зацікавленого була:
«Ми не можемо це налагодити; воно tainted».
Команда порівняла нудні знімки між вузлами.
У краш‑хостів був один зайвий out-of-tree модуль, доданий «невинним» оновленням агента безпеки.
Модуль завантажувався раніше, ніж раніше, змінюючи таймінги подій CPU hotplug. Крах виявився гонкою в тому модулі, а не в ядрі Debian.
Оскільки вони мали before/after список модулів і логи завантаження, вони швидко звузили вікно регресії,
відкотили агент лише на уражених вузлах і відновили стабільність без заморозки оновлень ядра по всьому флоту.
Урок: нудна звичка фіксувати стан ядра/модулів на межах змін перетворює taint з «таємничої мітки» на «дієвий diff».
Поширені помилки: симптом → корінна причина → виправлення
Це повторювані помилки, які я бачу в каналах інцидентів і постмортемах. Кожна з них марнує час по‑своєму.
1) Симптом: «Ядро tainted, тому ми нічого не можемо налагодити»
Корінна причина: Плутанина між «питаннями підтримки» та «неможливістю».
Taint обмежує допомогу upstream, але не вашу здатність виконувати локальний аналіз.
Виправлення: Збирайте докази будь‑як: journalctl -k -b, список модулів, версії, стек‑трейси, vmcore якщо доступний.
Потім вирішіть, чи потрібне вам відтворення без taint для ескалації.
2) Симптом: «Ми вивантажили модуль, але все ще показує tainted»
Корінна причина: Taint залишається до перезавантаження за дизайном.
Виправлення: Якщо потрібен чистий стан — перезавантажте в конфігурацію, яка уникає тригера taint.
Не витрачайте час на спроби «очистити» taint під час роботи системи.
3) Симптом: Випадкові зависання, taint присутній, всі звинувачують пропрієтарний драйвер
Корінна причина: Кульгавість причинно‑наслідкового мислення. Пропрієтарний модуль може бути не пов’язаний.
Зависання часто викликані апаратурою або планувальником/IO ядра.
Виправлення: Перевірте MCE/EDAC апаратні помилки, IO‑таймаути і soft lockups.
Звинувачуйте модуль лише якщо стек‑трейси чи кореляція вказують на нього.
4) Симптом: Secure Boot увімкнено, але логи ядра показують «required key missing»
Корінна причина: Непідписані DKMS‑модулі завантажуються всупереч вашій моделі довіри, або ключі не узгоджено заенролено.
Виправлення: Уніфікуйте підписування модулів і реєстрацію ключів (MOK) по флоту, або навмисно вимкніть Secure Boot для цього класу хостів і задокументуйте виняток.
5) Симптом: Після оновлення ядра сервіс падає і dmesg згадує taint при завантаженні модуля
Корінна причина: Несумісність перебудови DKMS, відсутні заголовки або дрейф ABI між модулем і ядром.
Виправлення: Гарантуйте відповідність linux-image і linux-headers, перевірте dkms status і ставте блоки на розгортаннях на канарках.
6) Симптом: Oops ядра показує прапорці taint, звіт про баг відкидають
Корінна причина: Ви надіслали upstream без розкриття стеку сторонніх модулів, або не можете відтворити без них.
Виправлення: Надайте повний список модулів і причину taint у звіті. Якщо можливо, відтворіть на чистому ядрі або в мінімальній VM. Якщо ні — маршрутизируйте через вендора модуля.
Чек-листи / покроковий план
Чек‑лист A: Коли ви вперше бачите «Tainted:» під час інциденту
- Зафіксуйте поточний стан:
uname -a,cat /proc/sys/kernel/tainted,lsmod. - Знайдіть найранішу подію taint:
journalctl -k -b | grep "taints kernel". - Класифікуйте категорію taint: proprietary/out-of-tree/unsigned vs hardware vs oops‑related.
- Вирішіть, чи taint у гарячому шляху: модуль сховища під час IO‑інциденту? драйвер NIC під час втрат пакетів? Інакше трактуйте як контекст.
- Зменшіть ризик: якщо є oops/зависання/апаратні помилки, евакуюйте навантаження і плануйте перезавантаження після збору доказів.
Чек‑лист B: Стандартна операційна процедура для tainted‑флотів (нудна, але важлива)
- Визначте дозволені taint за класом хостів. GPU‑вузли можуть дозволяти пропрієтарні модулі; платіжні системи, ймовірно, не повинні дозволяти непідписані модулі.
- Фіксуйте і інвентаризуйте модулі ядра. Додайте
lsmod+modinfoу базове виявлення дрейфу конфігурації. - Ставте шлюзи оновлень ядра на успіх DKMS. Канаркові вузли мають проходити: заголовки відповідають образу, DKMS‑модулі побудовані, модулі завантажуються чисто.
- Майте стратегію для символів/пакетів налагодження. Якщо ви покладаєтеся на дампи аварій, переконайтеся, що можете розв’язати стеки для вашої збірки ядра.
- Документуйте шляхи ескалації до вендора. Якщо ви запускаєте пропрієтарні/out‑of‑tree модулі, знайте, хто відповідальний, коли щось ламається.
Чек‑лист C: Коли потрібно чисте відтворення без taint
- Відтворіть у VM з лише модулями, що постачає Debian, якщо можливо.
- Використайте ту ж версію ядра що в продакшені спочатку; потім спробуйте новішу, щоб перевірити виправлення регресій.
- Видаліть тригер taint: завантажте без стороннього модуля; при необхідності blacklist.
- Запустіть мінімальне навантаження, яке викликає баг.
- Порівняйте логи і трейс між tainted і untainted виконаннями; шукайте відмінності у шляху відмови.
Часті запитання
1) Чи означає «kernel tainted», що моя система скомпрометована?
Не обов’язково. Це означає, що сталася умова, яка впливає на довіру до налагодження або «стандартності» ядра.
Якщо taint походить від непідписаних модулів і Secure Boot важливий у вашому середовищі, то так — це питання безпеки.
2) Чи слід перезавантажувати негайно, коли я бачу taint?
Не тільки через taint. Перезавантажуйте, коли taint вказує на нестабільність (oops/panic), є апаратні помилки, або коли вам потрібен чистий стан для відповідності/налагодження.
Якщо система здорова, а taint — лише «завантажено пропрієтарний модуль», перезавантаження — зазвичай театральний акт.
3) Чому taint залишається після вивантаження модуля?
Тому що ядро не може гарантувати, що модуль не змінив стан (пам’ять, гачки, таймінг) у спосіб, що зберігається.
Головна ідея — історична правда: ядро було впливовим. Лише перезавантаження очищає це.
4) Чи підтримає мене Debian, якщо моє ядро tainted?
Вам допоможуть ідентифікувати, що саме tainted і чи пакував це Debian.
Для багів, які ймовірно спричинені пропрієтарними/out‑of‑tree модулями, очікуйте прохання відтворити без них
або звернутися до вендора/підтримки модуля.
5) Чи гарантовано ZFS taint‑ить ядро на Debian?
Не гарантовано, але часто включає out‑of‑tree модулі залежно від способу пакування і збірки.
Операційно сприймайте це як потенційно taint‑ячий компонент і забезпечте узгодженість версій при оновленнях ядра.
6) У чому різниця між «proprietary» і «out-of-tree» taint?
«Proprietary» стосується ліцензії і доступності коду (закритий або не сумісний з GPL).
«Out-of-tree» — про походження збірки (не всередині дерева ядра), навіть якщо код відкритий.
Обидва знижують відтворюваність; proprietary додатково блокує інспекцію коду upstream.
7) Чи може taint сам по собі спричинити проблеми з продуктивністю?
Taint — це прапорець, а не навантаження. Він не уповільнить CPU.
Але те, що спричинило taint (драйвер, файлова система, примусові опції), може викликати проблеми з продуктивністю.
Ваше завдання — відокремити «мітку» від «компонента».
8) Як запобігти випадковому taint по флоту?
Інвентаризуйте завантажені модулі, обмежте завантаження модулів там, де потрібно, і послідовно застосовуйте політики Secure Boot/підписування модулів.
Більшість випадкових taint походить від DKMS‑модулів, встановлених «бо пакет рекомендував», і ніхто не помітив.
9) Якщо я бачу апаратні помилки разом з taint, що пріоритетніше?
Пріоритет — апаратна ізоляція. Евакуюйте навантаження, збирайте логи і перевіряйте здоров’я вузла.
Програмне налагодження все ще корисне, але апаратні помилки змінюють «можливо» на «ймовірно».
10) Чи впливають контейнери на taint ядра?
Контейнери самі по собі не завантажують модулі ядра (у нормальних конфігураціях), тож зазвичай вони безпосередньо не taint‑ять ядро.
Але агенти на рівні ядра для безпеки/спостереження контейнерів можуть, і ці агенти часто з’являються як out‑of‑tree модулі.
Висновок: практичні наступні кроки
У Debian 13 tainted ядро — це механізм видимості: ядро повідомляє, які припущення більше не безпечні.
Ставтеся до цього як до анотації в постмортемі, а не як до сигналу тривоги, що замінює мислення.
Що робити далі, по порядку:
- Зафіксуйте докази (число taint, рядки dmesg про taint, список модулів, версію ядра) у момент виявлення.
- Ідентифікуйте тригер taint (перша запис у логах) і вирішіть, чи це в гарячому шляху інциденту.
- Якщо це питання підтримки, забезпечте шлях ескалації до вендора/утримувача і правила узгодженості по флоту.
- Якщо це апаратне або пов’язане з oops, ізолюйте ризик: евакуюйте, збирайте дампи, плануйте контрольований рестарт і починайте апаратний триаж.
- Перетворіть це в політику: визначте дозволені taint за класом хостів і забезпечте узгодженість модулів/підписів, щоб не налагоджувати різні сніжинки щоразу.