systemd

17 августа 2026 · ~15 мин чтения

инструмент linux devops init-система sre

systemd

systemd — это первый процесс, который запускается при загрузке большинства современных Linux-систем (у него PID 1), и одновременно набор инструментов, которые следят за всеми остальными процессами: стартуют их, перезапускают после падений, ведут журнал, планируют задачи по времени.

История

Что это такое

systemd — одновременно и программа, и экосистема программ. Программа — это бинарник /lib/systemd/systemd, который ядро (kernel — сердцевина операционной системы) запускает сразу после загрузки как процесс с PID 1. Всё остальное в системе — либо его потомок, либо будет к нему подключено через сокет.

Вокруг PID 1 живёт семья утилит с общим префиксом systemd-: systemd-journald (журнал сообщений), systemd-logind (сессии пользователей), systemd-networkd (сеть), systemd-resolved (DNS), systemd-timesyncd (NTP-часы), systemd-udevd (управление устройствами) и ещё десяток. Не обязательно использовать все — многие дистрибутивы оставляют только init-часть, а сеть и DNS отдают привычным NetworkManager и systemd-resolved. Но идея одна: у всех этих кусочков общий язык (unit-файлы), общий журнал (journald), общая CLI-точка (systemctl, journalctl).

Ключевая механика — декларативные unit-файлы. Ты не пишешь «bash-скрипт запуска nginx»; ты пишешь текстовый файл nginx.service из трёх секций ([Unit], [Service], [Install]), где описано, что запустить, от кого, что делать при падении, от чего зависеть. systemd читает файл и берёт на себя всю рутину: запуск в правильном порядке, слежение за живучестью, отправку логов в journal, изоляцию через cgroups (control groups — механизм ядра для ограничения ресурсов).

Явные пары «X vs Y».

Аналогии из жизни

1. Диспетчер большого аэропорта.
Диспетчер решает, какой самолёт садится первым, кто ждёт на рулёжке, кому дать топливо. Он не летает сам, но без него всё рассыпается — самолёты полезут друг на друга. systemd — такой диспетчер для сервисов: он говорит nginx «взлетай после того, как поднялся network.target», postgres — «сначала смонтируется диск, потом стартуешь», а cron-задачам — «летите в 3 часа ночи, когда трафик низкий».

Где ломается: у настоящего диспетчера один горизонт — небо над аэропортом. Он не рулит расписанием стюардесс, не отвечает за багаж, не готовит еду в самолёте. systemd — рулит всем: и запуском сервиса, и логами, и таймерами, и монтированием, и сессиями пользователей. Как раз это — главный упрёк критиков: слишком много в одних руках.

2. Умный дом с центральным контроллером.
Есть отдельные лампы, чайник, кондиционер, робот-пылесос. Каждый — своя коробка, своя прошивка. Умный дом с центральным контроллером — не устройства, а сценарии: «утром в 7:00 включи свет, свари кофе, если проснулся раньше — не будь». Контроллер сам решает порядок: свет — сразу, кофе — если человек встал. systemd — центральный контроллер сервера: unit-файл — это сценарий «после того как поднялась сеть — стартуй nginx; если nginx упал — подними за 5 секунд; каждый день в 3 ночи — прогони таймер бэкапа».

Где ломается: умный дом ломается по-своему. Если контроллер завис — ты не можешь просто дёрнуть выключатель, всё завязано на прошивку. Systemd — тоже: если systemd-юнит криво написан, обычный nginx -s reload может не сработать, потому что systemd считает сервис «в процессе рестарта» и блокирует команду. Приходится учить второй язык поверх привычного.

3. Симфонический оркестр с дирижёром vs камерный ансамбль по слуху.
SysV init — джаз-ансамбль: три-четыре музыканта, договорились «начинаем с барабана», играют по слуху, если один сфальшивил — остальные подстроились. Работает, пока играющих мало. systemd — симфонический оркестр: 60 музыкантов, партитура, дирижёр. Никакого «по слуху» — только по нотам, но зато можно играть Малера, а не только «В лесу родилась ёлочка».

Где ломается: дирижёр — единая точка отказа. Если у него сердце схватило посреди концерта — весь оркестр стоит. PID 1 в Linux — тоже единая точка: если systemd упадёт, вся машина превращается в тыкву. К счастью, systemd падает крайне редко, а разработчики фанатично следят за стабильностью именно этой части.

Как это работает

Общая схема запуска Linux-машины с systemd выглядит так:

BIOS/UEFI  →  Загрузчик (GRUB)  →  Ядро Linux  →  initramfs  →  systemd (PID 1)
                                                                       │
                                                                       ├─→ default.target
                                                                       │      │
                                                                       │      ├─→ multi-user.target
                                                                       │      │      ├─→ network.target
                                                                       │      │      │     └─→ nginx.service
                                                                       │      │      ├─→ ssh.service
                                                                       │      │      └─→ cron.service
                                                                       │      └─→ graphical.target (если десктоп)
                                                                       │
                                                                       └─→ journald + logind + udevd + ...

Шаг за шагом.

  1. Ядро запускается и вызывает /sbin/init — а это симлинк на /lib/systemd/systemd. Всё, systemd теперь — PID 1.
  2. systemd читает default.target — «цель по умолчанию». Обычно это multi-user.target (сервер без графики) или graphical.target (десктоп). Target (цель) — это unit-файл, который сам ничего не запускает, а только группирует зависимости: «чтобы достичь цели multi-user, надо поднять network.target, ssh.service, cron.service…».
  3. systemd строит dependency graph (граф зависимостей) — направленный ациклический граф всех юнитов, которые нужно стартовать. Смотрит поля Requires=, After=, Before=, Wants= и раскладывает: «сначала — сеть, потом — nginx; параллельно с nginx — cron, они не зависят друг от друга».
  4. Стартует юниты параллельно там, где это возможно. Здесь и живёт главное ускорение по сравнению с SysV: пять сервисов, не зависящих друг от друга, поднимаются одновременно. Если nginx ждёт network.target, systemd не тормозит cron — тот стартует в это же время.
  5. Ленивая активация по сокету (socket activation). Для «редких» демонов systemd открывает сокет вместо самого демона. Пример: cups (демон печати). Пока никто не печатает — cups не запущен. Кто-то отправил задачу на печать — systemd видит соединение на сокете, тут же поднимает cups и передаёт ему уже открытое соединение. Экономия памяти и времени загрузки.
  6. cgroups для изоляции. Каждый service — это отдельная cgroup ядра. systemd видит все процессы юнита (даже если они форкнулись), может задать лимит на CPU и память (CPUQuota=50%, MemoryMax=512M), и при остановке юнита прибивает всё дерево — не бывает «зависших сирот».
  7. journald собирает логи. Всё, что сервис пишет в stdout/stderr, автоматически летит в journal — бинарный индексированный лог. Смотреть через journalctl -u nginx.service -f. Не нужно искать, где какой демон складывает логи: /var/log/nginx/error.log, /var/log/syslog, ~/.local/logs/... — journald поглощает всё.

Как выглядит минимальный unit-файл. Файл /etc/systemd/system/mybot.service:

[Unit]
Description=Мой telegram-бот
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mybot
Restart=on-failure
RestartSec=5
User=mybot

[Install]
WantedBy=multi-user.target

Разбор:
- [Unit] — метаданные: описание, зависимости. After=network.target — «запускай меня после того, как поднялась сеть».
- [Service] — что и как запускать. Type=simple — «программа не форкается, она сама и есть демон». Restart=on-failure — «если упадёт с ненулевым кодом — перезапусти». RestartSec=5 — «подожди 5 секунд перед рестартом».
- [Install] — как включать. WantedBy=multi-user.target — «когда я включён (systemctl enable), меня надо запускать в цели multi-user, то есть при обычной загрузке».

Ключевые команды systemctl.

Помимо .service бывают юниты других типов: .timer (аналог cron-задачи), .socket (сокет для ленивой активации), .mount (монтирование файловой системы), .path (реагировать на появление файла), .target (группа зависимостей). Все — один синтаксис, один язык, одна CLI.

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Кто пользуется

Альтернативы и конкуренты

1. SysV init.
- Плюсы: минимализм, понятность, унаследованность, живёт везде без сюрпризов.
- Минусы: последовательный запуск (медленно), нет слежения за упавшими сервисами, скрипты на bash — отладка боль, каждый дистрибутив писал свои паттерны.

2. OpenRC (Gentoo, Alpine).
- Плюсы: лёгкий, не претендует быть init'ом (может работать поверх любого PID 1), простой формат.
- Минусы: нет параллельной активации по сокету, нет cgroups «из коробки», сообщество меньше, инструментов меньше.

3. runit (Void Linux, некоторые Docker-минибазы).
- Плюсы: очень маленький, философия KISS (keep it simple, stupid — держи проще), быстрый.
- Минусы: скудная документация, скудные возможности (только сервисы, ни таймеров, ни сокетов).

4. launchd (macOS).
- Плюсы: идейно чист, отлично интегрирован с Apple-миром.
- Минусы: только macOS/iOS, XML plist — многословно.

5. supervisord (Python).
- Плюсы: работает поверх любого init (не претендует на PID 1), простая конфигурация, кроссплатформенно.
- Минусы: не заменяет init — это надстройка, не умеет socket activation, не так глубоко интегрирован с системой.

Когда НЕ стоит использовать

Связанные понятия

Литература и источники

Где встретилось у меня

Вчера чинил VPS: бот автопрозвона перестал стартовать, оказалось — переполнился диск. Диагностика вся шла через systemd: systemctl list-units --failed показал, кто упал, journalctl -u ... -n 200 — почему, systemctl restart — поднял обратно. Заодно проверил oneshot-таймеры парсеров и always-on сервисы. Без systemd пришлось бы лезть в пять разных мест.

Краткое резюме