О, великий systemd

Systemd — это современная система инициализации и управления службами в Linux. Она использует unit-файлы (юниты) для описания сервисов, таймеров, сокетов и других сущностей.

Где лежат systemd-Юниты:

  • /lib/systemd/system/
  • /usr/lib/systemd/user/
  • /usr/lib/systemd/system/ (повторение)
  • Самый часто используемый - /etc/systemd/system/, в который мы будем добавлять свои.

Типы юнитов systemd

  1. target — группирует сервисы в группы, аналогично понятию runlevel.
  2. service — отвечает за запуск сервисов и поддерживает вызов интерпретаторов для исполнения пользовательских скриптов.
  3. mount — занимается монтированием файловых систем.
  4. automount — автоматическое挂载, используется при обращении к точке montariруания.
  5. swap — отвечает за подключение файла подкачки.
  6. timer — запускает модули по расписанию, аналогично cron.
  7. socket — запуск модуля при подключении к сокету.
  8. slice — группировка других модулей в контейнере (дерево) cgroups.
  9. device — использует реакцию на подключение какого-либо устройства.
  10. path — запуск модуля по событию доступа по конкретному пути в файловой системе.

После изменения unit-файлов обязательно выполнять:

sudo systemctl daemon-reload

Структура unit-файла

Файл имеет формат INI (секции в квадратных скобках). Основные секции:

  1. [Unit] — общее описание и зависимости.
    • Description — краткое описание сервиса
    • After, Before — порядок запуска относительно других юнитов
    • Requires — жёсткая зависимость (если зависимый юнит падает, текущий тоже останавливается)
    • Wants — мягкая зависимость (сервис попытается запуститься, даже если зависимость не работает)
    • Conflicts — запрещает совместный запуск с другим юнитом

Пример:

[Unit]
Description=Мой веб-сервер
After=network.target postgresql.service
Wants=postgresql.service
  1. [Service] — настройки сервиса.
    • Type — тип сервиса:
      • simple (по умолчанию) — systemd считает сервис запущенным сразу после ExecStart.
      • forking — для демонов, которые форкаются (нужен PIDFile).
      • oneshot — сервис завершается после выполнения команды (полезно для скриптов).
      • notify — сервис уведомляет systemd о готовности (через sd_notify)
    • ExecStart, ExecStop, Restart, User, Group, WorkingDirectory, Environment

Пример:

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/myapp/server.py
User=myapp
Group=myapp
Restart=on-failure
Environment="PORT=8080"
  1. [Install] — настройки для systemctl enable.
    • WantedBy — в какой target добавить сервис (например, multi-user.target).
    • RequiredBy — аналогично, но с жёсткой зависимостью

Пример:

[Install]
WantedBy=multi-user.target

Примеры

Пример 1: Простой сервис (Python-скрипт)

/etc/systemd/system/myapp.service:

[Unit]
Description=Мой Python-сервис
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/myapp/main.py
WorkingDirectory=/opt/myapp
User=appuser
Restart=on-failure

[Install]
WantedBy=multi-user.target

Пример 2: Демон с PID-файлом (forking)

[Service]
Type=forking
ExecStart=/usr/local/bin/mydaemon --pid-file=/run/mydaemon.pid
PIDFile=/run/mydaemon.pid
Restart=always

Пример 3: Таймер (аналог cron)

Файл /etc/systemd/system/backup.timer:

[Unit]
Description=Ежедневное резервное копирование

[Timer]
OnCalendar=daily
Persistent=true
Unit=backup.service

[Install]
WantedBy=timers.target

Файл /etc/systemd/system/backup.service:

[Unit]
Description=Backup Script

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Запуск и управление сервисами

  1. Просмотр всех юнитов:
    systemctl list-units --type=service --all
    
  2. Запустить сервис:
    systemctl start name
    
  3. Остановить сервис:
    systemctl stop name
    
  4. Перезапустить сервис:
    systemctl restart name
    
  5. Статус сервиса:
    systemctl status name
    
  6. Перечитать конфигурацию:
    systemctl reload name
    
  7. Загрузить новую конфигурацию для всех unit-файлов:
    systemctl daemon-reload
    
  8. Перезапустить сервис, если он запущен:
    systemctl try-restart name
    
  9. Включить автозапуск сервиса:
    systemctl enable name
    
  10. Отключить автозапуск сервиса:
    systemctl disable name
    
  11. Список установленных юнит-файлов сервисов:
    systemctl list-unit-files --type service
    
  12. Список зависимостей сервиса:
    systemctl list-dependencies