Привичка перезавантажувати — це податок, який ви платите вічно. Вона дає кілька хвилин спокою, стирає ваші сліди з місця подій і тихо гарантує, що ви побачите той самий інцидент знову — зазвичай о 2:13 ранку під час деплою, коли хтось «просто хоче, щоб воно працювало».
Ubuntu 24.04 — надійна база. Коли щось йде не так, це рідко тому, що ОС просто вирішила бути хаотичною. Це тому, що трапилось щось вимірюване: накопичилась черга, тиск пам’яті перейшов поріг, відпрацювання ядра застрягло, мережевий інтерфейс флапнув, файлову систему призупинило, сервіс застряг у поганому стані. Ваше завдання — не перезавантажувати докази. Ваше завдання — ізолювати корінну причину і вирішити найменше можливе безпечне виправлення.
Перезавантаження — це не фікс: мислення для продакшну
Перезавантаження — це грубий інструмент. Воно очищає пам’ять, скидає драйвери, вбиває застряглі процеси і робить метрики «хорошими», бо ви обнуляєте лічильники. Це технічний еквівалент того, як зробити тишіше музику в машині, щоб почути шум двигуна: вам стане легше, але двигун усе ще вмирає.
У продакшні ви оптимізуєте під повторюване відновлення і ізоляцію кореня проблеми. Це означає:
- Спочатку стримування: припинити вплив на користувачів, обмежити радіус ураження, зменшити навантаження.
- Збирання доказів: журнали, стан, лічильники, черги — перш ніж їх скинути.
- Найменша відкатна зміна: перезапустити один сервіс, перечитати конфіг, віддати вузол з балансувальника, відключити один feature flag.
- Корінна причина: доведіть її даними, а не відчуттями.
Якщо ваш процес — «перезавантажити і сподіватися», ви тренуєте організацію сприймати нез’ясовані відмови як норму. Це не стійкість. Це синдром Стокгольма з дашбордами uptime.
Коли варто тримати на стіні: Джин Кранц (керівник польотів Apollo) культивував культуру «суворий і компетентний». Парафраз: Будьте суворі й компетентні — використовуйте дисциплінований процес під тиском.
Це і є робота опсів у випадковий вівторок.
Жарт №1: Перезавантажувати продакшн, щоб виправити його — це як підігріти мікрохвильовкою телефон, бо він повільний. Отримаєте тепло, але не вирішите справжню проблему.
Факти та контекст: чому це повторюється
Ось кілька конкретних, неміфічних фактів, які пояснюють, чому «перезавантаження виправило» так часто — і чому це вводить в оману:
- Раніше Linux рідше потребував перезавантаження для застосування змін, ніж Windows, але проблеми з драйверами та баги ядра все ще існують. Багато «перезавантажень, які вирішили проблему» — насправді історії про скидання стану драйвера.
- systemd зробив управління сервісами радикально більш послідовним, ніж ad-hoc init-скрипти. Це також означає, що часто проблему можна виправити цільовим
systemctl restartзамість повного перезавантаження. - Перехід Ubuntu на передбачувані імена мережевих інтерфейсів зменшив хаос «eth0 зник», але неправильно налаштований netplan все ще може викликати тонкі проблеми з лінком/маршрутом, які триватимуть, поки не зроблено reload.
- cgroups еволюціонували від «приємної можливості» до «площини контролю ресурсів» (особливо з контейнерами). Багато «випадкових уповільнень» — це насправді обмеження cgroup, тиск пам’яті або IO weight, які виконують саме те, що ви задали.
- NVMe приніс чудову латентність — і нові режими відмов: проблеми з прошивкою, особливості управління живленням PCIe і періодичні помилки медіа, що проявляються як затримки IO, а не як чисті відмови.
- OOM killer — це не помилка; це політика. Він вбиває процес, щоб зберегти ядро живим. Перезавантаження після OOM часто означає відмову вивчити, який процес «з’їдає» машину.
- Структуровані журнали journald змінили реагування на інциденти: ви можете фільтрувати по завантаженню, юніту, пріоритету, PID і часовому вікні. Це докази, яких не було в розкиданих текстових файлах.
- Сучасні ядра можуть «зависати» без краху: soft lockup, RCU stalls, заблокований IO і очікування транзакцій файлової системи. Сервер виглядає живим, але прогрес уповільнено або зупинено.
- Хмара зробила «перезавантаження» небезпечно дешевим: звичка перейшла з десктопів у флоти, і раптом ніхто не пам’ятає зберегти судові дані (forensics).
Ubuntu 24.04 (Noble) особливо «наглядна», якщо ви використовуєте те, що вже є: systemd, journald, журнали ядра, лічильники продуктивності та метрики, які вам і так слід було мати. Плейбук нижче припускає, що ви готові дивитися.
Швидкий плейбук діагностики (перший/другий/третій)
Це послідовність триажу, яка швидко знаходить вузькі місця, не заглиблюючись у тривіум. Використовуйте її, коли дзвонить сторінка і у вас є хвилини, щоб зробити систему менш полум’яною.
Перший: визначте режим відмови (CPU, пам’ять, диск чи мережа?)
- Чи відповідає машина? Можна SSH? Чи виконуються команди за 1–2 секунди?
- Чи бреше load average? Load може бути високим через навантаження на CPU або через те, що завдання застрягли в uninterruptible IO sleep.
- Чи активний своп або OOM? Тиск пам’яті викликає каскадні відмови: повільні алокації, своп-шторм, IO, таймаути.
- Чи стрибнула латентність диска? Високий await / довгі черги заморожують усе, що торкається сховища.
- Чи мережа є вузьким місцем? Перегрузки, втрати, DNS-невдачі, невідповідність MTU — класичне «воно ніби вгору, але не працює».
Другий: визначте «хто» (який процес/юнит і яка залежність)
- Головні підозрювані: CPU‑хог, витік пам’яті, застряглі потоки або занадто багато процесів.
- Мапа залежностей: чи чекає ваш додаток на БД, DNS, NFS, об’єктне сховище або локальний диск?
- Стан сервісу: стан systemd-юніту, петля рестартів, тригери watchdog.
Третій: зробіть найменше безпечне виправлення, потім підтвердіть метриками
- Зменште навантаження: зніміть вузол з LB, призупиніть батч‑задачі, обмежте швидкість, відключіть бюджетоємні feature flags.
- Цільовий рестарт: перезапустіть сервіс, а не машину, хіба що ви робите контрольований скидання драйвера/ядра для відомої проблеми.
- Підтвердьте: чи впала латентність, знизився рівень помилок, чи спорожнились черги, чи нормалізувалися ресурси?
- Збережіть докази: навіть якщо доведеться перезавантажити, спершу збережіть уривки журналів, лог ядра і стан.
Ця послідовність допомагає уникнути пастки «бачив високий load, отже CPU», через яку люди масштабують CPU, поки справжня причина — черга на диску, що застопорилася за одним сумним NVMe таймаутом.
Практичні завдання (команди, виводи, рішення)
Нижче — практичні завдання, які можна виконати на Ubuntu 24.04 під час інциденту. Кожне містить: команду, реалістичний шматок виводу, що це означає, і рішення, яке ви приймаєте.
Завдання 1: Визначити, чи це тиск CPU чи IO wait
cr0x@server:~$ uptime
14:22:10 up 18 days, 3:11, 2 users, load average: 18.72, 17.95, 16.40
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
6 0 0 412180 90244 3218120 0 0 12 110 980 2100 45 10 40 5 0
3 2 0 398200 90244 3221200 0 0 240 9010 1200 2600 18 6 22 54 0
2 4 0 390112 90244 3221456 0 0 180 12050 1180 2500 10 4 18 68 0
Значення: load високий, але b (blocked) зростає і wa (IO wait) величезний. Це не «тільки CPU». Це «потоки застрягли, чекаючи на сховище».
Рішення: не масштабувати CPU. Перемкніться на перевірку латентності диска та файлової системи/RAID/NVMe.
Завдання 2: Перевірити латентність дисків і глибину черги
cr0x@server:~$ iostat -x 1 3
Linux 6.8.0-41-generic (server) 12/30/2025 _x86_64_ (8 CPU)
Device r/s w/s rkB/s wkB/s aqu-sz await r_await w_await %util
nvme0n1 12.0 220.0 384.0 9012.0 18.40 78.20 6.10 82.10 99.2
nvme1n1 0.0 0.0 0.0 0.0 0.00 0.00 0.00 0.00 0.0
Значення: %util ~99% і await ~78ms на nvme0n1 — це погано для системи, що очікує мілісекундної латентності. aqu-sz глибока: запити ставляться в чергу.
Рішення: знайти, хто пише, перевірити файлову систему, пошукати насичення або помилки, розглянути обмеження винуватця.
Завдання 3: Визначити процеси‑лідери за записом на диск
cr0x@server:~$ sudo iotop -oPa
Total DISK READ: 1.10 M/s | Total DISK WRITE: 102.45 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
8921 be/4 postgres 0.00 B/s 68.20 M/s 0.00 % 7.10 % postgres: checkpointer
25140 be/4 root 0.00 B/s 22.30 M/s 0.00 % 3.20 % /usr/bin/rsync -aH --delete /var/lib/app/ /mnt/backup/
Значення: PostgreSQL checkpointer і job резервного копіювання сильно пишуть. Бекап може відбирати IO у найгірший момент.
Рішення: призупинити/змінити пріоритет/ionice бекап, перевірити налаштування DB checkpoint, переконатися, що ви не робите snapshot у пік.
Завдання 4: Підтвердити тиск пам’яті та поведінку свопу
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 31Gi 28Gi 510Mi 2.1Gi 2.5Gi 1.1Gi
Swap: 4.0Gi 3.6Gi 410Mi
Значення: Своп дуже використовується; «available» низьке. Це часто перетворює «прийнятну» латентність на болото.
Рішення: знайти споживача пам’яті, зупинити витік, обмежити через systemd/cgroups або масштабувати пам’ять — але тільки після доведення, що це не шкідлива задача.
Завдання 5: Зловити події OOM killer і жертву
cr0x@server:~$ journalctl -k -b | grep -i -E "oom|out of memory|killed process" | tail -n 5
Dec 30 13:58:41 server kernel: Out of memory: Killed process 18221 (java) total-vm:9643212kB, anon-rss:6123400kB, file-rss:10240kB, shmem-rss:0kB, UID:1001 pgtables:18432kB oom_score_adj:0
Значення: Ядро вбило Java‑процес через виснаження пам’яті. Перезавантаження «виправляє» це, бо видаляє порушника і очищає кеші, а не тому, що система зцілилася.
Рішення: виправити розмір пам’яті/ліміти, знайти витік, додати запобіжники (systemd MemoryMax, ліміти контейнерів) і переконатися, що параметри купи (heap) додатка відповідають реальності.
Завдання 6: Знайти юніт у петлі рестартів або що флапає
cr0x@server:~$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● app-api.service loaded failed failed App API service
cr0x@server:~$ systemctl status app-api.service --no-pager -l
× app-api.service - App API service
Loaded: loaded (/etc/systemd/system/app-api.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 2025-12-30 14:10:18 UTC; 2min 1s ago
Process: 24410 ExecStart=/usr/local/bin/app-api (code=exited, status=1/FAILURE)
Memory: 1.2G
CPU: 11.203s
Dec 30 14:10:18 server app-api[24410]: FATAL: cannot connect to Redis: dial tcp 10.20.0.15:6379: i/o timeout
Dec 30 14:10:18 server systemd[1]: app-api.service: Main process exited, code=exited, status=1/FAILURE
Dec 30 14:10:18 server systemd[1]: app-api.service: Failed with result 'exit-code'.
Значення: Додаток не «зламаний»; він падає, бо Redis недосяжний або повільний. Перезавантаження хосту додатка не вирішить шлях мережі або перевантаженість Redis.
Рішення: перейти до залежності: перевірити досяжність Redis, його латентність і валідність маршрутизації/фаєрволу.
Завдання 7: Перевірити попередження ядра, що натякають на затримки або скидання драйвера
cr0x@server:~$ journalctl -k -b -p warning..alert --no-pager | tail -n 20
Dec 30 14:01:12 server kernel: INFO: task kworker/u16:3:1123 blocked for more than 120 seconds.
Dec 30 14:01:12 server kernel: nvme nvme0: I/O 224 QID 3 timeout, aborting
Dec 30 14:01:42 server kernel: nvme nvme0: Abort status: 0x371
Dec 30 14:02:10 server kernel: EXT4-fs warning (device nvme0n1p2): ext4_end_bio:340: I/O error 10 writing to inode 524313 (offset 0 size 4096)
Значення: NVMe таймаути і помилки ext4 IO — це не «випадкова повільність». Це проблема сховища, можливо апаратна або прошивкова.
Рішення: захистити дані, планувати технічне обслуговування, перевірити SMART/NVMe‑здоров’я, розглянути виведення пристрою з експлуатації і припинити вдавати, що перезавантаження це «ремонт».
Завдання 8: Перевірити здоров’я NVMe та журнал помилок
cr0x@server:~$ sudo nvme smart-log /dev/nvme0
Smart Log for NVME device:nvme0 namespace-id:ffffffff
critical_warning : 0x00
temperature : 49 C
available_spare : 100%
available_spare_threshold : 10%
percentage_used : 7%
data_units_read : 193,421,112
data_units_written : 882,100,420
media_errors : 12
num_err_log_entries : 98
cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head -n 8
Error Log Entries for device:nvme0 entries:64
Entry[ 0]
error_count : 98
sqid : 3
cmdid : 0x00d1
status_field : 0x4004
lba : 182736128
Значення: media_errors і зростаючий журнал помилок корелюють з таймаутами ядра. Це тренд до реальної відмови.
Рішення: запланувати заміну, зменшити write amplification, перевірити резервні копії і перемістити критичні сервіси з цього пристрою.
Завдання 9: Перевірити вільне місце/іноди файлової системи (нудний генератор відмов)
cr0x@server:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 220G 218G 1.2G 100% /
tmpfs 16G 1.2G 15G 8% /run
cr0x@server:~$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/nvme0n1p2 14417920 14399811 18109 100% /
Значення: Повний диск або вичерпання інодів викликають «випадкові» відмови: сервіс не може записати PID‑файл, логи не пишуться, бази даних відмовляються комітити, apt ламається, сокети фейляться.
Рішення: видалити/прокрутити логи, очистити старі релізи, виправити runaway створення файлів, додати квоти і налаштувати алерти до досягнення 100% знову.
Завдання 10: Помітити виснаження дескрипторів файлів (стелс‑ліміт)
cr0x@server:~$ cat /proc/sys/fs/file-nr
10240 0 1048576
cr0x@server:~$ sudo lsof | wc -l
245112
Значення: Системний ліміт дескрипторів в порядку, але сама кількість відкритих файлів вказує на високу конкуренцію або витік (сокети/файли не закриваються).
Рішення: перевірити ліміти на процес (ulimit, systemd LimitNOFILE=), знайти процес‑втік і виправити його — не перезавантажуйте, щоб «закрити файли».
Завдання 11: Довести втрати мережі, повторні передавання і дивні маршрути
cr0x@server:~$ ip -s link show dev enp5s0
2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 3c:ec:ef:12:34:56 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped missed mcast
10498312323 8123312 0 24810 0 12901
TX: bytes packets errors dropped carrier collsns
9983211121 7921101 0 120 0 0
cr0x@server:~$ ss -s
Total: 2135 (kernel 0)
TCP: 1980 (estab 1120, closed 650, orphaned 3, timewait 645)
Transport Total IP IPv6
RAW 0 0 0
UDP 62 55 7
TCP 1330 1211 119
INET 1392 1266 126
FRAG 0 0 0
Значення: RX‑dropping значне. Це не «додаток повільний», це «пакети втрачаються», що призводить до ретраїв, таймаутів і сумних дашбордів.
Рішення: розслідувати розміри кілець NIC, насичення softirq на CPU, помилки портів комутатора, невідповідність MTU і сплески трафіку. Перезавантаження може тимчасово очистити черги, але не виправить поганий лінк чи oversubscription.
Завдання 12: Швидко перевірити DNS (бо все від нього залежить)
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.10.0.53
DNS Servers: 10.10.0.53 10.10.0.54
Link 2 (enp5s0)
Current Scopes: DNS
DNS Servers: 10.10.0.53 10.10.0.54
cr0x@server:~$ dig +time=1 +tries=1 api.internal A @10.10.0.53
; <<>> DiG 9.18.24-1ubuntu0.1-Ubuntu <<>> +time=1 +tries=1 api.internal A @10.10.0.53
;; connection timed out; no servers could be reached
Значення: DNS таймаутиться. Багато сервісів «таємничо» падають, коли резолюція імен затримується.
Рішення: переключитися на запасні резолвери, виправити upstream DNS і уникати рестартів додатків, які лише збільшать навантаження на вмираючий рівень DNS.
Завдання 13: Перевірити throttling cgroup (контейнери і systemd це роблять)
cr0x@server:~$ systemctl show app-api.service -p CPUQuota -p MemoryMax -p IOWeight
CPUQuota=50%
MemoryMax=2147483648
IOWeight=100
Значення: Ви навмисно обмежили CPU до 50% і пам’ять до 2GiB. Якщо сервіс повільний під навантаженням, він може просто виконувати ваші обмеження, а не «неправильно працювати».
Рішення: перевірте, чи відповідають обмеження SLO; регулюйте квоти обдумано, не «виправляйте» перезавантаженням у тих самих межах.
Завдання 14: Зберіть докази перед будь‑якими змінами
cr0x@server:~$ sudo journalctl -b --since "2025-12-30 13:30" --until "2025-12-30 14:30" -o short-iso > /tmp/journal-incident.txt
cr0x@server:~$ sudo dmesg -T > /tmp/dmesg-incident.txt
cr0x@server:~$ ps -eo pid,ppid,cmd,%cpu,%mem,stat --sort=-%cpu | head -n 15 > /tmp/ps-topcpu.txt
cr0x@server:~$ ps -eo pid,ppid,cmd,%cpu,%mem,stat --sort=-%mem | head -n 15 > /tmp/ps-topmem.txt
Значення: Тепер ви зберегли історію. Якщо доведеться рестартувати сервіси або навіть перезавантажити — ви не викидаєте підказок.
Рішення: продовжуйте з пом’якшенням, знаючи, що можете провести пост‑інцидентний RCA на основі збережених артефактів.
Жарт №2: Якщо перезавантаження — єдиний ваш крок троблшутингу, вітаю — ви винайшли дуже дорогу кнопку живлення.
Три корпоративні міні‑історії (реалістично, болісно, корисно)
Міні‑історія 1: Інцидент через неправильне припущення
У них був внутрішній API‑шар на Ubuntu. Коли латентність зросла, on‑call рефлексом перезапускали API‑сервіс. Коли це не допомагало, перезавантажували VM. Це працювало достатньо часто, щоб ніхто не ставив під сумнів.
Одної п’ятниці перезавантаження не допомогло. Помилки повернулись негайно: таймаути до кеш‑кластера. Інцидент‑командир припустив «кеш впав». Тому команда кешу отримала пейдж, потім команда мережі, потім безпека. Класичне корпоративне кровопролиття: три команди сперечаються в чаті, а клієнти чекають.
Насправді проблема була простішою й повчальнішою. Новий netplan‑запис додав статичний маршрут, який випадково затіняв підмережу кешу через неправильний шлюз. Більшість трафіку все ще працювала, бо дефолтний маршрут був ок. Лише кеш‑трафік пішов кривим шляхом через фаєрвол, який обмежував швидкість.
Перезавантаження «виправляло» це раніше, бо маршрут іноді некоректно застосовувався після часткових оновлень конфига — питання таймінгу і стану. Цього разу маршрут застосувався коректно, тож проблема стала детермінованою. Перезавантаження не скинуло поганий маршрут; воно його просто знову завантажило.
Після цього вони зробили дві речі: (1) трактувати «залежність недоступна» як мережеву/маршрутну проблему, поки не доведено інше, і (2) зберігати диф‑маршрутів і валідувати конфіг у CI. Звичка перезавантажувати маскувала неправильну конфігурацію, а не вирішувала інциденти.
Міні‑історія 2: Оптимізація, що обернулась проти
Сервіс з інтенсивним записом у сховище «оптимізували», перемістивши логи на швидкий локальний NVMe і підвищивши рівень логування для кращого дебагу. Команда також загострила logrotate, бо одного разу їх підпалив повний диск. Мотиви розумні. Погана взаємодія.
На масштабі гучний лог‑вивід означав часті записи. Розклад logrotate був агресивний, і пост‑rotate хук надсилав сигнали, щоб перечитали кілька сервісів. При сплесках трафіку logrotate починався, стискав логи і викликав спайк CPU та IO саме тоді, коли додаток найбільше потребував ресурсів.
Користувачі бачили періодичні обриви латентності кожну годину. On‑call перезавантажував вузли, бо «це очищує повільність». Перезавантаження допомагало, бо переривало компресію і скидало черги. Ніхто не зв’язав годинний патерн, бо людям важко помічати часові закономірності в голові.
Коли вони наклали графіки дискового await і CPU iowait, усе стало очевидним: кожен обрив співпадав із logrotate. Виправлення було нудним: зменшити обсяг логів, перейти на асинхронну відправку, рознести ротацію в часі і прибрати reload‑хуки, які не були потрібні. Також додали алерти на латентність диска, а не тільки «використання диска».
Висновок: «оптимізація» без вимірювання другорядних ефектів — це просто гра з кращою лексикою.
Міні‑історія 3: Нудна, але правильна практика, що врятувала
Фінтех‑компанія працювала на Ubuntu 24.04 для обробки транзакцій. У них було суворе правило інцидентів: перед будь‑яким перезавантаженням зберегти journal і логи ядра за релевантне вікно, плюс один знімок процесів і мережевого стану. Без винятків, якщо хост прямо не пошкоджує дані.
Одної ночі підмножина вузлів почала зависати. Не падати. Просто зависати: зростаючий load, підвищена латентність, періодичні таймаути. Найшвидшим «фіксом» було б перезапустити вузли. Натомість on‑call дотримався правила і зібрав докази.
Журнали ядра показали NVMe таймаути, але тільки після специфічних патернів: сплеск sync‑записів від певної версії сервісу. Знімки процесів показали, що ця версія включила feature flag, який збільшив частоту fsync.
Вони відкотили feature flag, латентність стабілізувалась, і вузли відновились без перезавантажень. Пізніше, збережені логи дозволили співпрацювати з вендором для оновлення прошивки NVMe і відрегулювати стратегію надійності додатка. Докази перетворили північну загадку на план дій.
Це «нудне правило» не тільки допомогло діагностувати. Воно запобігло більшій відмові: перезавантаження сховало б проблему на рівні сховища до тих пір, поки це не переросло в втрату даних. У продакшні нудне часто означає «безпечне».
Поширені помилки: симптом → корінь → виправлення
1) «Високий load average означає, що CPU навантажений»
Симптом: Load average 20+, додаток повільний, але графіки CPU виглядають «не настільки погано».
Корінь: Завдання блокуються на IO (стан D). Load включає uninterruptible sleep; це часто латентність сховища.
Виправлення: Використовуйте vmstat (b, wa), iostat -x (await, util), потім знайдіть IO‑хогів (iotop).
2) «Перезавантаження виправило, отже це була проблема ядра»
Симптом: Перезавантаження очищає проблему на години/дні; інцидент повторюється.
Корінь: Витік пам’яті, витік дескрипторів файлів, поступове накопичення черг, заповнення логів/диска або застрягла залежність.
Виправлення: Збирайте докази; відстежуйте зростання (RSS, відкриті файли, використання диска, довжина черг). Перезапустіть винний юніт і виправте витік або встановіть ліміти.
3) «Додаток впав», коли насправді це DNS
Симптом: Випадкові таймаути до внутрішніх сервісів; рестарти додатків нічого не змінюють.
Корінь: Резолвер таймаутить, upstream упав або неправильно налаштований split‑horizon.
Виправлення: Перевірте resolvectl і тестуйте запити з короткими таймаутами (dig +time=1 +tries=1). Переключіть резолвери або відремонтуйте DNS‑рівень.
4) «Диск не повний, отже сховище не причина»
Симптом: Достатньо вільного місця, але IO повільний; сервіси зависають.
Корінь: Стрибки латентності через помилки пристрою, прошивку, write amplification або шумний писач. Також іноді іноді вичерпання інодів трапляється при наявності вільних байтів (або навпаки).
Виправлення: Перевіряйте латентність (iostat), помилки (journalctl -k), здоров’я (nvme smart-log) і іноди (df -i).
5) «Мусить бути мережа», коли насправді CPU softirq або conntrack
Симптом: Втрати пакетів, періодичні таймаути, велика кількість з’єднань.
Корінь: CPU витрачає час на обробку softirq пакетів, або таблиця conntrack під тиском викликає падіння/таймаути, часто від сплесків.
Виправлення: Корелюйте RX drops з навантаженням CPU і статистикою з’єднань; пом’якшуйте шляхом шейпінгу трафіку, налаштування або розподілу навантаження по вузлах.
6) «Петлі рестартів нешкідливі»
Симптом: Сервіс флапає; іноді «повертається», іноді ні.
Корінь: Таймаут залежності, погана конфігурація або досягнення ліміту ресурсів. Петлі рестартів підсилюють навантаження і можуть викликати каскад (thundering herd).
Виправлення: Перевірте systemctl status, налаштуйте адекватний backoff на рестарти і виправте залежності або конфіг. Віддавайте перевагу circuit breaker над сліпими рестартами.
7) «Ми підвищили продуктивність, зробивши все синхронним»
Симптом: Латентні обриви під час сплесків; дискові метрики показують стрибки.
Корінь: Надмірний fsync або синхронні записи, особливо якщо кілька сервісів ділять пристрій.
Виправлення: Виміряйте IO‑патерн; батчіть записи, регулюйте налаштування надійності усвідомлено, ізолюйте навантаження або перемістіть логи/тимчасові файли з критичних шляхів.
8) «Це витік пам’яті», коли це насправді page cache + навантаження
Симптом: Вільна пам’ять низька, люди панікують.
Корінь: Linux використовує пам’ять під кеш; низький «free» — нормальний стан. Сигнал — це «available» і активність свопу, а не просто «free».
Виправлення: Використовуйте free -h, vmstat (si/so) і тренди RSS додатків. Виправляйте тільки якщо available колапсує або починається своп‑чурн.
Чеклісти / покроковий план
Чекліст A: «Не перезавантажуйте ще» — 10‑хвилинна рутина
- Підтвердити вплив: що падає (API, БД, диск, DNS) і для кого (одна AZ/вузол чи глобально).
- Зберегти докази: вікно journal, dmesg, топ‑процеси, мережевий знімок. (Використайте Завдання 14.)
- Класифікувати вузьке місце: CPU vs пам’ять vs диск vs мережа за допомогою
vmstat,iostat,free,ip -s link. - Знайти винуватця: топ CPU/mem процес, IO‑письменник, флапаючий юніт.
- Перевірити помилки залежностей: логи додатка на «cannot connect» і таймаути; швидко валідовати DNS.
- М’яко пом’якшити: віддати вузол з LB, зупинити батч‑задачі, зменшити concurency, призупинити бекапи.
- Цільовий рестарт за потреби: перезапустити один сервіс або перечитати конфіг; підтвердити відновлення метриками.
- Тільки потім думати про перезавантаження: сценарій скидання драйвера/прошивки, петля kernel panic або невідновний deadlock — після збирання доказів.
Чекліст B: Якщо перезавантажувати, робіть це як дорослий
- Озвучте причину: «Перезавантажуємо, щоб скинути контролер NVMe після таймаутів», а не «бо повільно».
- Збережіть докази спершу: знімки journal/dmesg; зафіксуйте поточні версії ядра і прошивки.
- Злити трафік: виведіть вузол з ротації.
- Перезавантажити і валідувати: підтвердити, що симптом зник і стежити за його поверненням під навантаженням.
- Відкрити follow‑up таск: постінцидентний RCA обов’язковий; інакше ви просто запланували повторення інциденту.
Чекліст C: Поток‑післяінцидентний workflow (те, що всі пропускають)
- Таймлайн: коли почались симптоми, що змінилось, що погіршилося, що виправило.
- Корелювати сигнали: латентність диска vs рівень помилок, тиск пам’яті vs таймаути, втрати пакетів vs ретраї.
- Довести одну корінну причину: виберіть найменший набір фактів, який пояснює більшість симптомів.
- Визначити запобігання: зміни конфігу, ліміт, алерт, план потужності, оновлення runbook або політика відкату.
- Додати тест/захисну сітку: CI‑валідація netplan‑маршрутів, алерти на використання інодів, автоскейлінг за SLO тощо.
FAQ
1) Коли перезавантаження дійсно правильне рішення?
Коли є докази deadlock ядра/драйвера, повторних NVMe‑скидань або відомого бага з документованим workaround — і ви спершу зібрали логи. Також коли хост коруптує дані або не може просунутися вперед і потрібно його від’єднати.
2) Чому перезавантаження «виправляє» витоки пам’яті?
Бо воно вбиває процес‑втікача і очищає стан пам’яті. Витік залишається. Ви просто скидаєте таймер до наступного заповнення RAM.
3) Як швидко відрізнити насичення CPU від IO wait?
vmstat 1: високі us/sy з низьким wa означають CPU. Зростаючі b і високий wa натякають на IO wait. Підтвердіть за допомогою iostat -x для латентності пристрою.
4) Чому load average високий, коли CPU простоює?
Бо load включає завдання в uninterruptible sleep (часто IO). Вони зараховуються в load, але не споживають CPU‑цикли.
5) journald здається «іншим». Як його використовувати, щоб не загубитись?
Фільтруйте по завантаженню (-b), часовому вікну (--since/--until), юніту (-u) і пріоритету (-p). Обробляйте його як пошукову систему, а не як нескінченну стрічку.
6) Який найнедооціненіший сигнал дискової відмови?
Стрибки латентності і періодичні таймаути IO у логах ядра. Диски можуть бути «up» і «не повні», але при цьому не виконувати свою основну роботу — своєчасно і коректно завершувати IO.
7) Що робити, якщо залежність повільна, але не впала?
Вимірюйте і ізолюйте: додайте таймаути, circuit breaker’и і backpressure. Зменшіть навантаження на залежність (контроль cache stampede, ліміти запитів) і відокремте шумних тенантів. «Не впала» ще не означає «зручна для використання».
8) Як відучити людей від перезавантаження як рефлексу?
Зробіть збирання доказів і цільову ліквідацію дефолтною практикою. Впровадьте просте правило: «Жодного перезавантаження без заявленої гіпотези і збережених логів». Потім винагороджуйте швидкі, правильні пом’якшення — не драматичні північні геройства.
9) Який найшвидший спосіб виявити «повний диск» до відмови?
Алертуйте одночасно на використання df -h і df -i, а також на латентність запису. Диск‑повний часто передує зростання обсягу логів або runaway створення файлів — обидва передбачувані.
10) Чому перезапуск одного сервісу іноді допомагає більше, ніж перезавантаження?
Тому що це скидає зламаний стан (мертві з’єднання, застряглі потоки, витрачені дескриптори) без очищення всієї системи. Це швидше, менш ризиковано і зберігає інші здорові сервіси.
Наступні кроки для зменшення інцидентів (без героїзму)
Припиніть використовувати перезавантаження як емоційну підтримку. В Ubuntu 24.04 у вас вже є інструменти для ізоляції корінних причин: systemd, journald, журнали ядра та лічильники продуктивності, які кажуть, де справжнє вузьке місце.
Зробіть наступне:
- Прийміть 10‑хвилинну рутину: збирайте докази, класифікуйте вузьке місце, знайдіть винуватця, а потім пом’якшуйте.
- Запровадьте правило «без перезавантаження без гіпотези»: записуйте причину в канал інциденту/квиток.
- Алертуйте по правильних речах: IO‑латентність, використання інодів, активність свопу, RX‑втрати — не тільки CPU і «процент використання диска».
- Обмежуйте радіус ураження: квоти/ліміти для сервісів, rate limits для клієнтів і ізоляція шумних навантажень.
- Практикуйте цільове відновлення: перезапускайте юніти, зливаєте вузли, вимикайте фичі — доведіть, що можете відновитися без скидання всього світу.
Вам не потрібно бути шептуном ядра. Потрібно бути дисциплінованими, підозріливими щодо зручних оповідей і алергічними до «працювало після перезавантаження» як фінальної відповіді.