# Типы systemd-юнитов _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** Юнит - управляемый systemd ресурс. Расширение файла = тип: `.service` (демон), `.socket` (lazy-старт по сокету), `.timer`, `.mount`, `.path`, `.slice`/`.scope` (cgroup'ы), `.target` (группа). ## Где живут unit-файлы Три каталога с приоритетом снизу вверх (ниже = перебивает): ``` /usr/lib/systemd/system/ ← от пакетов (canonical, /lib/systemd/system - symlink) /run/systemd/system/ ← runtime, generated (systemd-fstab-generator и др.) /etc/systemd/system/ ← локальные правки SysAdmin'а, override'ы ``` Если файл с одинаковым именем есть в `/etc/` и в `/usr/lib/` - `/etc/` выигрывает целиком. Для частичной правки - drop-in (см. [systemd-drop-ins](/kb/systemd-drop-ins.md)). ## Полный список типов | Расширение | Кто пишет | Назначение | |---------------|------------------|------------------------------------------------| | `.service` | SysAdmin | Обычный демон (sshd, nginx, postgres) | | `.socket` | SysAdmin | Слушать сокет, активировать service по запросу | | `.timer` | SysAdmin | Cron-replacement (см. [systemd-timers](/kb/systemd-timers.md)) | | `.mount` | SysAdmin / auto | Mount-point (генерится из [mount-and-fstab](/kb/mount-and-fstab.md)) | | `.automount` | SysAdmin | Lazy-mount: монтирует при первом обращении | | `.swap` | SysAdmin / auto | Swap-устройство или файл | | `.target` | SysAdmin / dist | Группа юнитов (см. [systemd-targets](/kb/systemd-targets.md)) | | `.path` | SysAdmin | Триггер service'а на изменение файла/каталога | | `.slice` | SysAdmin / auto | Узел иерархии [cgroups](/kb/cgroups.md) для лимитов | | `.scope` | systemd | Внешне созданная группа процессов (sessions) | | `.device` | udev → systemd | Появилось /dev/* - авто, файла обычно нет | ## .service - самый частый Управляет демоном. Главное - `Type=` и `ExecStart=`. ```ini # /etc/systemd/system/myapp.service [Unit] Description=My App After=network-online.target postgresql.service Requires=postgresql.service [Service] Type=simple ExecStart=/usr/local/bin/myapp Restart=on-failure User=myapp [Install] WantedBy=multi-user.target ``` `Type=simple` - самый частый. Бинарь не форкается. Альтернативы - см. [systemd](/kb/systemd.md). ## .socket - socket activation Главная идея: systemd слушает сокет ВМЕСТО сервиса. При первом подключении - стартует парный `.service` и передаёт ему уже открытый fd. ```ini # /etc/systemd/system/myapp.socket [Unit] Description=My App socket [Socket] ListenStream=8080 Accept=no # один service на все коннекты (по умолчанию) [Install] WantedBy=sockets.target ``` Зачем: - **Lazy-start** - сервис не жрёт RAM пока никто не подключился. - **Параллельный boot** - клиенты могут писать в сокет ДО того как сервис реально стартанул, systemd буферизует. - **Zero-downtime restart** - рестарт сервиса не теряет коннекты. Пример из реальной жизни: `cups.socket`, `pcscd.socket`, `docker.socket`. ## .timer - расписание См. [systemd-timers](/kb/systemd-timers.md). Парный `.service` запускается по расписанию. ## .mount - точка монтирования Имя файла = mount-point с `/` заменённым на `-`. `/var/data` → `var-data.mount`. ```ini # /etc/systemd/system/var-data.mount [Unit] Description=Data partition [Mount] What=/dev/disk/by-uuid/abc-123 Where=/var/data Type=ext4 Options=defaults,noatime [Install] WantedBy=multi-user.target ``` На практике пишут `.mount`-юниты руками редко - `systemd-fstab-generator` парсит [mount-and-fstab](/kb/mount-and-fstab.md) и создаёт их в `/run/systemd/system/`. Свой юнит нужен когда требуются специфичные `Requires=`/`After=`. ## .automount - монтировать по требованию Парный `.automount` к `.mount`. Сама ФС не монтируется при boot - только при первом обращении к каталогу. Для редко используемых NFS/съёмных дисков. ```ini # /etc/systemd/system/mnt-nfs.automount [Unit] Description=NFS automount [Automount] Where=/mnt/nfs TimeoutIdleSec=600 # отмонтировать после 10 мин простоя [Install] WantedBy=multi-user.target ``` ## .path - реакция на файл Триггерит парный service когда файл появился/изменился. Inotify под капотом. ```ini # /etc/systemd/system/upload-watcher.path [Path] PathExistsGlob=/var/uploads/*.zip Unit=process-upload.service [Install] WantedBy=multi-user.target ``` Работает только если парный service `Type=oneshot` (или просто короткий). ## .slice и .scope - узлы cgroup'ов - `.slice` - иерархический контейнер для группировки сервисов под общие лимиты. Системные дефолты: `system.slice` (демоны), `user.slice` (юзеры), `machine.slice` (виртуалки/контейнеры). - `.scope` - **создаётся программно** systemd для внешне-запущенных групп процессов: SSH-сессии (`session-1.scope`), `systemd-run`, контейнеры от Docker/Podman. Свой slice пишут чтобы зашить лимит на группу сервисов: ```ini # /etc/systemd/system/heavy.slice [Slice] CPUQuota=200% MemoryMax=4G ``` И в сервисах: `Slice=heavy.slice`. См. [cgroups](/kb/cgroups.md). ## Дебаг - что есть в системе ```bash systemctl list-unit-files # ВСЕ установленные юниты systemctl list-unit-files --type=service # только сервисы systemctl list-units --type=socket # активные сокеты systemctl list-units --type=mount --all # все mount-юниты, включая стопнутые systemctl cat docker.socket # содержимое юнита целиком systemctl show -p TriggeredBy nginx.service # кто триггерит этот сервис ``` Состояния в `STATE` колонке: - `enabled` - есть symlink в `*.target.wants/` (стартует при boot) - `disabled` - symlink'а нет - `static` - нет [Install] секции, нельзя enable, тянется только через зависимости - `masked` - `/etc/systemd/system/` → `/dev/null` (не запустить никак) ## Команды ```bash systemctl list-unit-files --type=timer --state=enabled ``` Все enabled-таймеры - обзор того что реально стартует по расписанию ```bash systemctl cat ssh.socket ``` Полный итоговый файл юнита с применёнными drop-in'ами ```bash systemctl show -p Type,ExecStart,User nginx.service ``` Конкретные ключи юнита без вывода всего файла ```bash sudo systemctl mask telnet.socket ``` Жёстко запретить юнит - symlink на /dev/null, не запустится никак ```bash systemd-analyze verify /etc/systemd/system/myapp.service ``` Проверить unit-файл перед daemon-reload - синтаксис, deps, ошибки ## См. также - [systemd - init и менеджер сервисов](/kb/systemd.md) - [systemd targets - runlevels по-новому](/kb/systemd-targets.md) - [systemd timers - замена cron](/kb/systemd-timers.md) - [systemd drop-ins - override без правки оригинала](/kb/systemd-drop-ins.md) - [cgroups (v2)](/kb/cgroups.md) - [mount и /etc/fstab - подключение ФС](/kb/mount-and-fstab.md) - [systemctl - управление сервисами systemd](/kb/cmd-systemctl.md)