Skip to content

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:

  1. Команда systemd загружает свою конфигурацию.
  2. Команда systemd определяет цель загрузки, которая обычно называется defa­ult.target.
  3. Команда systemd определяет все зависимости для цели загрузки по умолчанию, зависимости зависимостей и т. д.
  4. Команда systemd активизирует зависимые процессы и цель загрузки.
  5. После загрузки команда systemd может реагировать на системные события (такие как uevents) и активизировать дополнительные компоненты.

При запуске служб команда systemd не придерживается жесткой последователь­ности. Как и у других современных версий команды init, процесс загрузки с помо­щью команды systemd довольно гибок. В большинстве вариантов конфигурации команды systemd намеренно пытаются избегать какой бы то ни было стартовой последовательности, предпочитая использовать другие методы для устранения жестких зависимостей.

Команды управления

systemctl cmd
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.

journalctl
journalctl -u myservice.service

Таймеры

systemd может использоваться для запуска задач по расписанию с помощью таймеров (timer units). Файлы таймеров обычно имеют расширение .timer.

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” немного сложнее, чем простое редактирование файла с настройками.

Увидеть зависимости какого-либо модуля можно с помощью команды sys­temctl. С ее помощью можно также указать тип зависимости, например Wants или Requires:

systemctl show
systemctl show -p type unit

Порядок следования

Ни один из вариантов синтаксиса, который вы видели, не определяет явным образом порядок следования модулей. По умолчанию активизация модуля с зависимостью 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
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:

isolate target
sudo systemctl list-dependencies multi-user.target
# Если все перечисленные модули можно завершить, цель можно изолировать:
sudo systemctl isolate multi-user.target

Существуют цели, которые используются для важных событий, например, перезагрузки системы. Для того, чтобы пользователю было проще оперировать этими событиями, созданы ярлыки systemctl:

  • systemctl rescue вводит систему в режим восстановления;
  • systemctl halt осуществляет изоляцию цели halt.target
  • systemctl 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 юнит