# systemd - init и менеджер сервисов _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** systemd - init-система Linux: PID 1, который запускает всё остальное, следит за зависимостями, перезапускает упавшее, агрегирует логи. ## Что делает PID 1 Когда ядро загрузилось - оно стартует один процесс с PID 1. На современных Linux это **systemd**. Его задачи: - Запустить нужные сервисы при старте системы - Следить за их состоянием, перезапускать упавшие - Управлять зависимостями («старт docker после network») - Подбирать «осиротевшие» процессы (parent умер - мы становимся новым) - Логировать всё через journald - Управлять [cgroups](/kb/cgroups.md) для лимитов и изоляции ## Unit-файлы Всё что systemd умеет делать = **unit**. Виды: - **`.service`** - обычный демон (nginx, ssh, postgres) - **`.socket`** - слушать сокет, запустить сервис при первом подключении - **`.timer`** - cron-replacement: запускать unit по расписанию - **`.mount` / `.automount`** - монтирование ФС - **`.target`** - группа unit'ов (как runlevel: `multi-user.target`, `graphical.target`) - **`.path`** - реагировать на появление/изменение файла - **`.slice`** - узел иерархии cgroup'ов Расположение: - `/lib/systemd/system/` - от пакетов - `/etc/systemd/system/` - твои локальные / drop-in'ы (приоритет) ## Минимальный service unit ```ini [Unit] Description=My App After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/myapp --config=/etc/myapp.yml Restart=on-failure RestartSec=5 User=myapp Group=myapp [Install] WantedBy=multi-user.target ``` Положить в `/etc/systemd/system/myapp.service`, потом: ```bash sudo systemctl daemon-reload sudo systemctl enable --now myapp ``` ## Type - модель запуска - `simple` - ExecStart = бинарь который НЕ форкается; default - `forking` - старая школа (бинарь форкает дочерку и выходит); `PIDFile=` нужен - `notify` - приложение шлёт `READY=1` через `sd_notify` когда готово - `oneshot` - выполнить и выйти (для скриптов/настроек) - `idle` - простой, но запустить когда другие units стабилизировались ## Зависимости - `Wants=` - мягкая зависимость (мы хотим, но не критично) - `Requires=` - жёсткая (если зависимость упала - мы тоже) - `After=` / `Before=` - порядок (не зависимость, а очерёдность!) - `Conflicts=` - взаимоисключение ## Изоляция через [cgroups](/kb/cgroups.md) systemd кладёт каждый сервис в свой cgroup и поддерживает sandboxing: ```ini [Service] MemoryMax=512M CPUQuota=50% PrivateTmp=yes # свой /tmp ProtectSystem=strict # /usr, /etc r/o ProtectHome=yes # /home, /root недоступны NoNewPrivileges=yes # запрет setuid-эскалации CapabilityBoundingSet=CAP_NET_BIND_SERVICE ``` Это даёт большую часть «контейнеризации» без Docker. ## Targets вместо runlevels Старое vs новое: | runlevel | systemd target | |---|---| | 0 | poweroff.target | | 1 | rescue.target | | 3 | multi-user.target (CLI) | | 5 | graphical.target (GUI) | | 6 | reboot.target | ```bash systemctl get-default # текущий default-target sudo systemctl set-default multi-user.target systemctl isolate rescue.target # перейти в target прямо сейчас ``` ## Дебаг ```bash systemctl status myapp # state + последние логи journalctl -u myapp -f # tail логов systemd-analyze blame # кто медленно стартовал systemd-analyze critical-chain # критический путь загрузки systemctl list-dependencies myapp ``` ## Команды ```bash systemctl --failed ``` Все упавшие сервисы - первое что смотришь после загрузки ```bash systemd-analyze blame | head ``` Топ медленных юнитов при старте - оптимизировать boot-time ```bash sudo systemctl edit myapp ``` Открыть drop-in override без правки оригинального unit'а ```bash systemctl cat myapp ``` Показать ИТОГОВЫЙ unit (с применёнными override'ами) ```bash systemctl daemon-reload ``` После правки unit-файлов обязательно - иначе systemd видит старую версию ## См. также - [systemctl - управление сервисами systemd](/kb/cmd-systemctl.md) - [journalctl - журнал systemd](/kb/cmd-journalctl.md) - [cgroups (v2)](/kb/cgroups.md) - [cgroups v2 - unified hierarchy, PSI, eBPF control](/kb/cgroups-v2-deep.md) - [Процесс и PID](/kb/process-and-pid.md)