Ви підключені по SSH до сервера Ubuntu 24.04, де df -h каже, що «місця вдосталь».
Проте кожен деплой ламається, логи не обертаються, apt не може розпакувати пакети, а ядро постійно викидає
No space left on device, наче йому платять за кожну помилку.
Це один із тих інцидентів, що змушує розумних людей сумніватися у власних очах. Диск не переповнений.
Переповнене щось інше. Зазвичай: іноди. І як тільки ви зрозумієте, що це означає, виправлення майже нудне.
Майже.
Що ви бачите: «диск повний», хоча гігабайти вільні
В Ubuntu «диск повний» часто означає одне з трьох:
- Вичерпання блоків: класичний випадок; у вас закінчилися байти.
- Вичерпання інодів: закінчилися записи метаданих файлів; байти можуть залишатися вільними.
- Резервні блоки, квоти або корупція файлової системи: місце є, але його не можна використати.
Вичерпання інодів — підступне, бо воно не показується в тій команді, яку всі запускають першою.
df без прапорців повідомляє лише про використані/доступні блоки. Ви можете мати 200 ГБ вільних і при цьому
не створити 0-байтний файл. Файлова система не може виділити новий інод, отже не може створити файл.
Ви помітите дивні побічні ефекти:
- Нові лог-файли не створюються, через що сервіси падають або перестають логувати в найважливіший момент.
aptпадає посеред встановлення, бо не може створити тимчасові файли або розпакувати архіви.- Збірки Docker починають падати на операціях «writing layer», хоча томи виглядають в порядку.
- Деякі додатки повідомляють «диск повний», а інші продовжують працювати (бо не створюють файли).
Є простий тест: спробуйте створити файл у ураженій файловій системі. Якщо це завершується помилкою «No space left»
при тому, що df -h показує вільне місце, припиняйте сперечатися з df і перевіряйте іноди.
Іноди пояснені для продакшну
Інод — це запис файлової системи про файл або директорію. Це метадані: власник, права, часові мітки,
розмір, вказівники на блоки даних. У багатьох файлових системах ім’я файлу не зберігається в іноді; воно знаходиться
в записах директорії, які відображають імена в номери інодів.
Важлива операційна істина: більшість Linux-файлових систем мають два окремі «бюджети»:
блоки (байти) і іноди (кількість файлів). Якщо ви витратите будь-який із цих бюджетів — все.
Чому іноди закінчуються в реальних системах
Вичерпання інодів зазвичай не через «безліч великих файлів». Це «мільйони дрібних файлів».
Думайте про кеші, поштові черги, артефакти збірок, шари контейнерів, робочі простори CI,
тимчасові завантаження і буфери метрик, які хтось забув видаляти.
1 КБ файл все одно коштує одного інода. 0-байтний файл теж коштує інод. Директорія також займає інод.
Коли у вас 12 мільйонів дрібних файлів, диск може бути переважно порожнім по байтах, але таблиця інодів — вичерпана.
Які файлові системи найчастіше кусають
- ext4: поширена на Ubuntu; іноди зазвичай створюються при форматуванні на основі співвідношення bytes-per-inode. Якщо ви невірно вгадали — можна вичерпати іноди.
- XFS: іноди більш динамічні; вичерпання інодів трапляється рідше, але не виключено.
- btrfs: алокація метаданих інша; все ще можна вдаритися об проблеми з метаданими, але це не та сама історія зі «фіксованою кількістю інодів».
- overlayfs (Docker): це не самостійний тип файлової системи, але воно підсилює поведінку «багато файлів» на хостах із великою кількістю контейнерів.
Цитата, яку варто тримати у своєму мануалі:
«Надія — не стратегія.» — General Gordon R. Sullivan
Швидкий план діагностики (перший/другий/третій)
Коли алерт каже «No space left on device», а графіки показують, що все гаразд, не блукайте.
Дійте за планом.
Перший: підтвердьте, який саме «ресурс» вичерпано
- Перевірте блоки (
df -h) і іноди (df -i) для ураженого монту. - Спробуйте створити файл на цьому монті; підтвердіть шлях помилки.
- Перевірте
dmesgна предмет переведення в режим лише читання або помилок файлової системи.
Другий: знайдіть монту та топ-споживачів інодів
- Визначте, який шлях файлової системи ламається (логи, тимчасові файли, директорія даних).
- Знайдіть директорії з великою кількістю файлів за допомогою
findі парочціці цілеспрямованих підрахунків. - Якщо це Docker/Kubernetes, перевірте overlay2, images, containers та логи.
Третій: безпечно звільніть іноди
- Почніть з очевидного безпечного прибирання: старі логи, кеші, тимчасові файли, вакуум журналу, сміття контейнерів.
- Видаляйте файли, не директорії, якщо додаток очікує структуру директорій.
- Підтвердіть зниження використання інодів (
df -i) і відновлення сервісів.
Вам не потрібні героїчні вчинки. Потрібен контрольований план видалення та постмортем, що запобіжить повторенню.
Практичні завдання: команди, значення виводу, рішення
Нижче — реальні завдання, які можна виконати на Ubuntu 24.04. Кожне містить, на що звертати увагу і яке рішення прийняти.
Виконуйте послідовно, якщо ви на чергуванні; вибирайте вибірково, якщо ви вже знаєте уражений монтувальний шлях.
Завдання 1: Підтвердити використання блоків (очевидна перевірка)
cr0x@server:~$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 200G 62G 128G 33% /
tmpfs tmpfs 3.1G 1.2M 3.1G 1% /run
/dev/sdb1 ext4 1.8T 1.1T 648G 63% /data
Значення: Блоки в порядку на / і /data.
Рішення: Якщо ви все ще отримуєте «No space left», переходьте до перевірки інодів. Не витрачайте час на пошук великих файлів поки що.
Завдання 2: Перевірити використання інодів (реальний винуватець у половині випадків)
cr0x@server:~$ df -iT
Filesystem Type Inodes IUsed IFree IUse% Mounted on
/dev/sda2 ext4 13107200 13107190 10 100% /
tmpfs tmpfs 790000 420 789580 1% /run
/dev/sdb1 ext4 122142720 982134 121160586 1% /data
Значення: Файлова система кореневого розділу має IUse% 100%. Лише 10 інодів вільні. Це робить неможливим створення файлів.
Рішення: Треба видалити файли на / (або перемістити їх), щоб звільнити іноди. Видалення одного великого файлу не допоможе, якщо це все одно один інод.
Завдання 3: Відтворіть помилку контрольовано
cr0x@server:~$ touch /tmp/inode-test-file
touch: cannot touch '/tmp/inode-test-file': No space left on device
Значення: Файлова система не може виділити інод для крихітного файлу.
Рішення: Розглядайте це як інцидент доступності. Все, що потребує записів (логи, сокети, PID-файли, тимчасові файли), може наступним впасти.
Завдання 4: Визначте, який шлях знаходиться на ураженому монту
cr0x@server:~$ findmnt -T /var/log
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda2 ext4 rw,relatime,errors=remount-ro
Значення: /var/log знаходиться на /. Якщо логи вибухнули у мільйони файлів, це ваше поле бою.
Рішення: Зосередьте пошук під /var, /tmp, /var/lib та в будь-яких директоріях додатків на /.
Завдання 5: Виявити підозрілі директорії за розміром (байти)
cr0x@server:~$ sudo du -xh --max-depth=1 /var | sort -h
12M /var/cache
180M /var/log
2.1G /var/lib
2.4G /var
Значення: Використання байтів не екстремальне. Це ваш перший натяк, що проблема в кількості файлів, а не в розмірі.
Рішення: Припиніть оптимізувати під ГБ. Почніть оптимізувати під кількість файлів.
Завдання 6: Знайдіть директорії з величезною кількістю файлів (очищення верхнього рівня)
cr0x@server:~$ sudo bash -lc 'for d in /var/* /tmp /home; do [ -d "$d" ] && printf "%s\t" "$d" && find "$d" -xdev -type f 2>/dev/null | wc -l; done | sort -n -k2 | tail -n 10'
/var/cache 1320
/var/log 5402
/var/lib 12877190
/tmp 120
/home 88
Значення: /var/lib має ~12.8 мільйона файлів. Це не «трохи безладу»; це ваші іноди.
Рішення: Зосередьтесь на /var/lib. Якщо це хост контейнерів, очікуйте /var/lib/docker або /var/lib/containerd.
Завдання 7: Звузьте пошук всередині /var/lib швидко
cr0x@server:~$ sudo bash -lc 'for d in /var/lib/*; do [ -d "$d" ] && printf "%s\t" "$d" && find "$d" -xdev -type f 2>/dev/null | wc -l; done | sort -n -k2 | tail -n 10'
/var/lib/systemd 2200
/var/lib/dpkg 9800
/var/lib/docker 12866012
Значення: Docker споживає ваш бюджет інодів через шари, кеш збірок і логи контейнерів.
Рішення: Вирішіть, чи можна безпечно виконати prune зараз. Якщо це вузол для конкретного призначення, pruning зазвичай коректний. Якщо це «pet» сервер з невідомими робочими навантаженнями — будьте обережніші.
Завдання 8: Перевірка з боку Docker (байти, не іноди, але корисно)
cr0x@server:~$ sudo docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 48 12 23.4GB 18.1GB (77%)
Containers 65 18 4.2GB 2.9GB (69%)
Local Volumes 26 20 11.8GB 1.1GB (9%)
Build Cache 152 0 6.4GB 6.4GB
Значення: Є що почистити, але цей вивід не показує кількість файлів.
Рішення: Продовжуйте з prune-дiями, якщо ви розумієте їхній вплив: зупинені контейнери, dangling images, кеш збірок.
Завдання 9: Безпечне prune Docker (почніть консервативно)
cr0x@server:~$ sudo docker image prune -a -f
Deleted Images:
deleted: sha256:1a2b3c...
deleted: sha256:4d5e6f...
Total reclaimed space: 17.8GB
Значення: Видалені невикористовувані образи; кількість інодів теж має зменшитись, бо шари містять багато дрібних файлів.
Рішення: Повторно перевірте df -i. Якщо використання інодів не знизилось достатньо, почистіть контейнери та build cache далі.
Завдання 10: Prune build cache (часто мовчазна фабрика інодів)
cr0x@server:~$ sudo docker builder prune -a -f
Deleted build cache objects:
k2r1m3n4o5p6...
Total reclaimed space: 6.4GB
Значення: CI/хости збірок люблять залишати фрагменти кешу.
Рішення: Якщо вам потрібні відтворювані та швидкі збірки, плануйте цю очистку, а не виконувати її постійно вручну. Наразі ваша мета — стабілізувати вузол.
Завдання 11: Підтвердіть відновлення інодів (це ваш KPI по успішності)
cr0x@server:~$ df -i /
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda2 13107200 8123400 4983800 63% /
Значення: Ви відійшли від краю. Сервіси можуть створювати файли знову.
Рішення: Перезапустіть сервіси, що впали через неможливість запису, і влаштуйте запобіжні заходи, щоб не повторилось.
Завдання 12: Якщо логи — винуватець, очистіть і обмежте їх (systemd-journald)
cr0x@server:~$ sudo journalctl --disk-usage
Archived and active journals take up 1.7G in the file system.
Значення: Журнали не обов’язково завантажують іноди (вони — менше, більші файли), але можуть створювати тиск по байтах.
Рішення: Якщо байти теж важливі — вакуумуйте. Якщо проблема саме в інодах — зосередьтесь на додатках, які створюють велику кількість окремих лог-файлів, а не на journal.
cr0x@server:~$ sudo journalctl --vacuum-time=7d
Vacuuming done, freed 1.2G of archived journals from /var/log/journal.
Значення: Байти звільнено. Іноди звільняються лише помірно.
Рішення: Встановіть постійні обмеження в конфігі journald, якщо цей хост схильний до шумних логів.
Завдання 13: Якщо apt падає, очистіть кеш пакетів
cr0x@server:~$ sudo apt-get clean
Значення: Очищає завантажені архіви пакетів під /var/cache/apt/archives.
Рішення: Добра гігієна, але зазвичай не панацея для інодів. Допомагає, коли кеші містять багато дрібних частинних файлів.
Завдання 14: Знайдіть директорії з великою кількістю файлів за допомогою du (стиль інодів)
cr0x@server:~$ sudo du -x --inodes --max-depth=2 /var/lib | sort -n | tail -n 10
1200 /var/lib/systemd
9800 /var/lib/dpkg
12866012 /var/lib/docker
12877190 /var/lib
Значення: Це ключовий вигляд: споживання інодів по директоріях.
Рішення: Цільте на найбільшого споживача. Не «чистіть трохи скрізь» — ви витратите час і все одно залишитесь на 100%.
Завдання 15: За сумнівів, інспектуйте патологічний розкид файлів
cr0x@server:~$ sudo find /var/lib/docker -xdev -type f -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -n | tail -n 5
42000 /var/lib/docker/containers/8a7b.../mounts
78000 /var/lib/docker/overlay2/3f2d.../diff/usr/lib
120000 /var/lib/docker/overlay2/9c1e.../diff/var/cache
250000 /var/lib/docker/overlay2/b7aa.../diff/usr/share
980000 /var/lib/docker/overlay2/2d9b.../diff/node_modules
Значення: Шар контейнера з node_modules може згенерувати абсурдну кількість файлів.
Рішення: Виправте збірку (multi-stage builds, видалення dev-залежностей, .dockerignore) або перемістіть дані Docker на файлову систему, спроєктовану для такого навантаження.
Завдання 16: Підтвердіть тип файлової системи та деталі провізії інодів
cr0x@server:~$ sudo tune2fs -l /dev/sda2 | egrep -i 'Filesystem features|Inode count|Inode size|Block count|Reserved block count'
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Inode count: 13107200
Inode size: 256
Block count: 52428800
Reserved block count: 2621440
Значення: ext4 має тут фіксовану кількість інодів. Ви не можете «додати інодів» без відбудови файлової системи.
Рішення: Якщо завдання хоста — «мільйони дрібних файлів», плануйте міграцію: нова файлова система з іншим співвідношенням інодів або інша організація збереження.
Жарт №1: Іноди схожі на переговорні кімнати: ви можете мати порожню будівлю і все одно бути «повними», якщо в кожній кімнаті приклеєно по записці.
Три корпоративні міні-історії (анонімізовано, болісно реально)
1) Інцидент через хибне припущення: «df каже, що ми в порядку»
Середній SaaS запустив флот серверів Ubuntu для обробки webhook’ів. Інженери моніторили використання диска у відсотках,
налаштували алерти на 80% і були впевнені: «диски більше не переповнюються». У вівторок вдень pipeline обробки
почав повертати переривчасті 500. Повторні спроби накопичувалися, черги росли, дашборди загорілися.
На чергуванні виконали стандартну рутину: df -h виглядав здоровим. CPU був у нормі. Пам’ять не найкраща, але терпима.
Вони перезапустили сервіс, і він помер відразу, бо не зміг створити PID-файл. Нарешті з’явилася зрозуміла помилка:
No space left on device.
Хтось сказав «можливо диск збрехав», що було по-людськи чарівно інтерпретовано як «ми не вимірювали правильну річ».
Запустили df -i і побачили корінь на 100% використання інодів. Винуватцем не була база даних.
Це був «тимчасовий репозиторій повторів», реалізований як один JSON-файл на подію webhook у /var/lib/app/retry/.
Кожен файл був крихітним. Мільйони.
Виправлення було миттєве: видалити файли старші за поріг і перезапустити. Реальне виправлення зайняло спринт:
перенести retry store до черги, перестати використовувати файлову систему як дешеву базу даних і додати алерти на іноди.
Постмортем мав ввічливу назву. Внутрішній чат — ні.
2) Оптимізація, що зіграла в зворотний бік: «кешуємо все на локальний диск»
Команда з обробки даних прискорила ETL, кешуючи проміжні артефакти на локальний SSD.
Вони перейшли від «один артефакт на батч» до «один артефакт на розділ», щоб підвищити паралелізм.
Продуктивність зросла. Витрати виглядали кращими. Усі забули про це.
Через кілька тижнів вузли почали падати по черзі. Не всі одразу, що ускладнювало діагностику.
Деякі задачі виконувалися, інші випадково падали при спробі записати вихід. Помилки були різні:
винятки Python, IO-помилки Java, іноді «read-only filesystem» після того, як ядро перемонтувало диск у режим лише читання.
Корінь проблеми був принизливо механічним: кеш створив десятки мільйонів дрібних файлів.
Файлова система ext4 була відформатована зі стандартним співвідношенням інодів, придатним для загальних навантажень, але не для «мільйонів шард».
Вузли не вичерпали байти; вони вичерпали ідентичності файлів. Оптимізація фактично стала стрес-тестом для інодів.
Вони намагалися «вирішити» це, збільшивши розмір диска. Це не допомогло, бо кількість інодів залишилася фіксованою.
Потім відформатували заново з вищою щільністю інодів і змінили стратегію кешування, пакуючи партії в tar-подібні бандли.
Продуктивність трохи впала. Надійність значно покращилась. Це прийнятна компромісна угода.
3) Нудна, але правильна практика, що врятувала день: окремі файлові системи і запобіжники
Інша організація запускала змішані навантаження на Kubernetes-нодах: системні сервіси, Docker/containerd і локальний scratch.
У них було одне правило: все, що може вибухнути у кількості файлів — на окрему файлову систему. Docker жив на /var/lib/docker,
змонтованому з виділеного тому. Scratch був на окремому монту з агресивними політиками очищення.
Також вони мали два нудні монітори: «блоки» і «іноди». Ніякого складного ML. Просто дві часові серії і алерти, які дзвонили до краю.
Вони тестували алерти щоквартально, створюючи тимчасову бурю інодів у staging (так, таке роблять).
Одного дня новий pipeline збірки почав продукувати патологічні шари з величезними деревами залежностей.
Іноди на Docker-тобі зросли швидко. Алерт спрацював раніше. Черговий не мусив вивчати нічого нового під стресом.
Вони зробили prune, відкотили pipeline і підвищили ліміти. Решта ноди залишилась здорова, бо кореневий розділ не постраждав.
Звіт по інциденту був коротким. Виправлення — нудне. Усі спали.
Ось в чому суть SRE.
Цікаві факти та трохи історії (бо це пояснює режими відмов)
- Іноди походять з раннього Unix: концепція сягає оригінального дизайну файлової системи Unix, де метадані і блоки даних були окремими структурами.
- Традиційні ext-файлові системи передвиділяють іноди: ext2/ext3/ext4 зазвичай визначають кількість інодів під час mkfs на основі співвідношення bytes-per-inode, а не динамічно під навантаження.
- Стандартні співвідношення інодів — компроміс: вони орієнтовані на загальні навантаження; не оптимізовані для шарів контейнерів, кешів CI або вибухової maildir-активності.
- Директорії теж коштують інодів: «ми лише створили директорії» не є виправданням; кожна директорія також споживає інод.
- «No space left on device» має багато значень: той самий рядок помилки може означати вичерпання блоків, інодів, перевищення квоти або навіть те, що файлова система переведена у режим лише читання після помилок.
- Резервні блоки існують не просто так: ext4 зазвичай резервує відсоток блоків для root, щоб система лишалася працездатною під тиском; іноди так само не резервуються.
- Навантаження з дрібними файлами важче, ніж здається: операції з метаданими домінують; ефективність роботи з інодами і пошуком у директоріях може важити більше, ніж пропускна здатність.
- Контейнерні образи підсилюють патерни дрібних файлів: екосистеми мов з великими деревами залежностей (Node, Python, Ruby) можуть створювати шари з масивною кількістю файлів.
- Деякі файлові системи рухаються в бік динамічних метаданих: XFS і btrfs інакше працюють з метаданими, що змінює форму «повних» відмов, але не усуває їх повністю.
Виправлення: від швидкого очищення до постійного запобігання
Негайна стабілізація (хвилини): звільніть іноди, не погіршуючи ситуацію
Ваше завдання під час інциденту — не «зробити красиво». Воно — «зробити знову записуваним» без видалення неправильних речей.
Ось що зазвичай безпечно і ефективно, за спаданням здорового глузду:
- Видаляйте відомі ефемерні кеші (кеш збірок, пакетний кеш, тимчасові файли) командами, призначеними для цього.
- Prune сміття контейнерів, якщо хост контейнерний і ви можете дозволити видалення невикористовуваних артефактів.
- Видаляйте старі файли, засновані на часі, а не на припущеннях. Віддавайте перевагу політикам «старше за N днів».
- Перемістіть директорії з файлової системи, якщо видалення ризиковане: архівуйте на інший монтувальний шлях, потім видаляйте локально.
Якщо це пов’язано з логами: вирішуйте проблему з кількістю файлів, а не лише з ротацією
Logrotate вирішує «один файл виростає вічно». Він не вирішує автоматично «ми створюємо один файл на запит».
Якщо ваш додаток створює унікальні лог-файли на одиницю роботи (request ID, job ID, tenant ID), ви самі атакуєте свою таблицю інодів.
Надавайте перевагу:
- єдиному потоку логів зі структурованими полями (JSON підходить, але тримайте його в розумних межах)
- інтеграції з journald там, де доречно
- обмеженому локальному спулінгу з явним збереженням термінів
Якщо це Docker: обирайте data root відповідно до навантаження
Docker на ext4 може працювати добре, поки не стане погано. Якщо ви знаєте, що вузол буде збирати образи, запускати багато контейнерів
і активно псувати шари — ставтесь до /var/lib/docker як до datastore з високим churn і дайте йому окремий том.
Практичні опції:
- Окремий монтувальний том для
/var/lib/dockerз щільністю інодів, що відповідає очікуваній кількості файлів. - Планове очищення кешу збірок, а не ручне під час аварій.
- Виправлення образів для зменшення розгалуження файлів: multi-stage builds, обрізання залежностей,
.dockerignore.
Постійне виправлення: проєктуйте файлову систему під навантаження
Якщо вичерпання інодів повторюється, у вас не проблема «прибрати». У вас проблема планування потужностей.
На ext4 кількість інодів фіксується під час створення. Єдиний реальний вихід — міграція на файлову систему з більшою кількістю інодів
(або інший лейаут), що означає:
- створити нову файлову систему з вищою щільністю інодів
- перенести дані
- оновити монтування та сервіси
- додати моніторинг і політики зберігання
Як створити ext4 з більшою кількістю інодів (планована міграція)
Кількість інодів у ext4 впливається параметром -i (bytes-per-inode) і -N (явна кількість інодів).
Менше байтів-на-інод означає більше інодів. Більше інодів — більше метаданих. Це компроміс, не безкоштовні ласощі.
cr0x@server:~$ sudo mkfs.ext4 -i 16384 /dev/sdc1
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 976754176 4k blocks and 61079552 inodes
Filesystem UUID: 9f1f4a1c-8b1d-4c1b-9d88-8d1aa14d4e1e
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done
Значення: Цей приклад створює набагато більше інодів, ніж дефолтне співвідношення на тому ж розмірі тому.
Рішення: Використовуйте це лише коли точно знаєте, що вам потрібні тисячі/мільйони файлів. Для великих послідовних даних не витрачайте метадані даремно.
Жарт №2: Якщо ви поводитесь з файловою системою як з базою даних — вона колись виставить вам рахунок інодами.
Типові помилки: симптом → корінь → виправлення
1) «df показує 30% використано, але я не можу записати файли» → вичерпання інодів → перевірити та видалити точки з великою кількістю дрібних файлів
- Симптом: записи не вдаються,
touchпадає,aptламається, сервіси падають при створенні тимчасових файлів. - Корінь:
df -iпоказує 100% використання інодів на монті. - Виправлення: знайдіть директорії з найбільшою кількістю файлів за допомогою
du --inodes/find ... | wc -l, видаліть безпечні ефемерні файли, потім запобігайте повторенню.
2) «Видалив великий файл, але все ще не працює» → ви звільнили блоки, не іноди → видаліть багато файлів замість одного
- Симптом: кількість вільних ГБ зросла, але «No space left» продовжує з’являтися.
- Корінь: використання інодів не змінилося.
- Виправлення: звільніть іноди, видаляючи велику кількість файлів, а не одиничні великі файли. Цільте кеші, спули, артефакти збірок.
3) «Тільки root може писати; користувачі — ні» → резервні блоки або квоти → перевірте за допомогою tune2fs та інструментів квот
- Симптом: root може створювати файли, non-root — ні.
- Корінь: відсоток резервних блоків на ext4 або досягнуті користувацькі квоти.
- Виправлення: перевірте резервні блоки за допомогою
tune2fs; перевірте квоти; налаштовуйте обережно. Не ставте резервні блоки в 0% на системних розділах без розуміння наслідків.
4) «Він став read-only і тепер все ламається» → помилки файлової системи → дивіться dmesg, запускайте fsck офлайн
- Симптом: ядро перемонтувало з
errors=remount-ro, записи падають з помилками read-only. - Корінь: помилки введення/виведення або корупція, а не брак ємності.
- Виправлення: інспектуйте
dmesg; плануйте ребут у recovery та запустітьfsck. Очищення місця не виправить корупцію.
5) «Kubernetes node має DiskPressure, але df виглядає добре» → inode-тиск від runtime контейнерів → prune і окремі монти
- Симптом: поди відкидаються; kubelet скаржиться; вузол нестабільний.
- Корінь: директорії runtime заповнили бюджет інодів (overlay2, логи).
- Виправлення: очистіть runtime storage, примусьте image garbage collection, розмістіть runtime на виділеному томі з моніторингом.
6) «Ми почистили /tmp; допомогло на годину» → додаток відтворює бурю → фіксуйте утримання у джерелі
- Симптом: повторні інциденти інодів після очищення.
- Корінь: баг додатку, поганий дизайн (один файл на подію) або відсутній TTL/ротація.
- Виправлення: додайте політику утримання, переробіть сховище (БД/черга/object store), примусьте ліміти і алерти.
Контрольні списки / покроковий план
Чекліст для чергового (стабілізувати за 15–30 хвилин)
- Запустіть
df -hTіdf -iTдля проблемного монту. - Підтвердіть через
touchу ураженому шляху. - Знайдіть відповідний монтувальний шлях з
findmnt -T. - Визначте топ-споживачів інодів з
du -x --inodes --max-depth=2і цілеспрямованимиfind ... | wc -l. - Виберіть одне безпечне та високоефективне очищення (Docker prune, очищення кешу, видалення за часом).
- Пере-перевіряйте
df -iпоки не опуститесь під ~90% на критичному монті. - Перезапустіть впливові сервіси (тільки після того, як записи знову працюють).
- Зберіть докази: виконані команди, рахунок інодів до/після, відповідальні директорії.
Інженерний чекліст (запобігання повторенню)
- Додайте моніторинг і алерти на використання інодів по файлових системах (не лише відсоток диску).
- Помістіть високочастотні директорії на виділені монти:
/var/lib/docker, спул аплікацій, кеш збірок. - Впровадьте утримання у виробника: TTL, ліміти, періодична компакція або інше сховище.
- Перегляньте збірки та образи: зменште кількість файлів у шарах; уникайте вендорингу великих дерев залежностей в runtime.
- Якщо використовуєте ext4 для навантажень з дрібними файлами — задайте щільність інодів під час форматування і задокументуйте вибір.
- Проведіть game day у staging: симулюйте тиск інодів і перевірте алерти та recovery-процедури.
Чекліст міграції (коли кількість інодів ext4 фундаментально не підходить)
- Виміряйте поточну кількість файлів і темп росту (щоденні нові файли, поведінка зберігання).
- Виберіть ціль: ext4 з вищою щільністю інодів, XFS, або іншу архітектуру (object storage, БД, черга).
- Проведіть підготовку нового тому і файлової системи; змонтуйте на призначений шлях.
- Зупиніть робоче навантаження, скопіюйте дані (збережіть власність/права), перевірте, потім переключіться.
- Увімкніть робоче навантаження з увімкненими політиками утримання з першого дня.
- Залиште запобіжники: алерти, таймери очищення і жорстку політику ліміту.
FAQ
1) Що таке інод в одному реченні?
Інод — це запис метаданих файлової системи, що представляє файл або директорію; для створення нового файлу потрібен вільний інод.
2) Чому Ubuntu каже «No space left on device», коли df -h показує вільне місце?
Тому що «місце» може означати байти (блоки) або метадані файлів (іноди). df -h показує блоки; df -i — іноди.
3) Як швидко підтвердити вичерпання інодів?
Запустіть df -i на монті і перевірте на IUse% 100%, потім спробуйте touch, щоб підтвердити, що створення файлу не вдається.
4) Чи можна збільшити кількість інодів на існуючій ext4-файловій системі?
Практично — ні. Кількість інодів ext4 фактично фіксується при створенні файлової системи. Реальне рішення — міграція на нову файлову систему з потрібною кількістю інодів.
5) Чому контейнери роблять проблеми з інодами більш імовірними?
Шари образів і дерева залежностей можуть містити величезну кількість дрібних файлів. Overlay-сховище множить операції з метаданими, а кеші збірок накопичуються непомітно.
6) Чи безпечно видаляти одну велику директорію?
Іноді. Безпечніше видаляти файли з відомого ефемерного шляху за часовим критерієм, ніж видаляти директорію, яку сервіс очікує бачити. Віддавайте перевагу цілеспрямованому видаленню і перевіряйте конфігурації сервісів.
7) Що варто моніторити, щоб виявити це раніше?
Моніторте використання інодів по файлових системах (df -i) і ставте алерти на стійке зростання або порогові значення (наприклад, 85% і 95%), а не лише на відсоток диску.
8) Якщо я вичерпав іноди, чи варто перезавантажуватися?
Перезавантаження не створить інодів. Воно може тимчасово очистити деякі тимчасові файли, але це не вирішення і може ускладнити розслідування. Краще звільнити іноди цілеспрямовано.
9) Чому інодами іноді страждає лише один додаток?
Тому що тільки додатки, які створюють нові файли, блокуються. Сервіси, що лише читають, можуть продовжувати працювати до першої спроби запису логів, сокету чи стану.
10) Чи можуть журнали journald викликати вичерпання інодів?
Менш ймовірно, ніж «один файл на подію» логування додатків. journald зазвичай зберігає дані в небагатьох більших файлах, що більше тисне по блоках, ніж по інодах.
Наступні кроки, які варто зробити
Якщо ви візьмете лише одну звичку з цього: коли бачите «No space left on device», запускайте df -i так само автоматично, як df -h.
Файлова система має два ліміти, і продакшн не піклується про те, який саме ви забули моніторити.
Практичні наступні кроки:
- Додайте алерти на іноди на кожному персистентному монту (особливо
/і сховище runtime контейнерів). - Перенесіть шляхи з високою частотою створення файлів на окремі файлові системи, щоб одне погане навантаження не виводило з ладу весь вузол.
- Виправте поведінку виробника: TTL, ліміти, менше файлів, краще пакування артефактів.
- Для ext4 плануйте щільність інодів наперед під навантаження з дрібними файлами та документуйте вибір.
- Проведіть мікро-тест: створіть контрольовану бурю інодів у staging, перевірте алерти і процедури відновлення.
Вам не потрібні більше диску. Потрібно менше файлів, кращий lifecycle і розкладка файлової системи, що відповідає реальності, а не припущенням.