Блог "Дети ОИТа"
/поиск

Практическое руководство: systemd в production — от unit-файлов до observability

Практическое руководство по настройке systemd в production: от структуры unit-файлов и health-check'ов до логирования в journald, метрик для Prometheus и чек-листа выкатки.

Практическое руководство: systemd в production — от unit-файлов до observability

Введение

systemd — не просто init-система, а фундаментальный слой управления сервисами в современных Linux-дистрибутивах. В production-среде от корректной настройки unit-файлов зависит не только время старта, но и отказоустойчивость, наблюдаемость и безопасность. В этом руководстве мы пройдём путь от базового unit-файла до продвинутых сценариев: перезапуски по условиям, health-check’и, централизованный сбор логов и интеграция с Prometheus через node_exporter и systemd-exporter.

1. Анатомия unit-файла

Минимальный service-unit:

[Unit]
Description=Пример микросервиса
After=network.target

[Service]
Type=notify
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server --config /etc/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=3
StartLimitInterval=60
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

Ключевые поля:

  • Type=notify — сервис сам сообщает о готовности (sd_notify), systemd не угадывает. Для простых случаев — simple, для разветвлённых — forking.
  • Restart=on-failure + StartLimit* — защита от штормов рестартов.
  • RuntimeDirectory, StateDirectory, CacheDirectory, LogsDirectory — автоматическое создание каталогов с правильными правами (systemd 235+).

2. Health-check и готовность

Вариант A — readiness через sd_notify:

// В приложении: sd_notify(0, "READY=1");

Вариант B — systemd-exec-condition:

[Service]
ExecCondition=/usr/local/bin/health-check.sh

health-check.sh:

#!/usr/bin/env bash
set -euo pipefail
# Пример: ждём TCP
if ! timeout 2 bash -c "</dev/tcp/127.0.0.1/8080"; then
  exit 1
fi
exit 0

3. Логи: journald + структурирование

Включите хранение и разумное ротацию:

# /etc/systemd/journald.conf.d/storage.conf
[Journal]
Storage=persistent
SystemMaxUse=2G
RuntimeMaxUse=500M

# /etc/logrotate.d/journald
/var/log/journal/*/*.journal {
  daily
  rotate 14
  compress
  delaycompress
  missingok
  notifempty
  create 0640 root systemd-journal
}

Структурированные поля в логах приложения (json):

{"ts":"2026-10-12T10:00:00Z","level":"info","msg":"startup","service":"myapp","ver":"1.4.2","pid":1234}

Сбор в Loki/Promtail или Fluent Bit — по тегам systemd.unit и PRIORITY.

4. Observability: метрики systemd

  • node_exporter: текстовые файлы в /var/lib/node_exporter/textfile_collector/ (например, systemd_units.prom) с HELP/TYPE и значениями ActiveState/SubState.
  • Альтернатива: systemd-exporter (Prometheus exporter для unit-метрик).

Пример алёрта (Prometheus):

- alert: ServiceDown
  expr: node_systemd_unit_state{state="active"} == 0
  for: 2m
  labels:
    severity: критический
  annotations:
    summary: "Сервис {{ $labels.name }} не активен"
    runbook: "runbooks/service-down.md"

5. Безопасность

  • DynamicUser=yes — эфемерные пользователи, изоляция по временным директориям.
  • PrivateTmp=yes, ProtectSystem=strict, ProtectHome=yes — минимизация поверхности.
  • CapabilityBoundingSet, NoNewPrivileges=yes — ограничение привилегий.
  • systemd-analyze security <unit> — оценка профиля.

6. CI/CD: тестирование unit-файлов

  • ansible-lint для ролей, деплоящих unit-файлы.
  • container-based проверка: systemd в контейнере (через docker run --privileged --cgroupns=host) для smoke-тестов.
  • Molecule с scenario ‘systemd’ — запуск и проверка статуса через systemctl is-active.

7. Распространённые антипаттерны

  • Type=simple без health-check’а — ложные «зелёные» статусы.
  • Restart=always без StartLimit* — шторм рестартов.
  • Логи в файлы вместо journald — потеря структурности и централизованного доступа.
  • Жёстко закодированные пути — переносимость страдает; используйте %h, %t, %C.

8. Чек-лист выкатки

  • Unit прошёл systemd-analyze verify
  • Type и readiness согласованы
  • Restart/StartLimit настроены
  • RuntimeDirectory*/LogsDirectory* используются
  • Логи структурированы, retention задан
  • чек-лист observability: метрики экспортируются, алёрты проверены
  • Security profile проверен systemd-analyze security

Заключение

systemd даёт мощный инструментарий для надёжных production-сервисов, если использовать его семантику: notify/conditions, директории, ограничения и интеграцию с observability-стеком. Чек-лист и CI-проверки превращают unit-файлы из «конфига на проде» в воспроизводимый артефакт.


Ключевые слова: systemd, Linux, production, observability, unit-файл, journald, Prometheus, безопасность, CI/CD.