Практическое руководство: 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.