SystemD — это система инициализации и менеджер служб в Linux, пришедшая на смену традиционным SysVinit и Upstart. Она управляет запуском служб, отслеживает их состояние, обеспечивает зависимости между сервисами, управляет таймерами, сокетами и т.д. и т.п..
Ключевые понятия
- Юнит (unit) — абстрактный объект управления SystemD (служба, таймер, сокет и т. п.). Файлы юнитов лежат в /etc/systemd/system/ (пользовательские) и /usr/lib/systemd/system/ (по умолчанию от пакетов).
- Сервис (service) — юнит типа .service, описывающий запуск и управление приложением/демоном.
- Цель (target) — аналог «уровней запуска» (runlevels) в SysVinit; объединяет группы юнитов (например, multi-user.target, graphical.target).
- Зависимости — указания, какие юниты должны быть запущены до/после данного.
Структура файла сервиса (.service)
Типичный файл /etc/systemd/system/myservice.service:
[Unit]
Description=Пример сервиса
After=network.target # Запускаться после старта сети
[Service]
Type=simple # Тип запуска
ExecStart=/usr/bin/myapp --config /etc/myapp.conf
Restart=always # Перезапускать при падении
User=myuser # Запускать от имени пользователя
WorkingDirectory=/opt/myapp # Рабочий каталог
Environment="VAR1=value1" "VAR2=value2"
[Install]
WantedBy=multi-user.target # При включении добавлять в эту цель
Основные директивы [Service]:
- Type=:
- simple — процесс сразу становится главным.
- forking — процесс порождает дочерний (классический daemon).
- notify — сервис сообщает SystemD о готовности через sd_notify.
- exec — аналогично simple, но проверяет запуск команды.
- ExecStart= — команда запуска.
- ExecStop= — команда остановки (опционально и запускается после остановки сервиса).
- Restart= — когда перезапускать: no, always, on-failure и др.
- User=/Group= — пользователь и группа.
- WorkingDirectory= — рабочая директория.
- Environment= — переменные окружения.
- LimitNOFILE=, MemoryLimit= — лимиты ресурсов.
Примеры сервисов
- Простой веб-сервер (на Python)
Файл /etc/systemd/system/pyweb.service:
[Unit]
Description=Python Web Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 -m http.server 8000
Restart=always
User=www-data
WorkingDirectory=/var/www
[Install]
WantedBy=multi-user.target
- Сервис с внешним скриптом
Файл /etc/systemd/system/backup.service:
[Unit]
Description=Daily Backup
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backupuser
RemainAfterExit=yes # Статус «активен» после завершения
[Install]
WantedBy=multi-user.target
- Сервис с зависимостями
Файл /etc/systemd/system/app.service (требует базу данных):
[Unit]
Description=My App
After=network.target mysql.service
Requires=mysql.service
[Service]
Type=simple
ExecStart=/usr/bin/myapp
Restart=on-failure
[Install]
WantedBy=multi-user.target
Основные команды управления
- Управление службами
- systemctl start <service> — запустить сервис.
- systemctl stop <service> — остановить сервис.
- systemctl restart <service> — перезапустить сервис.
- systemctl reload <service> — перечитать конфигурацию (если поддерживается).
- systemctl enable <service> — добавить в автозагрузку.
- systemctl disable <service> — убрать из автозагрузки.
- systemctl status <service> — показать статус и логи.
- systemctl is-active <service> — проверить, запущен ли (возвращает active/inactive).
- systemctl is-enabled <service> — проверить, включён ли в автозагрузку.
- Просмотр списков и состояний
- systemctl list-units —type=service — список всех сервисов.
- systemctl list-units —type=service —state=running — только запущенные.
- systemctl —failed — показать упавшие сервисы.
- journalctl -u <service> — просмотреть логи сервиса.
- journalctl -u <service> -f — следить за логами в реальном времени.
- Работа с конфигурацией
- systemctl daemon-reload — перечитать конфигурации после изменения файлов .service.
- systemctl edit <service> — создать переопределение (drop-in) для сервиса (редактирует в /etc/systemd/system/<service>.d/).
- systemctl cat <service> — вывести содержимое файла сервиса.
- Управление целями (targets)
- systemctl isolate multi-user.target — переключиться на текстовую консоль.
- systemctl get-default — показать цель по умолчанию.
- systemctl set-default graphical.target — установить графическую цель по умолчанию.
- Общие операции
- systemctl reboot — перезагрузить систему.
- systemctl poweroff — выключить.
- systemctl halt — остановить систему (без отключения питания).
- systemctl suspend — перевести в спящий режим.
Полезные советы
- Логи: SystemD интегрирован с journald. Используйте journalctl для детального анализа.
- Переопределения: Вместо правки системных файлов .service создавайте переопределения через systemctl edit — так обновления пакетов не затрут ваши изменения.
- Зависимости: Используйте After=, Requires=, Wants= для корректной последовательности запуска.
- Отладка: Если сервис не запускается, смотрите логи: journalctl -u <service> -b (логи с последней загрузки).
- Таймеры: Для периодических задач вместо cron можно использовать юниты .timer (аналог cron с интеграцией в SystemD).
Проверка работоспособности
- Создайте файл сервиса в /etc/systemd/system/.
- Выполните systemctl daemon-reload.
- Включите сервис: systemctl enable myservice.service.
- Запустите: systemctl start myservice.service.
- Проверьте статус: systemctl status myservice.service.
- Посмотрите логи: journalctl -u myservice.service.
Лимиты ресурсов в SystemD
SystemD позволяет ограничивать ресурсы, потребляемые сервисами, через директивы в секции [Service] файла юнита (.service). Это помогает:
- предотвратить «раздувание» процессов;
- обеспечить изоляцию сервисов;
- соблюдать SLA и квоты;
- повысить стабильность системы.
Ключевые директивы лимитов
Ниже — основные параметры (все принимают числовые значения; единицы обычно подразумеваются, но можно указывать явно).
- LimitCPU=
Максимальное CPU‑время (в секундах). Если процесс превысит лимит, получит сигнал SIGXCPU.
Пример: LimitCPU=3600 — не более 1 часа CPU‑времени. - LimitFSIZE=
Максимальный размер создаваемых файлов (в байтах). При попытке записать больше — ошибка EPERM.
Пример: LimitFSIZE=1073741824 (1 ГБ). - LimitDATA=
Максимальный размер сегмента данных процесса (heap, глобальные переменные).
Пример: LimitDATA=536870912 (512 МБ). - LimitSTACK=
Максимальный размер стека потока (в байтах).
Пример: LimitSTACK=8388608 (8 МБ). - LimitCORE=
Максимальный размер дампа памяти (core dump). 0 — запретить дампы.
Пример: LimitCORE=0 (отключить core dumps). - LimitRSS=
Максимальный резидентный набор страниц (физическая память, в КБ).
Пример: LimitRSS=1048576 (1 ГБ). - LimitNOFILE=
Максимальное число открытых файловых дескрипторов.
Пример: LimitNOFILE=4096. - LimitNPROC=
Максимальное число процессов/потоков для этого сервиса.
Пример: LimitNPROC=100. - LimitMEMLOCK=
Максимальный объём памяти, который можно заблокировать (mlock).
Пример: LimitMEMLOCK=65536 (64 КБ). - LimitLOCKS=
Максимальное число файловых блокировок (flock, fcntl).
Пример: LimitLOCKS=1024. - LimitSIGPENDING=
Максимальное число сигналов в очереди для процесса.
Пример: LimitSIGPENDING=512. - LimitMSGQUEUE=
Максимальный размер POSIX message queue (в байтах).
Пример: LimitMSGQUEUE=819200 (800 КБ). - MemoryLimit=
Более современный и удобный аналог LimitRSS: жёсткий лимит на общую память (включая swap). Можно указывать с единицами.
Примеры: MemoryLimit=512M MemoryLimit=1G MemoryLimit=256K - CPUQuota=
Доля CPU в процентах (от одного ядра). Например, CPUQuota=50% означает «не более половины ядра».
Пример: CPUQuota=25% — сервис может использовать до 25 % одного CPU. - BlockIOWeight=
Приоритет I/O (от 10 до 1000). Влияет на планировщик CFQ/BFQ.
Пример: BlockIOWeight=200. - IOWeight=
Аналогично BlockIOWeight, но для cgroupv2.
Пример: IOWeight=300.
Где задавать лимиты
- В файле сервиса: /etc/systemd/system/myservice.service (предпочтительно).
- В переопределении: systemctl edit myservice создаёт файл в /etc/systemd/system/myservice.service.d/override.conf.
- Глобально — в /etc/systemd/system.conf (применяются ко всем сервисам).
Примеры конфигураций
Пример 1. Сервис с жёсткими лимитами памяти и CPU
[Unit]
Description=Ограниченный сервис
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp
# Жёсткий лимит памяти: 256 МБ
MemoryLimit=256M
# Не более 20 % одного CPU
CPUQuota=20%
# Максимум 1024 файловых дескриптора
LimitNOFILE=1024
# Максимум 50 процессов/потоков
LimitNPROC=50
# Запретить core dumps
LimitCORE=0
[Install]
WantedBy=multi-user.target
Пример 2. Веб‑сервис с ограничением файловых дескрипторов и стека
[Unit]
Description=Web Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/nginx
# Максимум 8192 файловых дескриптора
LimitNOFILE=8192
# Стек потока — не более 16 МБ
LimitSTACK=16777216
# Память — не более 1 ГБ
MemoryLimit=1G
[Install]
WantedBy=multi-user.target
Пример 3. Фоновый процессор задач с квотой CPU и I/O
[Unit]
Description=Task Processor
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/task-processor
# Не более 30 % CPU
CPUQuota=30%
# Приоритет I/O — 150
BlockIOWeight=150
# Память — до 512 МБ
MemoryLimit=512M
# Максимум 200 процессов
LimitNPROC=200
[Install]
WantedBy=multi-user.target
Как проверить действующие лимиты
- Статус сервиса
# systemctl status myservice
В выводе ищите строки с MemoryLimit, CPUQuota и т. п.
- Детали cgroups
# systemd-cgtop
Показывает использование ресурсов по cgroups.
- Прямые файлы cgroups
Лимиты видны в /sys/fs/cgroup/… (путь зависит от версии cgroups). Например:
cat /sys/fs/cgroup/system.slice/myservice.service/memory.max
cat /sys/fs/cgroup/system.slice/myservice.service/cpu.max
- journalctl
Если сервис нарушил лимит, в логах могут быть сообщения:
# journalctl -u myservice -b




