systemd
systemd — диспетчер системы и сервисов (system and service manager) для Linux, известный также как подсистема инициализации (init system). Она предоставляет стандартный способ инициализации и управления процессами на системе
Возможности:
- Системные Юниты (System Units): systemd использует юниты (units) для представления различных элементов системы, таких как службы, точки монтирования, устройства и другие. Файлы юнитов обычно располагаются в директории
/etc/systemd/systemили/usr/lib/systemd/system. - Службы (Services): Для управления службами используются служебные файлы (service units). Эти файлы обычно имеют расширение
.serviceи определяют параметры для службы, такие как исполняемый файл, параметры запуска, зависимости и т.д.
Порядок загрузки systemd:
- Команда systemd загружает свою конфигурацию.
- Команда systemd определяет цель загрузки, которая обычно называется
default.target. - Команда systemd определяет все зависимости для цели загрузки по умолчанию, зависимости зависимостей и т. д.
- Команда systemd активизирует зависимые процессы и цель загрузки.
- После загрузки команда systemd может реагировать на системные события (такие как uevents) и активизировать дополнительные компоненты.
При запуске служб команда systemd не придерживается жесткой последовательности. Как и у других современных версий команды init, процесс загрузки с помощью команды systemd довольно гибок. В большинстве вариантов конфигурации команды systemd намеренно пытаются избегать какой бы то ни было стартовой последовательности, предпочитая использовать другие методы для устранения жестких зависимостей.
Команды управления
systemctl start myservice.service # Запустить службу
systemctl stop myservice.service # Остановить службу
systemctl restart myservice.service # Перезапустить службу
sudo systemctl reload-or-restart myservice.service # Перезапустить конфигурацию или всю службу
systemctl enable myservice.service # Включить службу для автозапуска
sudo systemctl cat sshd.service # Отображает файл модуля
sudo systemctl show apache2.service # Отображает свойства модуля
sudo systemctl show apache2.service -p Description # Конкретное свойство
sudo systemctl edit --full myservice.service # Редактирование модуля
systemctl list-units --type=service # список служб
# Помимо простого отключения автозагрузки приложения systemd позволяет полностью удалить возможность включать модуль — это называется маскировкой юнита.
# Её можно выполнить с помощью команды:
sudo systemctl mask apache2.service
sudo systemctl unmask apache2.service # Снять маскировку
Журналирование journalctl
systemd собирает вывод всех служб в единый системный журнал. Вы можете просматривать журналы с помощью команды journalctl.
Таймеры
systemd может использоваться для запуска задач по расписанию с помощью таймеров (timer units). Файлы таймеров обычно имеют расширение .timer.
[Unit]
Description=Run myservice periodically
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Модули и типы модулей
Одним из самых интересных свойств команды systemd является то, что она не только управляет процессами и службами, но способна также монтировать файловые системы, отслеживать сетевые сокеты, запускать таймеры и многое другое. Каждый тип таких возможностей называется типом модуля, а каждая конкретная способность — модулем. Когда вы задействуете какой-либо модуль, вы активизируете его.
Основные типы модулей:
- Модули служб. Контролируют традиционные демоны служб в системе Unix.
- Модули монтирования. Контролируют присоединение файловых систем.
- Целевые модули. Контролируют другие модули, как правило группируя их.
По умолчанию целью загрузки обычно является целевой модуль, который группирует несколько служб и монтирует модули в качестве зависимостей. В результате довольно легко получить частичное представление о том, что происходит при загрузке системы. Можно даже составить дерево зависимостей с помощью команды systemctl dot.
Зависимости systemd
Чтобы приспособиться к требованиям гибкости и устойчивости к сбоям, команда systemd предлагает огромное количество типов и стилей зависимостей:
- Requires. Жесткие зависимости. При активизации модуля с зависимостью Requires команда systemd пытается активизировать модуль зависимости. Если модуль зависимости дает сбой, то команда systemd деактивизирует зависимый модуль.
- Wants. Зависимости, предназначенные только для активизации. Во время активизации какого-либо модуля команда systemd активизирует его Wants-зависимости, но не обращает внимания, если они дают сбой.
- Requisite. Модули, которые уже должны быть активными. Перед активизацией модуля с зависимостью Requisite команда systemd сначала проверяет состояние зависимости. Если такая зависимость еще не была активизирована, команда systemd дает сбой при активизации модуля с этой зависимостью.
- Conflicts. Противоположные зависимости. При активизации модуля с зависимостью Conflict команда systemd автоматически деактивизирует такую зависимость, если она активна.
Тип зависимостей Wants особенно важен, поскольку он не распространяет ошибки на другие модули. В документации к команде systemd заявлено, что именно таким образом следует по возможности определять зависимости. Это позволит создать гораздо более устойчивую систему, подобную той, которая применяет традиционную команду init.
Зависимости могут быть также подключены «реверсивно». Например, чтобы добавить модуль А в качестве Wants-зависимости для модуля Б, не обязательно добавлять зависимость Wants в конфигурацию модуля Б. Вместо этого можно указать его как WantedBy-зависимость в конфигурации модуля А. То же самое верно и для зависимости RequiredBy. Конфигурация (а также результат) зависимости “By” немного сложнее, чем простое редактирование файла с настройками.
Увидеть зависимости какого-либо модуля можно с помощью команды systemctl. С ее помощью можно также указать тип зависимости, например Wants или Requires:
Порядок следования
Ни один из вариантов синтаксиса, который вы видели, не определяет явным образом порядок следования модулей. По умолчанию активизация модуля с зависимостью Requires или Wants ведет к тому, что команда systemd активизирует одновременно все такие зависимости в качестве первого модуля. Это оптимально, поскольку необходимо запустить по возможности максимальное количество служб, причем максимально быстро, чтобы сократить время загрузки системы. Однако бывают ситуации, когда один модуль должен быть запущен после другого.
Чтобы активизировать модули в определенном порядке, можно использовать следующие модификаторы зависимостей.
- Before. Текущий модуль будет активизирован до указанного модуля или модулей. Например, если в модуле
foo.targetбудет инструкцияBefore=bar.target, команда systemd активизирует модульfoo.targetперед модулемbar.target. - After. Текущий модуль будет активизирован после перечисленного модуля или модулей.
Конфигурация systemd
Файлы конфигурации команды systemd рассеяны по множеству каталогов системы, так что вы, как правило, не сможете найти файлы для всех модулей в одном месте. Однако имеется два основных каталога для конфигурации команды systemd:
- каталог системных модулей (настраивается глобально, обычно это
/usr/lib/systemd/system) и - каталог системной конфигурации (локальные определения, обычно это
/etc/systemd/system).
Во избежание недоразумений следуйте правилу: не вносите изменения в каталог модулей, поскольку ваша система позаботится об этом за вас. Локальные изменения вносите в каталог системной конфигурации. Итак, если вам будет предоставлен выбор между изменениями чего-либо в каталогах /usr и /etc, всегда изменяйте каталог /etc.
Пример модуля sshd
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target
[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
Unit
Это первая обязательная секция. В ней описаны правила взаимодействия с другими службами и указаны метаданные — описание и документация. Эта секция содержит информацию о самом юните, его зависимостях, ограничениях, пользовательских параметрах и т. д. Подробнее:
- Description — описание модуля.
- Documentation — страница руководства man.
- After — после каких демонов и событий нужно запускать модуль. Например, модули веб-серверов запускаются только после сетевых интерфейсов.
- Before Список других юнитов, которые должны быть запущены до этого юнита.
- Requires — сервисы, необходимые для работы юнита
- Wants — сервисы, которые желательно запустить перед стартом модуля
- Conflicts Список других юнитов, с которыми этот юнит конфликтует. Если один из этих юнитов запущен, то этот юнит не будет запущен.
- OnFailure Действие, которое должно быть выполнено при сбое этого юнита.
- StopWhenUnneeded Если установлено в true, то юнит будет остановлен, если он больше не нужен другими запущенными юнитами.
Service
В этой секции необходимо указать, какими командами запускать службу. Определяет настройки и параметры для службы (service), которая запускается и управляется systemd. Эта секция содержит информацию о том, как запускать и контролировать службу.:
- Type — как запускается демон? По умолчанию — simple, то есть служба просто запускается. Notify это примерно то же самое, но в таком случае процесс сообщит диспетчеру, что он готов к работе. Есть также типы forking (после запуска демона родительский процесс завершается) и one-shot (выполняется один раз).
- PIDFile — ссылка на основной процесс
- WorkingDirectory — текущая рабочая директория для запуска команд
- User — пользователь для запуска сервиса
- Group — группа для запуска сервиса
- Environment - Устанавливает переменные среды для процесса службы.
- EnvironmentFile - Загружает переменные среды из указанного файла.
- ProtectSystem - Если установлен в full или strict, то файловая система будет защищена от изменений службой.
- ExecStart — команда для запуска сервиса
- ExecStop — команда для остановки сервиса
- TimeoutSec — время, которое служба ожидает остановки или старта
- Restart — Указывает, должна ли служба перезапускаться в случае аварийного завершения. Возможные значения: always, on-success, on-failure, on-abnormal, on-abort, on-watchdog, on-abort, on-abort
- RestartSec - Задержка перед повторным запуском службы после аварийного завершения.
Install
В этой секции нужно указать, на каком уровне загрузки системы нужно запускать сервис. Секция Install используется для настройки параметров автоматической активации (activation) сервиса при запуске системы. Эта секция определяет зависимости между юнитами, порядок их запуска и другие настройки, связанные с автоматической активацией.
В секции Install вы можете указать следующие параметры:
- WantedBy - Определяет, к какому целевому (target) юнит будет добавлен этот юнит в качестве зависимости. Если этот параметр не указан, то юнит не будет автоматически активироваться при запуске системы. Например, WantedBy=multi-user.target.
- Also - Позволяет добавлять дополнительные цели к параметру WantedBy. Это может быть полезно, если вы хотите, чтобы юнит был активирован не только при запуске определенной цели, но и при запуске других целей. Например, Also=graphical.target.
- RequiredBy - Аналогичен параметру WantedBy, но определяет жесткую зависимость. Если этот параметр указан, то юнит будет обязательно активирован при запуске цели, указанной в RequiredBy.
- Alias - Позволяет создать псевдоним для юнита. Это позволяет создавать альтернативные имена для юнита. Например, Alias=foo.service.
- DefaultInstance - Позволяет задать имя экземпляра по умолчанию, если юнит поддерживает множественные экземпляры.
Примечание: Не все параметры могут использоваться в каждом юните, это зависит от типа юнита и его спецификации.
Цели (targets)
Цели — специальные файлы модулей, которые описывают состояние системы. Они определяются по суффиксу .target. В основном эти файлы используются для группировки других юнитов. Например, в системе существует цель swap.target, которая указывает, что файл подкачки готов к использованию. Модули, которым нужен этот файл могут указывать его в своей спецификации.
Диспетчер systemd позволяет изолировать цели — то есть запустить все юниты, связанные с этой целью, и остановить все остальные. Чтобы случайно не остановить важные для системы процессы, сначала посмотрите на зависимости цели, которую изолируете, с помощью команды list-dependencies:
sudo systemctl list-dependencies multi-user.target
# Если все перечисленные модули можно завершить, цель можно изолировать:
sudo systemctl isolate multi-user.target
Существуют цели, которые используются для важных событий, например, перезагрузки системы. Для того, чтобы пользователю было проще оперировать этими событиями, созданы ярлыки systemctl:
systemctl rescueвводит систему в режим восстановления;systemctl haltосуществляет изоляцию цели halt.targetsystemctl poweroffготовит систему к завершению работы (то же самое, что команда poweroff)systemctl rebootперезапускает систему (в точности то же самое, что команда reboot)
Основные команды systemctl
| Действие | Команда | Примечание |
|---|---|---|
| Анализ состояния системы | ||
| Состояние системы | $ systemctl status |
|
| Список запущенных юнитов | $ systemctl или $ systemctl list-units |
|
| Список юнитов, запустить которые не удалось | $ systemctl --failed |
|
| Список установленных файлов юнитов | $ systemctl list-unit-files |
|
| Информация о процессе по его PID | $ systemctl status pid |
cgroup slice, занимаемая память и родительский процесс |
| Состояние юнита | ||
| Страница руководства юнита | $ systemctl help юнит |
если юнит её предоставляет |
| Состояние юнита | $ systemctl status юнит |
в т. ч. работает ли он в данный момент |
| Проверить, добавлен ли юнит в автозапуск | $ systemctl is-enabled юнит |
|
| Запуск, перезапуск, перезагрузка юнита | ||
| Незамедлительно запустить юнит | # systemctl start юнит |
|
| Незамедлительно остановить юнит | # systemctl stop юнит |
|
| Перезапустить юнит | # systemctl restart юнит |
|
| Перезагрузить юнит с новыми настройками | # systemctl reload юнит |
|
| Перезагрузить настройки systemd | # systemctl daemon-reload |
сканировать систему на наличие новых или изменённых юнитов |
| Включение юнита (автозапуск) | ||
| Включить юнит, добавив его в автозапуск | # systemctl enable юнит |
|
| Включить юнит и сразу запустить | # systemctl enable --now юнит |
|
| Отключить запуск юнита при загрузке | # systemctl disable юнит |
|
| Включить юнит заново | # systemctl reenable юнит |
т.е. отключить и снова включить |
| Маскировка юнита | ||
| Замаскировать юнит, сделав невозможным его запуск | # systemctl mask юнит |
|
| Снять маскировку юнита | # systemctl unmask юнит |