Управление службами в GNU/Linux #
Васильев Андрей Михайлович, 2023
Версии презентации
Загрузка системы #
Существует несколько стандартов для реализации систем загрузки
- BIOS, Basic Input Output System
- UEFI, Unified Extensible Firmware Interface
- EFI, Extensible Firmware Interface
- Множество закрытых решений
Решают общие задачи:
- Первоначальная инициализация устройств
- Поиск загрузчика ОС на устройствах хранения
- Поиск загрузчика ОС на сетевых устройствах
Загрузчик ОС #
Задачей загрузчика ОС является поиск ядра ОС с дальнейшей передачей ему управления
Современные загрузчики:
- Являются отдельными бинарными файлами на ПЗУ
- Обычно располагаются на ПЗУ в отдельном разделе
- Настраиваются с помощью внешнего файла
- Могут считывать данные из файловых систем
- Могут иметь интерактивный интерфейс для выбора ОС
- Решение для загрузки разных ОС
- Решение для загрузки разных ядер внутри одной ОС
Ядро ОС #
Ядро ОС обеспечивает эффективное использование технического обеспечения множеством конкурирующих друг с другом процессов
Операционная система помимо ядра предоставляет набор системных приложений
- Позволяющих настраивать параметры работы ядра
- Позволяющих управлять процессами внутри ОС
Файлы ядра Linux #
В GNU/Linux для загрузки ОС применяется связка из
- ядра ОС
- initrd, Initial RAM Disk, образа файловой системы, необходимой ядру для первичной загрузки операционной системы
Оба компонента поставляются файлами, лежащими в ПЗУ
В рамках initrd поставляются:
- Модули ядра ОС, необходимые для работы с оборудованием на данном компьютере
- Служебные приложения, нужные для загрузки модулей и настройки системы
Модули могут поставляться отдельно от ядра:
- Для поддержки проприетарных решений
- Для решения задачи поддержки множества разных конфигураций оборудования
Процесс загрузки ОС #
В рамках загрузки ядра ОС происходит поиск всего оборудования и его инициализация
После того как всё оборудование инициализировано, ядро запускает процесс-инициализации init
- Процесс работает до окончания работы ОС
- Процесс имеет идентификатор, равный 1
- Процесс запускает все остальные процессы в системе
Существует множество систем инициализации: SysVinit, systemd, openrc, runit, initware
- Для выбора системы инициализации ядру можно передать аргумент init с полным путём к исполняемому файлу
- Сравнение разных систем предоставляет проект Gentoo
Задачи системы инициализации #
- Запуск служб, постоянно работающих фоновых процессов
- В процессе запуска операционной системы
- При обращении к службе посредством сети, D-Bus, сокету и т.д.
- Перезапуск служб в случае их падения
Система инициализации может также выполнять действия других системных служб
- Подключение файловых систем (обычно да)
- Настройка сетевых интерфейсов (обычно нет)
- Запуск задач по расписанию (обычно нет)
- Журналирование работы служб (обычно нет)
- Управление входом пользователей в систему (обычно нет)
- Создание виртуальных файлов для устройств (обычно нет)
- Управление временем системы (обычно нет)
Стадии загрузки ОС #
При запуске системы обычно рассматриваются следующие стадии:
- Настройка ключевых служб (диски, системы обмена сообщениями и т.д.)
- Поддержка работы сессии суперпользователя
- Поддержка работы множества пользователей
- Запуск служб, обеспечивающих продуктовые функции системы (SSH, Веб-сервер, …)
- Поддержка работы с графическим пользовательским интерфейсом
Также система инициализации должна выполнять корректное выключение системы, т.е. выключать службы в правильном порядке и сохранить данные на ПЗУ в случаях:
- Завершения работы
- Перезагрузки системы
Система инициализации позволяет переходить между стадиями, выбирать разные стадии при запуске
Варианты реализации стадий #
SysV Runlevel | systemd Target (Цель) | Записки |
---|---|---|
0 | poweroff.target, runlevel0.target | Выключить систему. |
1, s, single | rescue.target, runlevel1.target | Режим одного пользователя. |
2, 4 | multi-user.target, runlevel2.target, runlevel4.target | Определённые пользователем (системой). По умолчанию 3 |
3 | multi-user.target, runlevel3.target | Многопользовательская инициализация, не графическая. Пользователи могут входить по сети или через терминалы. |
5 | graphical.target, runlevel5.target | Многопользовательская с поддержкой графического интерфейса. |
6 | reboot.target, runlevel6.target | Перезагрузка. |
emergency | emergency.target | Экстренный доступ для суперпользователя. |
Службы #
Служба обычно представляет собой некоторое приложение, которое постоянно запущено и которое предоставляет полезные услуги пользователю или другим приложениям
- Приложение реагирует на некоторые сигналы и выполняет некоторые действия
- Сигнал от ядра ОС о добавлении нового устройства
- Сигнал по шине взаимодействия, запрос на выполнение операции
- Сигнал по сетевому интерфейсу, выполнение действия
- Приложению для работы необходимо, чтобы все его зависимости были доступны на момент запуска:
- Файловая система с файлами службы уже доступна на момент запуска
- Сетевой интерфейс уже настроен и готов обрабатывать запросы
- Служба базы данных запущена и готова обрабатывать запросы
Службы также могут представлять собой действия, выполняющиеся с некоторой регулярностью, например по расписанию
Указание зависимостей #
Точное указание зависимостей позволяет ускорить загрузку системы, избежать проблем при запуске служб
- В классическом SysVInit необходимо было следить за включением службы в нужный уровень выполнения
- Подразумевается, что на третьем уровне уже доступны файловая система и сеть
- На последнем уровне можем надеяться, что служба базы данных тоже доступна
- Следующие системы инициализации предложили способы для указания зависимостей на уровне конкретных служб
- В рамках systemd каждая служба указывает список зависимостей:
- Явные зависимости от других служб
- Неявные зависимости через включение в конкретную цель
Настройка службы #
Вопрос запуска службы помимо момента запуска достаточно сложный:
- Где располагается исполняемый файл?
- Какие аргументы необходимо передать исполняемому файлу?
- Какие аргументы передавать через переменные окружения?
- С правами какого пользователя нужно запустить файл?
- Какие элементы должны быть доступны службы?
Помимо запуска есть много вопросов поддержки работы:
- Что делать в случае остановки службы?
- Как корректно выполнить перезапуск службы?
- Как проверить текущий статус работы службы?
Классическое решение #
Задача настройки параметров запуска службы достаточно сложная, разработчиками SysVInit решена не была, поэтому процесс запуска служб делегировали Shell-скриптам
- Требует высокой квалификации от разработчика
- Требуют запуска интерпретатора Shell для своей работы
- Сложно реализовать систему отслеживания работы
- Невозможно реализовать другие способы запуска:
- Запуск службы при обращении по шине D-Bus
- Запуск службы по расписанию
- Запуск службы по обращению к порту
Каждый из последних потребуют написания своей конфигурации
Настройка systemd #
Для описания всех компонентов systemd используются файлы модулей (unit), в которых описывается поведение конкретного компонента. В настоящий момент systemd поддерживает следующие виды модулей:
Тип модуля | Описание |
---|---|
Target | Синхронизационная точка для ряда модулей. Используется во время загрузки системы в определённом состоянии. |
Service | Модуль, который запускает, останавливает, перезапускает, даёт команду на обновление конфигурации различных служб, например Веб-сервер. |
Timer | Модуль данного типа активирует или деактивирует указанную службу по времени наступления таймера или истечения времени. |
Socket | Модуль данного типа активирует или деактивирует службу, когда приходит входящее подключение по указанному сокету. |
Device | A unit of this type implements device-based activation such as a device driver. |
Тип модуля | Описание |
---|---|
Mount | A unit of this type controls the file-system mount point. |
Automount | A unit of this type provides and controls on-demand mounting of file systems. |
Swap | A unit of this type encapsulates/activates/deactivates swap partition. |
Path | A unit of this type monitors files/directories and activates/deactivates a service if the specified file or directory is accessed. |
Snapshot | A unit that creates and saves the current state of all running units. This state can be used to restore the system later. |
Slice | A group of units that manages system resources such as CPU, and memory. |
Scope | A unit that organizes and manages foreign processes. |
busname | A unit that controls DBus system. |
Каталоги конфигурации systemd #
Список можно посмотреть в man-руководстве systemd.unit
- Пути для поиска модулей системного уровня
/etc/systemd/system.control/*
/run/systemd/system.control/*
/etc/systemd/system/*
— Файлы, созданные администратором/run/systemd/system/*
/lib/systemd/system/*
— Файлы, установленные вместе с пакетом приложения- …
- Пути для поиска модулей пользовательского уровня
~/.config/systemd/user.control/*
~/.config/systemd/user/*
$XDG_CONFIG_DIRS/systemd/user/*
/etc/systemd/user/*
$XDG_RUNTIME_DIR/systemd/user/*
/run/systemd/user/*
- …
Настройка systemd-службы #
Конфигурационные файлы служб systemd являются текстовыми файлами в формате INI
- Все типы конфигурационных файлов являются unit-файлами
- Все элементы конфигурации unit-файлов можно написать в других типах файлов
- Полную документацию можно найти в страницах
systemd.unit
,systemd.service
,systemd.timer
и т.д - Ввиду многообразия задач, решаемых systemd, конфигурационные файлы достаточно сложные
Простая служба на systemd #
[Unit]
Description=Start n service
After=default.target
[Service]
Type=simple
ExecStart=/usr/bin/n
[Install]
WantedBy=default.target
- Секция
Unit
описывает общую информацию о службе, часть unit-файловDescription
— краткое описание назначения службеAfter
— указание зависимости одной службы от другой
- Секция
Install
описывает параметры автоматического запуска службы при старте системы, часть unit-файловType
— поведение приложения после запускаWantedBy
— указание зависимости от цели запуска
- Секция
Service
описывает детали запуска службыExecStart
— команда для запуска приложения, должна включать полный путь к исполняемому файлу, может включать аргументы
Что нужно настроить #
Требований к параметрам работы служб много — скорее всего на настоящий момент в systemd есть поддержка для решения данной задачи
Указание учётной записи #
Если не указать пользователя, то приложение будет работать с правами суперпользователя, что является проблемой для большинства служб
В секции Service
необходимо указать пользователя с помощью параметра User
Настройка параметров перезапуска #
Служба не всегда ведёт себя как следует и может упасть. Политика перезапуска определяется в секции Service
с помощью параметра Restart
on-failure
— перезапускать в случае паденияalways
— перезапускать даже когда хорошо завершилось
Добавление новых служб #
- Создайте текстовый файл службы в каталоге
/etc/systemd/system
- Созданный файл должен иметь расширение
.service
- Предположим, что файл называется
example.service
- Созданный файл должен иметь расширение
- Заполните необходимые поля в созданном файле:
- Заполните секцию
[Unit]
, указав описание и зависимости - Заполните секцию
[Service]
, указав параметры запуска приложения - Заполните секцию
[Install]
, указав параметры автоматического запуска
- Заполните секцию
- Скажите демону systemd перечитать конфигурацию с жёсткого диска, выполнив команду
systemctl daemon-reload
- Запустите службу средствами systemd, выполнив команду
systemctl start example
или целикомsystemctl start example.service
- Посмотрите на статус запущенной службы
systemctl status example
Для остановки службы используйте команду systemctl stop example
Автоматический запуск службы #
Команды start
и stop
приложения systemctl
пытаются запустить или остановить процесс, который находится под управлением systemd
Для настройки автоматического запуска необходимо:
- Добавить секцию
[Install]
внутри конфигурационного файла - Выполнить команду
systemctl enable example.service
Последняя команда настраивает запуск службы при старте ОС, не запускает её сейчас
- Для запуска службы необходимо вызвать команду
start
- При включении автоматического запуска можно передать аргумент
--now
:systemctl enable --now example.start
. В этом случае будет настроен автоматический запуск при старте и будет выполнена попытка запуска службы сейчас
Для выключения автоматического systemctl disable example
или systemctl disable --now example
Управление службами systemd #
Анализ поведения системы
Дейтвие | Команда |
---|---|
Отобразить состояние systemd | systemctl status |
Отобразить список запущенных модулей | systemctl или systemctl list-units |
Отобразить список упавших модулей | systemctl --failed |
Отобразить список конфигурационных файлов модулей | systemctl list-unit-files |
Отобразить статус модуля по PID процесса | systemctl status PID |
Анализ поведения службы
Дейтвие | Команда | Комментарий |
---|---|---|
Отобразить страницу руководства, ассоциированную с данной службой | systemctl help UNIT |
если указана в конфигурации модуля |
Отобразить статус модуля | systemctl status UNIT |
показывает запущен или остановлен модуль |
Проверить включён ли модуль | systemctl is-enabled UNIT |
Управление состоянием службы. Все в данном разделе требуют прав суперпользователя
Дейтвие | Команда |
---|---|
Запустить модуль | systemctl start UNIT |
Остановить работу модуля | systemctl stop UNIT |
Перезапустить модуль | systemctl restart UNIT |
Дать команду службе перечитать конфигурацию | systemctl reload UNIT |
Перечитать конфигурацию systemd | systemctl daemon-reload |
Настроить автоматический запуск модуля при старте системы | systemctl enable UNIT |
Настроить автоматический запуск модуля при старте системы и сразу запустить его | systemctl enable --now UNIT |
Отключить автоматический запуск модуля при старте системы | systemctl disable UNIT |
Отключить и настроить автоматический запуск модуля | systemctl reenable UNIT |
Управление состоянием системы #
Данные действия надо выполнять от имени суперпользователя
Дейтвие | Команда |
---|---|
Выключить ОС и перезагрузить компьютер | systemctl reboot |
Выключить ОС и обесточить компьютер | systemctl poweroff |
Приостановить работу ОС с сохранением данных в оперативной памяти | systemctl suspend |
Приостановить работу ОС с сохранением данных в разделе подкачки | systemctl hibernate |
Приостановить работу ОС с гибридным сохранением состояния | systemctl hybrid-sleep |
Запуск служб по расписанию #
Ряд служб могут быть приложениями, которые выполняют поставленную задачу:
- Выполняют резервное копирование
- Выполняют обновление ключей безопасности
- Очищают каталоги с журналами
Они не работают постоянно, а выполнив свою задачу, отключаются
Для управления такого рода службами можно добавить таймеры, которые будут выполнять запуск службы согласно некоторому расписанию
Виды таймеров #
systemd поддерживает следующие таймеры:
- Таймеры по расписанию: активируются при наступлении некоторого события по времени
- Монотонные таймеры: выполняют действия через некоторое время после наступления события
Настройка таймера для службы #
- Конфигурационные файлы таймера располагаются рядом с
.service
-файлами службы - Расширение файла с конфигурацией таймера —
.timer
- Название файлов без расширения должны совпадать
- Описание полей находится в man-странице
systemd.timer
Автозапуск таймера #
systemd предоставляет цель timers.target ….