Как работает systemd: структура, юниты и как писать собственные сервисы
systemd — это современная система инициализации (init system) и менеджер служб, используемый в большинстве современных дистрибутивов Linux.
Он управляет запуском, остановкой и мониторингом процессов, обеспечивает логирование и контроль зависимостей между сервисами.
Разберём, как устроен systemd, какие типы юнитов существуют и как написать собственную службу.
1. Что такое systemd
Исторически Linux использовал классическую систему инициализации SysVinit, которая запускала процессы последовательно по скриптам /etc/init.d/*.
systemd заменил её, предложив параллельный запуск, контроль зависимостей и централизованное управление службами.
Основные задачи systemd:
- управление службами и демонами (system services);
- контроль зависимостей при загрузке;
- логирование через journald;
- монтирование файловых систем;
- управление сессиями пользователей.
2. Основные команды systemd
Для управления службами используется утилита systemctl:
| Команда | Назначение |
|---|---|
systemctl start nginx | Запустить сервис |
systemctl stop nginx | Остановить сервис |
systemctl restart nginx | Перезапустить |
systemctl enable nginx | Включить автозапуск |
systemctl disable nginx | Отключить автозапуск |
systemctl status nginx | Проверить состояние |
systemctl list-units --type=service | Список активных сервисов |
3. Что такое юнит (unit)
В systemd все управляемые объекты называются юнитами (units).
Юнит — это конфигурационный файл с расширением .service, .socket, .mount и т. д., который описывает, что и как нужно запустить.
Типы юнитов:
| Тип | Расширение | Назначение |
|---|---|---|
| Service | .service | Службы и демоны |
| Socket | .socket | Сокеты для активации по запросу |
| Mount | .mount | Точки монтирования |
| Timer | .timer | Планировщик задач (аналог cron) |
| Target | .target | Группировка инициализации (например, multi-user.target) |
| Path | .path | Реакция на изменение файлов или директорий |
4. Структура .service файла
Рассмотрим пример простого юнита для Node.js-приложения:
/etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
After=network.target
[Service]
ExecStart=/usr/bin/node /var/www/myapp/server.js
Restart=always
User=www-data
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp
[Install]
WantedBy=multi-user.target
Разбор ключевых секций:
[Unit]— метаданные и зависимости;[Service]— параметры запуска;[Install]— куда "подвязывать" юнит при автозагрузке.
5. Как запустить свой сервис
После создания файла нужно обновить конфигурацию systemd:
sudo systemctl daemon-reloadДалее:
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
sudo systemctl status myapp.serviceТеперь сервис будет автоматически запускаться при старте системы.
6. Переменные окружения и логи
Переменные окружения можно передавать через:
- секцию
Environment=прямо в юните; - файл с переменными:
EnvironmentFile=/etc/myapp/env
Логи можно смотреть через journalctl:
journalctl -u myapp.service -f-f показывает поток логов в реальном времени (аналог tail -f).
7. Зависимости между сервисами
Systemd позволяет явно указывать порядок запуска:
[Unit]
After=postgresql.service
Requires=postgresql.service
After=определяет порядок старта;Requires=делает зависимость обязательной: если PostgreSQL не запущен —myapp.serviceтоже не стартует.
8. Полезные команды для диагностики
| Команда | Что делает |
|---|---|
systemctl list-unit-files --type=service | Список всех сервисов и их состояния (enabled/disabled) |
systemctl show nginx | Подробные свойства сервиса |
systemd-analyze blame | Показывает, какие службы дольше всего стартовали |
systemd-analyze critical-chain | Граф зависимостей при загрузке системы |
9. Пример — создание сервиса для Python-скрипта
/etc/systemd/system/hello.service
[Unit]
Description=Hello Service
[Service]
ExecStart=/usr/bin/python3 /opt/hello/hello.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
Далее:
sudo systemctl daemon-reload
sudo systemctl start hello.service
sudo systemctl enable hello.serviceТеперь ваш скрипт работает как полноценный демон, управляемый через systemctl.
10. Заключение
systemd — это не просто “замена init”, а полноценная экосистема для управления процессами, логами и зависимостями.
Создавая собственные юниты, вы можете:
- запускать свои приложения как службы;
- автоматически перезапускать их при сбоях;
- логировать работу через
journalctl; - управлять автозагрузкой.
Понимание структуры unit-файлов и принципов работы systemd — обязательный навык для любого Linux-админа или разработчика backend-приложений.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний