# systemd targets - runlevels по-новому _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** Target - unit-файл `.target` который описывает желаемое состояние системы как набор зависимостей. Замена SystemV runlevels: `multi-user.target` ≈ runlevel 3, `graphical.target` ≈ runlevel 5. ## Что такое target Target - это **не процесс и не сервис**. Это `.target`-unit, который не делает ничего сам, но через `Wants=` / `Requires=` тянет за собой набор других unit'ов. Достижение target = «все нужные сервисы подняты». Аналогия из SystemV: target ≈ runlevel, но с зависимостями вместо пронумерованных скриптов в `/etc/rc3.d/`. ## Маппинг с SystemV runlevels | SystemV runlevel | systemd target | Что значит | |------------------|-------------------------|-----------------------------------------| | 0 | `poweroff.target` | Выключение | | 1 / S | `rescue.target` | Single-user, ФС смонтирована, root-shell| | 1 (deeper) | `emergency.target` | Только emergency-shell, ФС не монтируется| | 2 | `multi-user.target` | Многопользовательский без NFS (раньше) | | 3 | `multi-user.target` | CLI-сервер: всё крутится, без GUI | | 5 | `graphical.target` | Сервер + display manager (GUI) | | 6 | `reboot.target` | Перезагрузка | Алиасы `runlevel3.target` → `multi-user.target` сохранены для обратной совместимости со старыми скриптами и командой `init 3`. ## default.target - куда грузится система `/etc/systemd/system/default.target` - **symlink** на canonical target: ```bash ls -l /etc/systemd/system/default.target # → /usr/lib/systemd/system/graphical.target ``` Это то, что systemd подхватывает при старте если в kernel cmdline не передан `systemd.unit=...`. Менять руками `ln -s` не надо - есть команда: ```bash systemctl get-default # текущий sudo systemctl set-default multi-user.target # для серверов без GUI ``` ## Системные target'ы - полная цепочка boot Они образуют дерево зависимостей. Идут от низкоуровневых к высокоуровневым: ``` sysinit.target ← маунты, swap, sysctl, journald ↓ basic.target ← timers.target, sockets.target, slices.target ↓ multi-user.target ← все обычные демоны (sshd, nginx, postgres) ↓ graphical.target ← + display-manager.service (gdm/lightdm) ↓ default.target ← symlink на одно из вышеперечисленного ``` Параллельно есть «синхронизирующие» target'ы: - `network.target` - все network-units сконфигурированы (НЕ значит онлайн) - `network-online.target` - сеть реально готова, IP получен (для сервисов которые без интернета бесполезны) - `local-fs.target` - все локальные ФС из [mount-and-fstab](/kb/mount-and-fstab.md) смонтированы - `remote-fs.target` - все NFS/SMB смонтированы - `time-sync.target` - время синхронизировано (см. [chrony-and-ntp](/kb/chrony-and-ntp.md)) ## Как target собирает свои unit'ы Два механизма: **1) Через [Install] секцию сервиса** - когда ты делаешь `systemctl enable nginx`, создаётся symlink: ``` /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service ``` Эта папка `.wants/` (и `.requires/`) - то, что target подхватывает при старте. **2) Через директиву `WantedBy=` в самом target-файле** - для системных целей. ```bash cat /usr/lib/systemd/system/graphical.target # [Unit] # Description=Graphical Interface # Requires=multi-user.target # Wants=display-manager.service # After=multi-user.target display-manager.service # AllowIsolate=yes ``` `AllowIsolate=yes` - критично: без этого target нельзя сделать default и нельзя переключиться через `isolate`. ## Переключение между target'ами на лету ```bash sudo systemctl isolate multi-user.target # уйти в CLI без reboot sudo systemctl isolate graphical.target # вернуть GUI sudo systemctl isolate rescue.target # ремонт без перезагрузки sudo systemctl rescue # то же что isolate rescue.target sudo systemctl emergency # экстренный shell ``` `isolate` останавливает всё что НЕ нужно для нового target и стартует то что нужно. Имя странное - но это оно. ## Передача target через GRUB при загрузке Если система не грузится в default.target - можно один раз перебить из GRUB. На экране меню - `e` для редактирования, в строке `linux ...` дописать: ``` systemd.unit=rescue.target ``` Дальше `Ctrl+X` для загрузки. Только этот раз - default не меняется. ## Дебаг - что входит в target ```bash systemctl list-units --type=target # активные target'ы systemctl list-dependencies multi-user.target # дерево всех unit'ов systemctl list-dependencies --reverse nginx # в какие target'ы попадает nginx systemctl cat multi-user.target # итоговый файл ``` Создавать **свой** target имеет смысл редко - например для группы собственных сервисов которые включаются/выключаются вместе. Чаще достаточно `WantedBy=multi-user.target` в обычных юнитах. ## Команды ```bash systemctl get-default ``` В какой target грузится система при boot - обычно multi-user или graphical ```bash sudo systemctl set-default multi-user.target ``` Сделать сервер CLI-only - экономит ресурсы, не нужен display-manager ```bash sudo systemctl isolate rescue.target ``` Уйти в single-user mode на лету (без reboot) для ремонта ```bash systemctl list-dependencies multi-user.target ``` Показать всё дерево unit'ов которые тянет target - что реально стартует ```bash systemctl list-units --type=target --all ``` Все target'ы с их статусом - увидеть какие активны прямо сейчас ## См. также - [systemd - init и менеджер сервисов](/kb/systemd.md) - [systemctl - управление сервисами systemd](/kb/cmd-systemctl.md) - [Типы systemd-юнитов](/kb/systemd-unit-types.md) - [systemd drop-ins - override без правки оригинала](/kb/systemd-drop-ins.md) - [Prometheus: scrape, TSDB, PromQL и production-pitfalls](/kb/prometheus-basics.md)