Собственная служба systemd: разработка и безопасность¶
В НАЙС.ОС CLOUD роль менеджера служб выполняет systemd. Чтобы процесс надёжно запускался, останавливался и журналировался, его следует оформить как unit. Однако systemd не исправляет ошибки приложения и не гарантирует наличие сети/диска без явных зависимостей.
1. Типы unit¶
service запускает процесс; socket реализует сокетную активацию; timer запускает задачи по расписанию; mount управляет монтированием; target объединяет состояния загрузки. Устанавливать свои unit рекомендуется в /etc/systemd/system/, тогда как файлы в /usr/lib/systemd/system/ обычно принадлежат пакетам.
systemctl list-unit-files --type=service --no-pager | head -40
systemctl cat sshd.service
systemctl show sshd.service -p FragmentPath -p DropInPaths
Имя sshd.service подтверждено SPEC OpenSSH, но для диагностики на конкретном хосте сначала проверяйте systemctl list-unit-files '*ssh*'.
2. Пример отдельного приложения¶
Допустим, вы сами установили приложение /opt/example/bin/worker и создали системного пользователя example. Следующий unit показывает модель, но не может работать до создания приложения и учётной записи:
# /etc/systemd/system/example-worker.service
[Unit]
Description=Example background worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=example
Group=example
WorkingDirectory=/opt/example
ExecStart=/opt/example/bin/worker
Restart=on-failure
RestartSec=10s
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes
[Install]
WantedBy=multi-user.target
ProtectSystem=full делает системные каталоги частично недоступными для записи процессу, но требования конкретного приложения нужно тестировать. Если worker должен писать в /var/lib/example, используйте выделенную директорию и политику прав; не запускайте его как root из удобства.
3. Проверка и запуск¶
systemd-analyze verify /etc/systemd/system/example-worker.service
systemctl daemon-reload
systemctl start example-worker.service
systemctl status example-worker.service --no-pager --full
journalctl -u example-worker.service -b --no-pager -n 100
Только если приложение запускается корректно и политика позволяет автозапуск:
enable создаёт связи автозапуска, но не означает, что служба уже запущена. start запускает сейчас, но не добавляет в автозапуск. Отличайте эти операции.
4. Изменение пакетной службы¶
Не редактируйте unit-файл из /usr/lib/systemd/system/, потому что обновление RPM может его заменить. Используйте:
systemctl edit example-worker.service
systemctl cat example-worker.service
systemctl show example-worker.service -p DropInPaths
Параметры ExecStart при переопределении часто требуют очистить исходное значение пустой строкой. Проверяйте systemctl cat и документацию systemd.service перед использованием drop-in.
5. Диагностика¶
| Проблема | Проверка |
|---|---|
status=203/EXEC |
Путь и права исполняемого файла, shebang, SELinux |
status=217/USER |
Пользователь отсутствует/ошибка настройки UID |
Start request repeated too quickly |
Реальная первопричина в journal; start limit |
| Работает руками, не работает в unit | Окружение, права, рабочий каталог, сеть |
| Стартует до диска | mount dependencies, RequiresMountsFor= |
Никогда не заменяйте расследование циклическим Restart=always с интервалом в миллисекунды: это усилит нагрузку и скроет проблему.
Откат¶
В тестовой среде выполните systemctl stop, disable, удалите только созданный вами unit и systemctl daemon-reload. Чужие пакетные unit удалять нельзя. По результату диагностики сохраняйте unit и обезличенный journal.
Источники: Core/systemd/SPECS/systemd.spec; systemd.unit.