HostiServer
2026-06-27 13:01
Що таке systemctl: практичний гайд по systemd у 2026
Що таке systemctl: практичний гайд по systemd у 2026
Системний адміністратор у 2026 році 90% свого часу взаємодіє з сервером через одну команду: systemctl. Запуск веб-сервера, перезапуск бази даних після збійного оновлення, діагностика чому Nginx не піднявся вранці, налаштування власного сервісу. Все це робиться через одну утиліту.
Але systemctl, це лише фронтенд до systemd: системи ініціалізації і керування сервісами, яка стоїть за всім, що працює на сучасному Linux. Розуміння того, як вона працює всередині, відрізняє інженера, який копіює команди зі StackOverflow, від того, хто може за п'ять хвилин діагностувати проблему або написати власний unit-файл для свого додатку.
Ця стаття — практичний гайд для адмінів і DevOps. Усі приклади перевірені на Ubuntu 24.04 LTS / Debian 12, Rocky/AlmaLinux 9 та Arch Linux. Де поведінка відрізняється між дистрибутивами, це окремо позначено.
ℹ️ Для кого ця стаття: системні адміністратори, які щоденно працюють з Linux-серверами; DevOps-інженери, які пишуть власні unit-файли; розробники, чий додаток потребує власного сервісного юніта.
1. Що таке init-система
1.1 Роль init в Linux
Коли Linux завантажується, kernel виконує мінімум: ініціалізує драйвери, монтує root-партицію, запускає перший процес у user-space. Цей перший процес має PID 1 і називається init. Усе інше (мережа, файлові системи, сервіси, графічний інтерфейс) запускає вже він.
Завдання init:
- Запустити решту системи у правильному порядку (мережа → бази даних → веб-сервер).
- Залишатися «батьком» усіх процесів: якщо процес стає orphan, його успадковує PID 1.
- Збирати «дітей» (reap zombies): exit-коди процесів мають бути прочитаними.
- Реагувати на сигнали (SIGTERM від shutdown тощо).
- Контролювати життєвий цикл сервісів: перезапускати при падінні, зупиняти при shutdown.
1.2 Альтернативи systemd
До появи systemd (2010) стандартом був SysVinit, мінімалістичний init з 1983 року. Логіка: shell-скрипти у /etc/init.d/, які запускаються послідовно, без паралелізму, без залежностей. У 2026 році це вже екзотика, але концептуально розуміти варто.
Окрім systemd і SysVinit, є ще кілька живих альтернатив для тих, хто свідомо обирає мінімалізм: OpenRC (стандарт у Gentoo, опція у Alpine і Artix) і runit (Void Linux, ~5000 рядків коду). На практиці 95% серверів у 2026 використовують systemd. Решта 5% — це або історичні дистрибутиви (Devuan), або свідомий вибір на користь мінімалізму.
1.3 Коли systemd — не найкращий вибір
Systemd побудований навколо припущення, що у вас є повноцінний Linux-сервер з достатніми апаратними ресурсами. Це не завжди виправдано:
- Embedded і IoT. На Raspberry Pi Zero W або OpenWrt-роутерах кожен мегабайт RAM на рахунку. Systemd суммарно «з'їдає» 30-80 МБ резидентної пам'яті. На BusyBox-системах використовується busybox init (~50 КБ).
- Контейнери. Docker не запускає init взагалі: там працює одна заявлена команда як PID 1. Для повноцінного контейнера зазвичай використовується tini або dumb-init.
- Мінімальні образи. Якщо ви розгортаєте сотні мікро-VM на одному hypervisor, Alpine Linux на musl + OpenRC дає базовий образ ~5 МБ; systemd + glibc нижче 60-80 МБ не зменшити.
⚠️ Чого варто НЕ робити: викидати systemd зі звичайного сервера «бо так казали на Reddit». За 10+ років архітектура суттєво розвинулася. Для типового VPS, виділеного сервера, корпоративного Linux-середовища systemd залишається оптимальним вибором.
2. Огляд systemd
2.1 Чому systemd став стандартом
Systemd розробив Lennart Poettering у Red Hat у 2010 році. Поточний maintainer (з 2024) це Luca Boccassi з Microsoft. Чому systemd виграв ринок попри жорстку критику:
- Паралельний запуск. SysV запускав сервіси послідовно: Apache чекав на Bind, Bind на NetworkManager. На сучасному залізі це додавало 20-60 секунд до boot. Systemd використовує паралельний запуск, і boot-процес скорочується у 2-3 рази.
- Декларативні unit-файли. Замість 200-рядкового bash-скрипта тепер короткий INI-файл з чіткими секціями. Менше місця для багів.
- Єдина екосистема. Логи (journald), мережа (networkd), таймери замість cron, монтування: все під одним парасолем.
- Прийняли мейджор-дистрибутиви. Fedora 15 (2011), Arch (2012), Debian 8 і Ubuntu 15.04 (2015), RHEL 7 (2014). Коли корпоративні дистрибутиви переїхали, для решти стало зайвим опиратися.
2.2 Unit-и та їх типи
Базова одиниця в systemd, це unit: декларативний опис того, що системі треба зробити. Тип визначається розширенням файлу.
| Розширення | Тип | Для чого |
|---|---|---|
.service |
Service | Запуск і керування демоном |
.timer |
Timer | Періодичне виконання (заміна cron) |
.socket |
Socket | IPC або мережевий сокет |
.mount |
Mount | Монтування файлової системи |
.target |
Target | Група інших unit-ів (заміна runlevels) |
.path |
Path | Запуск при зміні файлу/каталогу |
На практиці 90% часу адміністратор працює з .service і .timer. Решта або автоматично генеруються, або нішеві.
2.3 Targets — заміна runlevel-ів
У SysV було поняття runlevel — режим роботи системи (3 = multi-user, 5 = graphical). У systemd замість них targets, які гнучкіші і мають імена замість номерів.
| Target | Аналог SysV | Що означає |
|---|---|---|
multi-user.target |
3 | Багатокористувацький, без GUI (стандарт для серверів) |
graphical.target |
5 | Багатокористувацький + GUI |
rescue.target |
1 | Single-user, мінімум сервісів |
emergency.target |
— | Аварійний режим (тільки root shell) |
Перевірити поточний target за замовчуванням:
# Поточний default target
systemctl get-default
# multi-user.target
3. Unit-файли
3.1 Структура файлу: [Unit], [Service], [Install]
Unit-файл має INI-формат з трьома основними секціями. Подивимось на спрощений приклад для Nginx:
# /usr/lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server and a reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
У реальних Debian/Ubuntu-пакетах nginx ви побачите складніший ExecStop з утилітою start-stop-daemon — це історичний костиль від Debian-команди для зворотної сумісності з SysVinit. У чистому systemd-стилі (як в апстрімі від nginx.org) зупинка робиться через простий kill з $MAINPID, що значно прозоріше для розуміння.
Секція [Unit]: метадані і залежності
- Description, людський опис, який показує
systemctl status. - After / Before: порядок запуску.
- Wants, м'яка залежність: «спробуй запустити це разом зі мною».
- Requires, жорстка залежність: «без цього я не запущусь».
Секція [Service]: як запускати
- Type: як systemd очікує, що сервіс «запустився»:
simple(за замовч.),forking,oneshot,notify. - ExecStart: головна команда запуску, повний шлях.
- ExecReload / ExecStop: команди reload і зупинки.
- Restart: політика перезапуску:
no,on-failure,always. - User / Group: від чийого імені запускати (важливо для безпеки).
Секція [Install]: як вмикати при boot
- WantedBy: на який target вішається при
systemctl enable(зазвичайmulti-user.target).
Один з найчастіших багів у власних unit-файлах: Type=simple на сервісі, який робить класичний fork() і виходить. systemd бачить, що головний процес «вмер», і починає його перезапускати, тоді як реальний демон спокійно крутиться у відфоркнутому дочірньому. Для таких випадків потрібен Type=forking.
А якщо ваш демон сучасний (Go, Rust, або Python з підтримкою sd_notify()), беріть Type=notify. Тоді сервіс сам каже systemd «я не тільки запустився, я вже підключився до бази, прогрів кеш і готовий приймати трафік», і залежні сервіси не стартонуть передчасно. PostgreSQL, MariaDB, sshd, Nginx (з notify-патчем) це підтримують з коробки, і у 2026 році це стандарт де-факто для будь-якого серйозного backend-сервісу.
3.2 Де знаходяться unit-файли і override
| Шлях | Призначення |
|---|---|
/etc/systemd/system/ |
Локальні (адмінські) unit-файли. Найвищий пріоритет. |
/usr/lib/systemd/system/ |
Юніти від пакетів дистрибутиву (канонічне місце на всіх сучасних дистрибутивах після UsrMerge). |
На старіших Debian/Ubuntu ви могли бачити шлях /lib/systemd/system/. У сучасних дистрибутивах (Debian 12, Ubuntu 22.04+, всі RHEL-сумісні, Arch) після завершення процесу UsrMerge /lib став symlink на /usr/lib, тому фактично юніти усюди лежать за одним канонічним шляхом.
Якщо в обох місцях лежить nginx.service, systemd візьме той з /etc/systemd/system/. Це дозволяє override пакетних unit-ів без правки файлів, які перезапишуться при оновленні пакета.
Override через drop-in каталоги
Замість копіювання всього unit-файлу, використовуйте drop-in:
sudo systemctl edit nginx.service
Команда створить /etc/systemd/system/nginx.service.d/override.conf, куди можна додати тільки те, що треба переписати:
[Service]
LimitNOFILE=65536
Environment="NGINX_WORKER_PROCESSES=auto"
Оригінальний unit-файл лишається недоторканим, override переживає оновлення пакету, і одразу видно «що саме змінили».
3.3 Створення власного unit-файлу
Реальний приклад: Go-додаток /usr/local/bin/myapi, який слухає 8080 порт. Треба запустити його як сервіс з автозапуском, обмеженням ресурсів, перезапуском при падінні.
Створюємо /etc/systemd/system/myapi.service:
[Unit]
Description=My API server (Go application)
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service
[Service]
Type=simple
User=myapi
Group=myapi
WorkingDirectory=/opt/myapi
Environment="LOG_LEVEL=info"
EnvironmentFile=/etc/myapi/env
ExecStart=/usr/local/bin/myapi --config /etc/myapi/config.yaml
Restart=on-failure
RestartSec=5s
StartLimitBurst=3
StartLimitIntervalSec=60
# Безпекові hardening-опції
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/myapi /var/lib/myapi
# Resource limits через cgroups v2
LimitNOFILE=65536
MemoryMax=512M
CPUQuota=200%
[Install]
WantedBy=multi-user.target
Розбираємо за блоками:
- Залежності. Запускаємо після мережі і PostgreSQL.
Requires=postgresql.serviceозначає, що якщо PostgreSQL не запуститься, наш сервіс теж не запуститься. - User/Group. Запускаємо НЕ від root (важливо для безпеки). Попередньо створюємо користувача:
sudo useradd -r -s /usr/sbin/nologin myapi. - Restart=on-failure з лімітами: 3 спроби за 60 секунд, інакше зупинка (без нескінченного циклу).
- Hardening.
NoNewPrivileges,PrivateTmp,ProtectSystem=strict,ProtectHomeмінімізують права.ReadWritePathsявно дозволяє писати тільки у вказані каталоги. - Resource limits. Через cgroups v2 обмежуємо пам'ять і CPU.
CPUQuota=200%= 2 повноцінні ядра.
Застосування змін
sudo systemctl daemon-reload
sudo systemctl enable --now myapi.service
--now одночасно вмикає сервіс (enable) і запускає (start).
Найбанальніша причина «правлю unit-файл, а зміни не застосовуються»: ви забули systemctl daemon-reload. Systemd підхоплює зміни тільки коли йому про це сказати. Виняток — systemctl edit, який робить daemon-reload автоматично.
4. systemctl — управління сервісами
Усе попереднє було про unit-файли, тобто декларативний опис сервісу. systemctl же це інструмент, через який ви цими сервісами керуєте. На нього припадає ~90% щоденної роботи адміна з systemd.
4.1 Основні команди
| Команда | Що робить |
|---|---|
systemctl start <unit> |
Запустити сервіс зараз |
systemctl stop <unit> |
Зупинити сервіс |
systemctl restart <unit> |
Повний рестарт (stop + start) |
systemctl reload <unit> |
М'який перечит конфігу (без зупинки процесу) |
systemctl enable --now <unit> |
Увімкнути автозапуск + запустити одразу |
systemctl disable --now <unit> |
Вимкнути автозапуск + зупинити |
systemctl mask <unit> |
Повністю заборонити запуск (symlink на /dev/null) |
systemctl daemon-reload |
Перечитати unit-файли з диска |
ℹ️ Різниця між disable і mask: disable прибирає сервіс з autostart, але його можна запустити вручну. mask повністю забороняє запуск, тож навіть systemctl start покаже помилку. Корисно, коли треба точно гарантувати, що сервіс ніколи не стартує (наприклад, masked apache2 на сервері з nginx).
4.2 Перегляд стану і списки
Робоча конячка для діагностики:
systemctl status nginx.service
Покаже: чи сервіс активний, з якого моменту, PID головного процесу, cgroup-tree з усіма підпроцесами, останні 10 рядків логу через journald. Це найкорисніший «one-shot» діагностичний звіт.
Корисні списки:
# Усі активні unit-и
systemctl list-units
# Тільки активні сервіси
systemctl list-units --type=service --state=active
# Сервіси, що впали
systemctl --failed
# Усі unit-файли (enable/disable стан)
systemctl list-unit-files --type=service
Різниця: list-units показує те, що зараз завантажене у пам'ять (фактичний стан); list-unit-files показує те, що лежить на диску як файли (декларативний стан).
5. journalctl — робота з логами
systemd-journald є централізованим логером. Кожен сервіс, запущений через systemd, автоматично пише свій stdout/stderr у journal. Тобто навіть якщо ваш додаток не пише ніяких логів самостійно, те, що він виводить у консоль, потрапляє в journald.
5.1 Базовий синтаксис
# Усі логи за весь час
journalctl
# У зворотному порядку (свіжі зверху)
journalctl -r
# Останні N рядків
journalctl -n 100
# Стрімінг (як tail -f)
journalctl -f
# Тільки конкретний unit
journalctl -u nginx.service
# Кілька unit-ів одночасно
journalctl -u nginx.service -u php8.4-fpm.service
ℹ️ Приклад з PHP-FPM: якщо у вас сайт на PHP і виникають помилки 502 Bad Gateway, починайте з journalctl -u php8.4-fpm -u nginx --since "10 min ago". Це покаже логи обох сервісів поряд з єдиним timeline, одразу видно, чи PHP-FPM падав, чи Nginx не міг до нього достукатися. Про тонке налаштування самого PHP-FPM (pool tuning, OPcache, JIT) — у нашій статті про оптимізацію PHP-сервера.
5.2 Фільтрація
# За часом
journalctl --since "14:00"
journalctl --since "1 hour ago"
journalctl --since "2026-06-15 09:00" --until "2026-06-15 10:00"
journalctl --since today
journalctl --since yesterday
# За пріоритетом (syslog-рівні)
# Показує цей рівень і вище
journalctl -p err # err, crit, alert, emerg
journalctl -p warning # warning і вище
# Тільки kernel-повідомлення (як dmesg)
journalctl -k
# Усе, що сталося в поточному boot
journalctl -b
# Усе з попереднього boot (-1 = попередній)
journalctl -b -1
# Список усіх boot-ів
journalctl --list-boots
5.3 Управління журналом
На сучасних дистрибутивах (Ubuntu 18.04+, Debian 12+, RHEL 8+) логи персистентні: лежать у /var/log/journal/ і переживають reboot. На старіших можуть бути volatile (в RAM, чистяться при reboot).
Перевірити поточний розмір логу:
journalctl --disk-usage
# Archived and active journals take up 384.0M in the file system.
Почистити старі логи:
sudo journalctl --vacuum-time=7d # видалити старіші 7 днів
sudo journalctl --vacuum-size=500M # залишити макс. 500 МБ
На практиці зв'язка journalctl -u <unit> -f --since "10 min ago" закриває більшість задач з діагностики: показує контекст за останні 10 хвилин і одразу стрімить нові події. Якщо тримати це у пам'яті як «команду за замовчуванням», більшість запитань до сервісу отримують відповідь одразу, без копання у мануалах.
6. systemd-analyze — діагностика boot
systemd-analyze дозволяє побачити, що саме і скільки часу займало під час завантаження. Без нього оптимізувати boot це гадання на кавовій гущі: ви можете прискорити сервіс, який і так не блокував старт, а реального винуватця залишити без уваги.
6.1 Загальний час завантаження
systemd-analyze time
Приклад виводу:
Startup finished in 4.231s (kernel) + 12.456s (userspace) = 16.687s
multi-user.target reached after 12.234s in userspace.
- kernel: час від BIOS до запуску PID 1.
- userspace: час від PID 1 до досягнення default target. Це те, що ми можемо оптимізувати.
6.2 blame: хто гальмує boot
systemd-analyze blame
Виводить список unit-ів, відсортованих за часом їх запуску:
8.234s plymouth-quit-wait.service
3.456s NetworkManager-wait-online.service
2.123s docker.service
1.892s snapd.service
876ms postgresql@16-main.service
Це не час, який сервіс впливав на boot, а абсолютний час його старту. Деякі сервіси запускаються паралельно і не блокують boot. Для точнішої картини є critical-chain.
6.3 critical-chain: реальне блокування
systemd-analyze critical-chain
Показує критичний ланцюг залежностей: той ланцюг сервісів, який реально визначає, коли boot завершиться:
multi-user.target @12.234s
└─docker.service @9.876s +2.123s
└─network-online.target @9.834s
└─NetworkManager-wait-online.service @6.378s +3.456s
└─NetworkManager.service @5.234s
Тут видно: docker чекає на network-online, який чекає на NetworkManager-wait-online (3.4 секунди!). Якщо хочемо прискорити boot, починаємо з NetworkManager-wait-online.
6.4 verify: перевірка unit-файлів
systemd-analyze verify /etc/systemd/system/myapi.service
Швидкий лінтер для unit-файлів. Покаже помилки синтаксису, missing dependencies, deprecated опції. Корисно перед systemctl daemon-reload. Якщо все добре, команда не виведе нічого.
6.5 dot: візуалізація залежностей
Команда systemd-analyze dot генерує опис графа залежностей у форматі Graphviz DOT, який потім можна перетворити на SVG через утиліту dot (пакет graphviz). Корисно, коли треба наочно побачити, що від чого залежить:
systemd-analyze dot nginx.service | dot -Tsvg > nginx-deps.svg
Установка graphviz: sudo apt install graphviz на Debian/Ubuntu, sudo dnf install graphviz на Rocky/Alma. Результат — направлений граф, де видно Requires, After, Wants зв'язки між сервісами. Особливо допомагає, коли ви успадкували незнайому інсталяцію і треба зрозуміти, як саме переплетені кастомні сервіси.
7. Інші утиліти systemd-екосистеми
systemd, це не тільки systemctl. У систему входять окремі утиліти, які заміняють старі окремі програми. Найкорисніші у щоденній роботі:
hostnamectl
hostnamectl # поточний стан
sudo hostnamectl set-hostname web01.example.com
Замінює правку /etc/hostname, але робить це коректно, з оновленням усіх місць де ім'я зберігається.
timedatectl
timedatectl # поточний стан
sudo timedatectl set-timezone Europe/Kyiv
sudo timedatectl set-ntp true # увімкнути NTP-синхронізацію
Керує часом і часовою зоною системи та налаштуванням NTP. Тонкі параметри синхронізації (NTP-сервери, інтервали) задаються у /etc/systemd/timesyncd.conf.
loginctl
loginctl # список активних сесій
loginctl session-status 5 # деталі сесії
sudo loginctl kill-user 1000 # завершити сесію користувача
Решта утиліт (localectl, networkctl, resolvectl, machinectl) є у man systemd. Якщо вони потрібні у вашому конкретному сценарії, ви про них дізнаєтесь з контексту.
8. Підсумок
Systemctl, journalctl і systemd-analyze, це той мінімальний набір, який закриває переважну більшість щоденних задач системного адміністратора у 2026 році. На цих трьох утилітах тримається все: від запуску і перезапуску сервісів до діагностики, чому щось не працює, і оптимізації boot-процесу.
Що варто винести з цієї статті у щоденну практику:
- Drop-in каталоги замість копіювання unit-файлів.
systemctl edit nginxпереживе оновлення пакета; копія unit-файлу у/etc/systemd/system/ні. - Правильний
Typeз першого разу. Знаючи різницю міжsimple,forkingіnotify, ви напишете робочий unit-файл за п'ять хвилин замість трьох годин гадання, чому сервіс рестартується. - journalctl з фільтрами.
-u,-p,--since,-f: чотири прапори, які закривають більшість сценаріїв з діагностики. Особливо у поєднанні з конкретним unit-ом. - systemd-analyze blame і critical-chain. Перед тим як купувати швидший SSD «бо сервер довго завантажується», подивіться що саме його гальмує. Часто це NetworkManager-wait-online або щось подібне, що можна вимкнути.
- Hardening у власних unit-файлах.
NoNewPrivileges,PrivateTmp,ProtectSystem,User=без root: базова гігієна, яка коштує п'яти хвилин і запобігає більшості сценаріїв компрометації. - Resource limits через cgroups v2.
MemoryMax,CPUQuota,TasksMaxу unit-файлі: одиничний процес не з'їсть всю RAM сервера, навіть якщо у ньому витік пам'яті.
Решта тонкощів (user-level systemd, socket activation, systemd-nspawn, systemd-homed) це окремі великі теми, які стануть актуальними коли ви впораєтесь з базою. До них варто повертатися саме тоді, коли з'явиться конкретна задача, а не «про всяк випадок» — інакше витратите час на вивчення того, чим у роботі ніколи не скористаєтесь.
🚀 Linux-сервери з повним root-доступом від Hostiserver
Усе, описане у цій статті, це робота на «вашому» Linux-сервері з повним контролем над systemd, unit-файлами, ресурсами. Hostiserver надає саме такі сервери: KVM-ізольований VPS з root-доступом або повний bare-metal dedicated.
💻 Cloud (VPS) Хостинг
- Від $19.95/міс, KVM-ізоляція, виділені vCPU і RAM
- Ubuntu 24.04 / Debian 12 / Rocky Linux 9 з коробки, оновлені systemd
- Повний root: пишіть власні unit-файли, налаштовуйте journald, cgroups
- API доступ для автоматизації, сумісність з Terraform і Ansible
- 24/7 DevOps-підтримка: інженери допоможуть розібратися із systemd-проблемами
🖥️ Виділені Сервери
- Від $90/міс, фізичний сервер з повним hardware-контролем
- Будь-який дистрибутив при встановленні: Ubuntu, Debian, RHEL-сумісні, Arch
- Безкоштовна міграція з допомогою інженерів
- SLA 99.9% uptime з гарантією у договорі
💬 Не впевнені, який варіант вам необхідний?
💬 Напишіть нам і ми зі всім допоможемо!
Часті питання
- Чому мій сервіс показує "active (running)", але насправді не працює?
Типова причина:
Type=simpleна сервісі, який сам робить fork(). systemd бачить, що головний процес «викликав ExecStart», і одразу вважає його активним. Але потім головний процес fork-нув дочірній і вийшов. Перевірте поведінку сервісу: якщо він «виходить» одразу після старту, але має запустити дочірній, цеType=forking. Якщо це сучасний сервіс з sd_notify підтримкою, берітьType=notify. Ще варіант: реальний процес впав, але PID-файл застряг. Перевірте:systemctl statusпокаже Main PID, звіртеся зps aux | grep <pid>.
- Як зробити, щоб сервіс перезапускався при будь-якому падінні?
У секції [Service] додайте
Restart=alwaysіRestartSec=5s(пауза перед перезапуском). Але завжди ставте обмеження кількості спроб:StartLimitBurst=5іStartLimitIntervalSec=60(5 спроб за 60 секунд, далі systemd зупинить сервіс. Без цього криво налаштований сервіс буде нескінченно крутитися, з'їдаючи логи і CPU. Якщо хочете дізнатися причину перезапуску, дивітьсяjournalctl -u <unit>навколо моменту падіння.
- Як знайти, який unit-файл насправді завантажений systemd?
Команда
systemctl cat <unit>покаже точно той файл, який systemd використовує, разом з усіма drop-in override-ами. Це найшвидший спосіб переконатися, що ваш override з/etc/systemd/system/<unit>.d/override.confсправді застосувався. Ще корисна команда:systemctl show <unit>, яка покаже всі реальні значення параметрів так, як їх «бачить» systemd після парсингу всіх файлів.
- Що робити, якщо сервіс показує "failed" при boot, але повторний запуск працює?
Найімовірніше, проблема залежностей при boot. Сервіс залежить від чогось, що ще не готове (база даних, мережа, mount), і запускається занадто рано. Перший крок:
journalctl -u <unit> -bпокаже логи саме того невдалого запуску. Другий: додати правильніAfter=у [Unit] секцію. Для мережі це частоAfter=network-online.target+Wants=network-online.target(саме обидва:Afterзадає порядок,Wantsзмушує network-online реально завантажитись).
- Як обмежити пам'ять для одного сервісу?
Через cgroups v2, які systemd використовує з коробки. У секції [Service] додайте
MemoryMax=512M(жорсткий ліміт, kill при перевищенні) абоMemoryHigh=400M(м'який, гальмування). Те ж для CPU:CPUQuota=50%обмежить процес половиною одного ядра,CPUQuota=200%дасть два повних ядра. Перевірити поточне використання:systemctl status <unit>покаже Memory і CPU rows. Для аналітики єsystemd-cgtop, який показує top по cgroups.
- Чи безпечно вимкнути systemd-resolved?
Залежить від дистрибутиву. На Ubuntu 18.04+ і Debian 12+ resolved інтегрований через
/etc/resolv.conf, що є symlink на/run/systemd/resolve/stub-resolv.conf(там прописано локальний stubnameserver 127.0.0.53). Вимкнення без альтернативи зламає DNS. Якщо хочете звичайний/etc/resolv.confз DNS-серверами вручну: 1) вимкніть resolved (systemctl disable --now systemd-resolved); 2) видаліть symlink (sudo rm /etc/resolv.conf); 3) створіть звичайний файл зnameserverрядками (наприклад,nameserver 1.1.1.1). На RHEL/Rocky resolved за замовчуванням не використовується, там працює NetworkManager з DNS-плагіном, тому вимкнення resolved нічого не зламає.
- Чи можна перевірити безпеку власного unit-файлу автоматично?
Так, командою
systemd-analyze security <unit>. Вона показує скор від 0.0 (бронебійно захищено) до 10.0 (UNSAFE) і пояснює, які саме hardening-опції не вистачає:NoNewPrivileges,ProtectSystem,PrivateTmp,ProtectHomeтощо. Корисно запустити для всіх своїх unit-файлів, отримаєте пріоритезований список того, що варто покращити з мінімумом зусиль.