О нас Руководства Проекты Контакты
Админка
пожалуйста подождите

Введение

Systemd — стандартный менеджер служб в современных дистрибутивах Linux. Понимание systemd необходимо для развёртывания и управления приложениями в production — от запуска служб при загрузке до мониторинга их состояния, управления зависимостями и проверок работоспособности. В этом руководстве рассматриваются практические аспекты администрирования systemd для развёртывания приложений.

Основы управления службами

Часто используемые команды

# Запуск/остановка/перезапуск службы
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# Перезагрузка конфигурации без перезапуска
sudo systemctl reload nginx
# Включить/отключить службу при загрузке
sudo systemctl enable nginx
sudo systemctl disable nginx
# Включить и запустить одной командой
sudo systemctl enable --now nginx
# Проверить статус службы
sudo systemctl status nginx
# Показать список всех служб
sudo systemctl list-units --type=service
# Показать список включённых служб
sudo systemctl list-unit-files --type=service --state=enabled

Вывод статуса службы

● nginx.service - A high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-01-15 10:30:00 UTC; 5h ago
Docs: man:nginx(8)
Main PID: 1234 (nginx)
Tasks: 5 (limit: 4915)
Memory: 12.5M
CPU: 1.234s
CGroup: /system.slice/nginx.service
├─1234 nginx: master process /usr/sbin/nginx
└─1235 nginx: worker process

Ключевые индикаторы:

  • Active: Текущее состояние (running, dead, failed)
  • Main PID: Идентификатор процесса (PID) основного процесса
  • Memory/CPU: Использование ресурсов

Создание пользовательских служб

Базовый unit-файл службы

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
Documentation=https://myapp.example.com/docs
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node /var/www/myapp/server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
# Применить изменения
sudo systemctl daemon-reload
sudo systemctl enable --now myapp

Типы служб

# Simple (по умолчанию): основной процесс и есть служба
Type=simple
ExecStart=/usr/bin/myapp
# Forking: процесс форкается, а родительский процесс завершается
Type=forking
PIDFile=/var/run/myapp.pid
ExecStart=/usr/bin/myapp --daemon
# Oneshot: процесс выполняется один раз и завершается
Type=oneshot
ExecStart=/usr/bin/setup-script.sh
RemainAfterExit=yes
# Notify: процесс сигнализирует о готовности
Type=notify
ExecStart=/usr/bin/myapp --notify

Конфигурация окружения

[Service]
# Переменные окружения inline
Environment=NODE_ENV=production
Environment=PORT=3000
# Файл окружения
EnvironmentFile=/etc/myapp/environment
# Несколько файлов окружения
EnvironmentFile=-/etc/myapp/environment # - означает опционально
EnvironmentFile=/etc/myapp/secrets
# /etc/myapp/environment
NODE_ENV=production
PORT=3000
DATABASE_URL=postgres://localhost/myapp

Ограничения ресурсов

Память и CPU

[Service]
# Ограничения памяти
MemoryMax=512M
MemoryHigh=400M
# Ограничения CPU
CPUQuota=50%
CPUWeight=100
# Файловые дескрипторы
LimitNOFILE=65535
# Ограничения по числу процессов
LimitNPROC=4096
# Core dumps
LimitCORE=infinity

Ограничения I/O

[Service]
IOWeight=500
IOReadBandwidthMax=/dev/sda 10M
IOWriteBandwidthMax=/dev/sda 5M

Усиление безопасности

Параметры изоляции

[Service]
# Запуск от имени не-root
User=myapp
Group=myapp
# Ограничения файловой системы
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/myapp /var/log/myapp
ReadOnlyPaths=/etc/myapp
# Временный каталог
PrivateTmp=yes
# Сетевая изоляция
PrivateNetwork=yes # Без доступа к сети
# Доступ к устройствам
PrivateDevices=yes
# Запрет повышения привилегий
NoNewPrivileges=yes
# Фильтрация системных вызовов
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM

Ограничения capabilities

[Service]
# Сбросить все capabilities, кроме необходимых
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
# Удалить все capabilities
CapabilityBoundingSet=

Надзор за процессами

Политики перезапуска

[Service]
# Параметры перезапуска: no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always
Restart=on-failure
# Интервал между перезапусками
RestartSec=5s
# Максимальное число попыток перезапуска
StartLimitIntervalSec=300
StartLimitBurst=5
# Действия при достижении лимита
# FailureAction=reboot
# SuccessAction=poweroff

Watchdog

[Service]
Type=notify
WatchdogSec=30s
# Приложение должно периодически вызывать sd_notify(0, "WATCHDOG=1")

Команды до/после запуска

[Service]
ExecStartPre=/usr/bin/check-config.sh
ExecStart=/usr/bin/myapp
ExecStartPost=/usr/bin/notify-started.sh
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/usr/bin/graceful-stop.sh
ExecStopPost=/usr/bin/cleanup.sh

Логирование с помощью Journal

Просмотр логов

# Логи службы
sudo journalctl -u myapp
# Следовать за логами
sudo journalctl -u myapp -f
# Последние 100 строк
sudo journalctl -u myapp -n 100
# С момента загрузки
sudo journalctl -u myapp -b
# Диапазон времени
sudo journalctl -u myapp --since "2024-01-15 10:00:00" --until "2024-01-15 12:00:00"
# Фильтр по приоритету (err и выше)
sudo journalctl -u myapp -p err
# Вывод в JSON
sudo journalctl -u myapp -o json
# Использование диска
sudo journalctl --disk-usage

Конфигурация логов

[Service]
# Отправлять вывод в journal
StandardOutput=journal
StandardError=journal
# Или в файл
StandardOutput=append:/var/log/myapp/output.log
StandardError=append:/var/log/myapp/error.log
# Идентификатор syslog
SyslogIdentifier=myapp

Персистентность Journal

# Сделать логи персистентными
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
# Настроить хранение
sudo vi /etc/systemd/journald.conf
# SystemMaxUse=500M
# MaxRetentionSec=1month
sudo systemctl restart systemd-journald

Таймеры (замена cron)

Unit-файл таймера

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Backup service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Расписания таймеров

# Выражения календаря
OnCalendar=hourly
OnCalendar=daily
OnCalendar=weekly
OnCalendar=monthly
OnCalendar=*-*-* 00:00:00 # Ежедневно в полночь
OnCalendar=Mon *-*-* 00:00:00 # Каждый понедельник
OnCalendar=*-*-* *:00:00 # Каждый час
OnCalendar=*-*-* *:*:00 # Каждую минуту
# Относительное время
OnBootSec=5min # Через 5 минут после загрузки
OnUnitActiveSec=1h # Через 1 час после последней активации

Управление таймерами

# Список таймеров
sudo systemctl list-timers
# Включить таймер
sudo systemctl enable --now backup.timer
# Немедленно запустить связанную службу
sudo systemctl start backup.service

Активация по сокету

# /etc/systemd/system/myapp.socket
[Unit]
Description=My App Socket
[Socket]
ListenStream=8080
Accept=no
[Install]
WantedBy=sockets.target
# /etc/systemd/system/myapp.service
[Unit]
Description=My App
Requires=myapp.socket
[Service]
ExecStart=/usr/bin/myapp
StandardInput=socket

Служба запускается только при получении подключения на сокет.

Мультиинстанс-службы

# /etc/systemd/system/[email protected]
[Unit]
Description=My App instance %i
[Service]
ExecStart=/usr/bin/myapp --instance %i --port %i
User=www-data
[Install]
WantedBy=multi-user.target
# Запустить несколько инстансов
sudo systemctl enable --now myapp@3000
sudo systemctl enable --now myapp@3001
sudo systemctl enable --now myapp@3002
# Управлять всеми инстансами
sudo systemctl restart 'myapp@*'

Отладка

# Проверить синтаксис unit-файла
sudo systemd-analyze verify /etc/systemd/system/myapp.service
# Показать конфигурацию unit
sudo systemctl show myapp
# Показать зависимости unit
sudo systemctl list-dependencies myapp
# Проверить производительность загрузки
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain myapp.service

Лучшие практики

  1. Используйте Type=notify по возможности для точного статуса.
  2. Задавайте подходящие политики перезапуска для устойчивости.
  3. Применяйте параметры усиления безопасности.
  4. Используйте environment files для конфигурации.
  5. Настраивайте ограничения ресурсов, чтобы предотвратить неконтролируемые процессы.
  6. Используйте таймеры вместо cron для задач по расписанию.
  7. Мониторьте через journalctl и настраивайте хранение логов.

Заключение

Systemd предоставляет мощные возможности управления службами. Создавайте корректные unit-файлы с усилением безопасности, настраивайте подходящие политики перезапуска и используйте таймеры для задач по расписанию. Шаблоны из этого руководства помогут вам развёртывать и сопровождать надёжные production-службы.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
Зетка Интерактив