systemd
systemd
systemd — это первый процесс, который запускается при загрузке большинства современных Linux-систем (у него PID 1), и одновременно набор инструментов, которые следят за всеми остальными процессами: стартуют их, перезапускают после падений, ведут журнал, планируют задачи по времени.
История
- 2010, апрель, Германия. Леннарт Поттеринг (Lennart Poettering) и Кай Сиверс (Kay Sievers) в компании Red Hat. 30 апреля 2010 года Поттеринг опубликовал в своём блоге эссе «Rethinking PID 1» — «переосмысление первого процесса». Он предложил заменить старую систему инициализации Linux — SysV init — на новую, вдохновлённую макосным launchd и подходом Apple к параллельному запуску демонов (фоновых служб). В тот же день на GitHub появился первый публичный код systemd.
- Какую проблему решали. До systemd Linux загружался последовательно и медленно. SysV init выполнял скрипты из
/etc/rc.d/один за другим: сеть, потом syslog, потом cron, потом ssh — каждый ждал, пока прогреется предыдущий. Скрипты писались на bash, у каждого дистрибутива был свой стиль, отладка сводилась к разбору длинных цепочекif [ -e /var/run/... ]. Параллельно с SysV init жил Upstart от Canonical (Ubuntu, 2006) — он умел события, но не решил проблему единого языка для описания служб. Поттеринг предложил радикальнее: сделать декларативные unit-файлы (единицы управления), запускать демоны параллельно и лениво (по обращению к сокету), собрать в одном инструменте init + cron + syslog + logind + монтирование. - 2011: Fedora 15 становится первым большим дистрибутивом, где systemd — по умолчанию. Это тестовый полигон Red Hat: если что-то ломается — ломается у энтузиастов, до RHEL можно докрутить.
- 2012, октябрь: openSUSE 12.2 переходит на systemd. В том же году Arch Linux, Mageia — по цепочке.
- 2014, февраль: Debian. Технический комитет Debian после нескольких месяцев жёстких дебатов (голосование прошло 8 против 4) выбирает systemd как init по умолчанию для Debian 8 Jessie. Это исторический момент: Debian всегда был знаменем консерватизма, и его выбор фактически закрыл вопрос для большинства производных, включая Ubuntu.
- 2014, апрель: Ubuntu. Марк Шаттлворт (основатель Canonical) объявляет о переходе с Upstart на systemd. Ubuntu 15.04 Vivid Vervet — первый релиз по умолчанию на systemd.
- 2014–2015: анти-systemd движение. Часть комьюнити резко против: слишком много функций в одном процессе, PID 1 «жиреет», нарушает Unix-философию «делай одно и делай хорошо». Появляются форки: Devuan (Debian без systemd), Void Linux, Artix (Arch без systemd). Они живы до сих пор, но остаются нишевыми.
- 2015, RHEL 7 и SLES 12 — большие энтерпрайз-дистрибутивы на systemd. С этого момента systemd — стандарт де-факто.
- Сейчас. systemd — PID 1 в Fedora, RHEL и всех клонах (CentOS Stream, Rocky, AlmaLinux), Debian, Ubuntu, openSUSE/SLES, Arch. Домашняя страница — freedesktop.org. Основной репозиторий — GitHub,
systemd/systemd. Актуальная версия на момент написания — из серии v256+ (релизы примерно раз в полгода). Формальный владелец — сообщество, коммерческая поддержка — Red Hat (IBM).
Что это такое
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».
- systemd vs SysV init. SysV init — bash-скрипты, последовательный запуск, никакого слежения за упавшими процессами. systemd — декларативные unit-файлы, параллельный запуск, автоматический рестарт. Разница по скорости загрузки — с 40–60 секунд до 5–15 на типовом сервере.
- systemd vs Upstart. Upstart (Canonical, 2006) — тоже event-driven, но конфиг многословный, а сама архитектура не покрыла cron, journal, монтирование. systemd — покрыл. Upstart официально мёртв с 2014, репозиторий заархивирован.
- systemd vs launchd. launchd (Apple, 2005, macOS/iOS) — идейный старший брат systemd. Оба про декларативность, оба про PID 1. systemd богаче: cgroups, journal, socket/timer/path/device/mount-юниты как единый механизм. launchd — только Apple-мир, XML plist вместо ini-подобного формата.
- systemd vs Docker/containerd. Категорически разные вещи, хотя часто путают. Docker — про контейнеризацию (изоляция приложения), systemd — про управление сервисами на хосте. Внутри Docker-контейнера обычно нет systemd (там PID 1 — само приложение). А хост, на котором крутится Docker, почти всегда управляется systemd.
Аналогии из жизни
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 + ...
Шаг за шагом.
- Ядро запускается и вызывает
/sbin/init— а это симлинк на/lib/systemd/systemd. Всё, systemd теперь — PID 1. - systemd читает
default.target— «цель по умолчанию». Обычно этоmulti-user.target(сервер без графики) илиgraphical.target(десктоп). Target (цель) — это unit-файл, который сам ничего не запускает, а только группирует зависимости: «чтобы достичь цели multi-user, надо поднять network.target, ssh.service, cron.service…». - systemd строит dependency graph (граф зависимостей) — направленный ациклический граф всех юнитов, которые нужно стартовать. Смотрит поля
Requires=,After=,Before=,Wants=и раскладывает: «сначала — сеть, потом — nginx; параллельно с nginx — cron, они не зависят друг от друга». - Стартует юниты параллельно там, где это возможно. Здесь и живёт главное ускорение по сравнению с SysV: пять сервисов, не зависящих друг от друга, поднимаются одновременно. Если nginx ждёт network.target, systemd не тормозит cron — тот стартует в это же время.
- Ленивая активация по сокету (socket activation). Для «редких» демонов systemd открывает сокет вместо самого демона. Пример: cups (демон печати). Пока никто не печатает — cups не запущен. Кто-то отправил задачу на печать — systemd видит соединение на сокете, тут же поднимает cups и передаёт ему уже открытое соединение. Экономия памяти и времени загрузки.
- cgroups для изоляции. Каждый service — это отдельная cgroup ядра. systemd видит все процессы юнита (даже если они форкнулись), может задать лимит на CPU и память (
CPUQuota=50%,MemoryMax=512M), и при остановке юнита прибивает всё дерево — не бывает «зависших сирот». - 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.
systemctl start nginx— запустить.systemctl stop nginx— остановить.systemctl restart nginx— перезапустить.systemctl status nginx— увидеть состояние + последние 10 строк лога.systemctl enable nginx— включить автостарт при загрузке.systemctl disable nginx— выключить автостарт.systemctl daemon-reload— перечитать unit-файлы после правки.systemctl list-units --failed— все сервисы, которые не смогли стартовать.journalctl -u nginx -n 100 --no-pager— последние 100 строк лога nginx.
Помимо .service бывают юниты других типов: .timer (аналог cron-задачи), .socket (сокет для ленивой активации), .mount (монтирование файловой системы), .path (реагировать на появление файла), .target (группа зависимостей). Все — один синтаксис, один язык, одна CLI.
Где встречается в обычной жизни
- Домашний интернет-роутер на OpenWrt (в новых версиях) — не всегда systemd, но многие NAS, умные колонки, приставки на Linux используют systemd под капотом. Когда роутер «перезагружается за 20 секунд», а раньше грузился минуту — это оно.
- Электромобили и мультимедиа-системы в машинах. BMW, Audi, Tesla — часть их бортовой электроники крутится на Linux с systemd. Быстрая холодная загрузка после «зажигания» — это в том числе про socket activation.
- Кассы, банкоматы, POS-терминалы. Внутри — Linux (часто Debian/Ubuntu LTS), сервисы автоматически перезапускаются, если внезапно моргнуло питание, — заслуга systemd
Restart=on-failure. - NAS-хранилища Synology, QNAP — гибрид, но всё чаще на systemd. Расписания резервных копий, ротация логов, автоперезапуск демонов SMB — всё через systemd-таймеры и сервисы.
- VPN-серверы и роутеры со «стабильным аптаймом». Когда админ говорит «сервер работает без перезагрузки 3 года» — обычно там systemd, который тихо переподнимает упавшие подсервисы, не трогая машину целиком.
Где встречается в IT и бизнесе
- Веб-серверы в проде. 99% VPS/dedicated в облаках (AWS, GCP, Azure, Hetzner, Fornex) — Linux с systemd. Nginx, приложение на Python/Node/Go, PostgreSQL — всё оформлено как systemd-сервисы. Нужно, когда «упал сервис — поднимись сам», «выпустил новую версию — атомарно перезапусти», «нагрузка выросла — ограничь по памяти».
- CI/CD-раннеры и агенты автоматизации. GitLab Runner, self-hosted GitHub Actions runner, Jenkins-агенты — почти всегда крутятся под systemd. Класс задачи: «должно жить вечно, при падении — сразу подняться».
- Кластера баз данных, брокеры очередей. PostgreSQL, MySQL, Redis, RabbitMQ, Kafka — в проде развёрнуты как systemd-юниты. Часто дополнительно ограничены через
MemoryMax=, чтобы БД не съела всю оперативку сервера при аномальном запросе. - Планировщики фоновых задач (замена cron). systemd-таймеры — прямая замена cron на серверах. Плюс перед cron: единый интерфейс с логами, поддержка
OnCalendar=с наносекундной точностью, возможность запустить пропущенный запуск (если сервер был выключен) черезPersistent=true. - Managed-сервисы вроде «отправить бэкап в S3 каждую ночь». Ставится
.timer+.serviceвместо cron-джобы. Класс задачи: «раз в сутки надо что-то сделать, и я хочу видеть в одном месте логи всех прогонов, а не рыть syslog».
Кто пользуется
- Red Hat и вся её экосистема. RHEL 7/8/9 (примерно с 2014) — везде systemd. CentOS Stream, Rocky Linux, AlmaLinux — по цепочке. Красный шляпник — коммерческий владелец systemd (Поттеринг работал в Red Hat с 2008 до 2022, потом ушёл в Microsoft, но команда осталась).
- Debian и всё её потомство. Debian с версии 8 (2015). Ubuntu Server — с 15.04 (2015), Ubuntu Desktop — тогда же. Все производные (Linux Mint, Elementary, Pop!_OS, Kali, Raspbian/Raspberry Pi OS) — по умолчанию на systemd.
- SUSE. openSUSE и enterprise-линейка SLES — на systemd с 2012.
- Arch Linux и Manjaro. Всё на systemd с 2012.
- Крупные облака. AWS AMI Amazon Linux 2/2023 — systemd. Google Cloud, Azure — Ubuntu/CentOS/Debian, значит systemd. По разным оценкам, доля Linux-серверов на systemd среди публичных облаков — 95–99%.
- Кто НЕ использует. Alpine Linux (популярен в Docker-образах) — использует легковесный OpenRC. Gentoo — по выбору пользователя, OpenRC или systemd. Devuan, Void, Artix — идейные противники systemd, живы в нише «против». Слитная доля этих дистрибутивов — единицы процентов.
Альтернативы и конкуренты
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, не так глубоко интегрирован с системой.
Когда НЕ стоит использовать
- Внутри Docker-контейнера. Контейнер — это одно приложение. PID 1 там — само приложение. Тащить systemd внутрь — почти всегда антипаттерн: раздувает образ, ломает механизмы сигналов, дублирует изоляцию, которую уже даёт Docker. Есть редкие исключения (systemd-in-container для тестов), но по умолчанию — не надо.
- На embedded-железе с 16–64 МБ RAM (умные лампочки, IoT-датчики). Потому что systemd оптимизирован под серверы и десктопы, минимальная память под PID 1 и семейство утилит — десятки мегабайт. На микроконтроллерах и одноплатниках уровня старых роутеров лучше BusyBox init или runit.
- Когда команде принципиально важна философия «маленькие инструменты, каждый — про одно». Это идеологический выбор. Если ваша культура — минимализм и OpenBSD-подход, systemd будет вечным раздражителем. В такой команде лучше OpenRC/runit — потому что технический выбор всегда сталкивается с культурой и человеческими предпочтениями, и последнее сильнее.
Связанные понятия
- PID 1 — первый процесс в системе, потомок ядра. Именно им и работает systemd (или SysV init, или launchd).
- unit-файл — текстовый файл-описание сервиса, таймера, сокета, монтирования. Формат — ini-подобные секции.
- cgroups (control groups) — механизм ядра Linux для группировки процессов и ограничения им CPU, памяти, дисковых операций. systemd активно использует cgroups для изоляции сервисов.
- journald — компонент systemd, собирающий логи всех сервисов в бинарный индексируемый журнал. Смотреть через
journalctl. - socket activation (активация по сокету) — техника, при которой демон стартует только когда кто-то подключился к его сокету. Экономит память и время загрузки.
- target — специальный тип unit-файла, группа зависимостей. Аналог «уровня загрузки» из SysV (
runlevel 3≈multi-user.target).
Литература и источники
- freedesktop.org/wiki/Software/systemd — официальный сайт проекта, ссылки на документацию, man-страницы онлайн.
- Rethinking PID 1 — эссе Леннарта Поттеринга от 30 апреля 2010 года, где он впервые изложил идею systemd (искать по запросу «Lennart Poettering Rethinking PID 1»).
- Wikipedia: systemd — ru.wikipedia.org/wiki/Systemd, en.wikipedia.org/wiki/Systemd. Хороший обзор истории и споров вокруг systemd.
- man systemd.service — исчерпывающий справочник по секциям и параметрам unit-файлов. Есть онлайн-версия на freedesktop.org.
- Arch Wiki: systemd — wiki.archlinux.org/title/Systemd. Один из лучших практических туториалов, коротко и по делу.
- The systemd Manager (книга Nathan Willis) — если хочется в глубину, англоязычная книга-справочник, ищи по названию в электронных библиотеках.
Где встретилось у меня
Вчера чинил VPS: бот автопрозвона перестал стартовать, оказалось — переполнился диск. Диагностика вся шла через systemd: systemctl list-units --failed показал, кто упал, journalctl -u ... -n 200 — почему, systemctl restart — поднял обратно. Заодно проверил oneshot-таймеры парсеров и always-on сервисы. Без systemd пришлось бы лезть в пять разных мест.
Краткое резюме
- systemd — PID 1 в 95%+ современных Linux-серверов. Придумал Леннарт Поттеринг в Red Hat в 2010 году, вдохновляясь маковским launchd.
- Главная идея — декларативные unit-файлы вместо bash-скриптов SysV init: пишешь, ЧТО должно быть, а не КАК это запускать.
- Умеет: параллельный старт демонов, автоперезапуск после падения, socket activation (ленивая загрузка), cgroups-изоляция, единый журнал через journald, таймеры (замена cron).
- Ключевые команды на каждый день:
systemctl start/stop/restart/status,systemctl list-units --failed,journalctl -u <сервис>. - Не тащи systemd в Docker-контейнер и на embedded-железо с 32 МБ RAM. Всё остальное — почти всегда твой инструмент по умолчанию.