systemd: что это, как работает и как управлять сервисами в Linux
systemd — система инициализации и менеджер служб Linux: он запускается ядром первым процессом (PID 1), поднимает остальные службы в нужном порядке и следит за ними. Всем, что делает systemd, управляют через юниты — текстовые описания сервисов, таймеров, точек монтирования; командой systemctl их запускают, останавливают и добавляют в автозагрузку, а journalctl показывает их логи.
systemd — это система инициализации и менеджер служб, который используется в большинстве современных дистрибутивов Linux: Debian, Ubuntu, Fedora, RHEL и их производных. Ядро после загрузки запускает systemd первым процессом с PID 1, а дальше уже он поднимает сеть, монтирует диски, запускает веб-сервер, базу данных и всё остальное. Если коротко отвечать на вопрос «systemd что это», то это «диспетчер», который знает, какие службы должны работать, в каком порядке их стартовать и что делать, если служба упала.
Проверить, что у вас именно systemd, просто:
$ ps -p 1 -o comm=
systemd
Зачем понадобился systemd
Раньше в Linux использовалась SysV init: набор shell-скриптов в /etc/init.d/, которые запускались по очереди. Схема была понятной, но медленной и хрупкой. Каждый скрипт сам писал PID-файл, сам решал, как проверить, жив ли процесс, а перезапуск упавшей службы приходилось прикручивать отдельно.
systemd решает эти задачи централизованно:
- Параллельный запуск. Службы стартуют одновременно, если между ними нет зависимостей, поэтому загрузка быстрее.
- Зависимости и порядок. В описании службы явно указано, что ей нужно (например, сеть) и после чего её запускать.
- Надзор. systemd знает все процессы службы через cgroups и может перезапустить её при сбое.
- Единый журнал. Вывод всех служб собирает journald, логи смотрят одной командой.
- Единый интерфейс. Любая служба управляется одинаково:
systemctl start|stop|restart|status.
Кроме менеджера служб, в проект systemd входит набор компонентов: journald (журнал), logind (сессии пользователей), timesyncd (синхронизация времени), resolved (DNS), networkd (сеть). Не все дистрибутивы используют их все, но systemd как PID 1 и journald есть почти везде.
Юниты: из чего состоит systemd
Всё, чем управляет systemd, описывается юнитами (units). Юнит — это текстовый файл в формате INI, тип юнита определяется расширением.
| Тип | Расширение | Что описывает |
|---|---|---|
| service | .service | Службу — процесс-демон или разовую задачу |
| timer | .timer | Запуск другого юнита по расписанию (замена cron) |
| socket | .socket | Сокет, при обращении к которому запускается служба |
| target | .target | Группу юнитов, «состояние системы» (например, multi-user.target) |
| mount | .mount | Точку монтирования |
| path | .path | Слежение за файлом или каталогом |
Где лежат unit-файлы
Файлы юнитов хранятся в нескольких каталогах, и у них есть приоритет:
/usr/lib/systemd/system/(в Debian и Ubuntu также/lib/systemd/system/) — юниты, установленные пакетами. Руками их не правят: обновление пакета перезапишет изменения./etc/systemd/system/— юниты и переопределения администратора. У них наивысший приоритет./run/systemd/system/— временные юниты, созданные во время работы.
Чтобы посмотреть итоговое содержимое юнита со всеми переопределениями, используйте systemctl cat nginx.service.
Targets вместо уровней запуска
Старые runlevel заменены целями (targets). multi-user.target — обычный серверный режим без графики, graphical.target — с графической оболочкой, rescue.target — однопользовательский режим восстановления. Текущая цель по умолчанию показывается командой systemctl get-default, меняется через systemctl set-default multi-user.target.
systemctl: управление службами
systemctl — основной инструмент для работы с systemd. Большинство команд меняют состояние системы и требуют sudo.
| Команда | Что делает |
|---|---|
systemctl status nginx | Состояние службы, PID, память, последние строки лога |
systemctl start nginx | Запустить сейчас |
systemctl stop nginx | Остановить |
systemctl restart nginx | Перезапустить (stop + start) |
systemctl reload nginx | Перечитать конфигурацию без остановки (если служба умеет) |
systemctl enable nginx | Добавить в автозапуск |
systemctl disable nginx | Убрать из автозапуска |
systemctl enable --now nginx | Включить автозапуск и сразу запустить |
systemctl is-active nginx | Вывести active/inactive — удобно в скриптах |
systemctl list-units --type=service | Загруженные службы |
systemctl --failed | Упавшие юниты |
systemctl daemon-reload | Перечитать unit-файлы после правки |
Как читать systemctl status
$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-10-12 09:14:03 UTC; 2h 5min ago
Docs: man:nginx(8)
Main PID: 812 (nginx)
Tasks: 3 (limit: 2307)
Memory: 6.1M
CPU: 154ms
CGroup: /system.slice/nginx.service
├─812 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
├─813 "nginx: worker process"
└─814 "nginx: worker process"
Строка Loaded говорит, откуда взят unit-файл и включён ли автозапуск (enabled). Строка Active — текущее состояние: active (running), inactive (dead) или failed. В блоке CGroup видны все процессы службы — именно так systemd отслеживает, что ей принадлежит.
Чем enable отличается от start
Это частая путаница. start запускает службу прямо сейчас, но после перезагрузки она не поднимется. enable создаёт символическую ссылку в каталоге цели (например, /etc/systemd/system/multi-user.target.wants/), и служба стартует при загрузке, но сейчас она не запускается. Нужно и то и другое — используйте enable --now.
Есть и третье состояние — mask. systemctl mask service связывает юнит с /dev/null, и его нельзя запустить ни вручную, ни как зависимость. Пригодится, когда службу нужно гарантированно выключить.
journalctl: логи служб
Всё, что служба пишет в stdout и stderr, перехватывает systemd-journald и сохраняет в бинарный журнал вместе с метаданными: имя юнита, PID, приоритет, время. Читают журнал командой journalctl.
journalctl -u nginx # логи одной службы
journalctl -u nginx -f # следить в реальном времени, как tail -f
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -n 50 # последние 50 строк
journalctl -b # с момента текущей загрузки
journalctl -b -1 # предыдущая загрузка
journalctl -p err -b # только ошибки и серьёзнее
journalctl -k # сообщения ядра
journalctl --disk-usage # сколько места занимает журнал
Флаг -p фильтрует по приоритету syslog: emerg, alert, crit, err, warning, notice, info, debug. Указанный уровень включает всё, что серьёзнее него.
Журнал после перезагрузки
Если каталог /var/log/journal не существует, а в /etc/systemd/journald.conf стоит Storage=auto, журнал хранится только в памяти (/run/log/journal) и пропадает при перезагрузке. Чтобы сделать его постоянным, задайте Storage=persistent или создайте каталог и перезапустите journald. Размер ограничивает параметр SystemMaxUse=, а почистить старое можно командой journalctl --vacuum-time=2weeks или --vacuum-size=500M.
journald часто работает в паре с rsyslog: журнал передаёт сообщения в rsyslog, а тот пишет классические текстовые файлы в /var/log/ и умеет отправлять логи на центральный сервер.
Автозапуск своего сервиса: пример unit-файла
Допустим, у вас есть приложение — скрипт или бинарник, которое нужно держать запущенным, поднимать при загрузке и перезапускать при падении. Создайте файл /etc/systemd/system/myapp.service:
[Unit]
Description=My web application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
EnvironmentFile=/etc/myapp/env
ExecStart=/opt/myapp/bin/server --port 8080
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Разберём секции:
- [Unit] — описание и зависимости.
After=задаёт только порядок,Wants=— мягкую зависимость (подтянуть юнит, но не падать, если он не поднялся). Жёсткая зависимость —Requires=. - [Service] — как запускать.
Type=simpleозначает, что процесс изExecStartи есть служба и он не уходит в фон.User=запускает от непривилегированного пользователя.Restart=on-failureперезапускает службу, если она завершилась с ошибкой, черезRestartSecсекунд. - [Install] — что делает
enable.WantedBy=multi-user.targetозначает «запускать при обычной загрузке».
Применяем:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp
journalctl -u myapp -f
Частые ошибки в unit-файлах
- Относительный путь в ExecStart. Путь к программе должен быть абсолютным. systemd не ищет команды в
PATHпользователя так, как это делает оболочка. - Забыли daemon-reload. После правки файла systemd продолжает использовать старую версию и предупреждает об этом в
status. - Демон уходит в фон. Если программа сама форкается, а указан
Type=simple, systemd решит, что служба завершилась. Либо запускайте программу в режиме foreground, либо используйтеType=forkingсPIDFile=. - Переменные окружения из профиля. Служба не видит
~/.bashrcи/etc/profile. Переменные задаются черезEnvironment=илиEnvironmentFile=.
Переопределение без правки пакетного юнита
Чтобы изменить параметры службы из пакета, не трогая её файл, используйте drop-in:
sudo systemctl edit nginx
Откроется редактор, и изменения сохранятся в /etc/systemd/system/nginx.service.d/override.conf. Например, туда можно дописать [Service] и Restart=always. После выхода из редактора systemd сам перечитает конфигурацию.
Таймеры systemd вместо cron
Таймер — это юнит, который запускает одноимённый сервис по расписанию. Плюсы перед cron: логи задачи в журнале, зависимости, пропущенные запуски можно догнать (Persistent=true). Пример — ежедневный бэкап:
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers
Проверить выражение OnCalendar можно командой systemd-analyze calendar "*-*-* 03:00:00" — она покажет, когда случится следующий запуск.
Диагностика загрузки
systemd хранит время старта каждого юнита, поэтому медленную загрузку легко разобрать:
systemd-analyze # общее время загрузки
systemd-analyze blame # юниты, отсортированные по времени запуска
systemd-analyze critical-chain # цепочка, которая задержала загрузку
systemd-analyze verify /etc/systemd/system/myapp.service # проверка unit-файла
Итог
systemd — это PID 1 и менеджер служб в современном Linux. Он описывает всё юнитами, управляется через systemctl, собирает логи в журнал, который читается journalctl, а вместо cron может запускать задачи таймерами. Чтобы уверенно им пользоваться, достаточно освоить status, enable --now, journalctl -u и уметь написать простой unit-файл с Restart=on-failure. На практике systemd, journald и логирование разобраны в курсе по Linux.
Частые вопросы
Как узнать, используется ли systemd в моей системе?
Выполните ps -p 1 -o comm= — если вывод systemd, система работает под systemd. Также есть каталог /run/systemd/system, который существует только при загрузке через systemd.
В чём разница между systemctl restart и reload?
restart полностью останавливает и снова запускает службу, соединения при этом обрываются. reload просит службу перечитать конфигурацию без остановки, но работает только если в юните задан ExecReload.
Можно ли запускать сервисы systemd от обычного пользователя без sudo?
Да, у systemd есть пользовательский экземпляр: юниты кладут в ~/.config/systemd/user/ и управляют ими через systemctl --user. Чтобы они работали без активной сессии, нужно включить loginctl enable-linger для пользователя.
Почему служба в статусе failed и как сбросить это состояние?
Причину ищите в journalctl -u имя -b и в строке Active команды status. После исправления запустите службу снова, а метку failed без перезапуска сбрасывает systemctl reset-failed.
Где хранятся логи systemd на диске?
При постоянном хранении — в /var/log/journal/ в бинарном формате, иначе в /run/log/journal/ в памяти. Читать их нужно через journalctl, а не текстовыми утилитами.
Эта тема подробно разобрана с практикой в курсе «Linux: с нуля до уверенного администрирования».
- systemd: как на самом деле запускаются сервисы в современном Linux
- Журналы и мониторинг: journald, rsyslog и sysstat