Какие бывают типы сервисов в Linux и как они работают на низком уровне?

«Какие бывают типы сервисов в Linux и как они работают на низком уровне?» — вопрос из категории Linux, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Linux под "сервисом" обычно понимают демон — фоновый процесс, предоставляющий какую-либо функциональность. Я управляю ими на разных уровнях:

1. Systemd (стандарт для современных дистрибутивов)

  • Управление: systemctl start|stop|restart|status <service>.
  • Конфигурация: Файлы юнитов в /etc/systemd/system/. Например, юнит для кастомного демона:

    [Unit]
    Description=Custom Metrics Exporter
    After=network.target
    
    [Service]
    Type=simple
    User=exporter
    ExecStart=/usr/local/bin/metrics-exporter --config /etc/exporter/config.yaml
    Restart=on-failure
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target
  • Как работает: systemd (PID 1) порождает процесс, отслеживает его состояние, управляет зависимостями, перезапускает при сбоях и собирает его логи (через journald).

2. Управляемые супервизором (Supervisor, systemd)

  • Для управления группами процессов, например, воркерами очереди. Конфиг для Supervisor:
    [program:celery_worker]
    command=celery -A proj worker --loglevel=info
    directory=/opt/app
    user=appuser
    autostart=true
    autorestart=true

3. Контейнеры как сервисы

  • Демон работает внутри контейнера. Управление жизненным циклом делегируется Docker (docker run -d) или оркестратору (Kubernetes Pod).

Низкоуровневый механизм работы демона:

  1. Процесс-родитель (часто init/systemd) вызывает fork() для создания дочернего процесса.
  2. Дочерний процесс вызывает setsid() чтобы стать лидером новой сессии и отвязаться от управляющего терминала.
  3. Процесс меняет рабочую директорию (chdir("/")), сбрасывает маску файлов (umask(0)) и перенаправляет или закрывает стандартные дескрипторы ввода/вывода.
  4. Демон начинает свою основную работу: слушает сокет (например, веб-сервер на порту 80), читает из очереди сообщений или обрабатывает файлы в каталоге.

Пример "ручного" создания демона на C (упрощенно):

pid = fork();
if (pid > 0) exit(0); // Завершаем родительский процесс
setsid(); // Становимся лидером сессии
chdir("/"); // Меняем рабочую директорию на корень
close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO);
// ... Основной цикл работы демона ...

На практике сейчас почти всегда используется systemd, который берет на себя все эти низкоуровневые задачи.