Перейти к содержимому

Systemd linux что это

  • автор:

Использование systemd для управления службами Linux с помощью WSL

подсистема Windows для Linux (WSL) теперь поддерживает системный, системный и диспетчер служб, используемый многими популярными дистрибутивами Linux, такими как Ubuntu, Debian и многое другое. (Что такое система?).

Системная система init по умолчанию недавно изменилась с SystemV, с системным значением по умолчанию для текущей версии Ubuntu , которая будет установлена с помощью wsl —install команды по умолчанию. Дистрибутивы Linux, отличные от текущей версии Ubuntu, по-прежнему могут использовать инициализацию WSL, аналогичную инициализации SystemV. Сведения об изменении системы см. в разделе «Как включить системные».

Что такое система в Linux?

Согласно systemd.io: «система представляет собой набор основных стандартных блоков для системы Linux. Он предоставляет систему и диспетчер служб, который выполняется как PID 1 и запускает остальную часть системы».

В первую очередь система и диспетчер служб содержат такие функции, как запуск daemons, подключение и обслуживание точек автоматического подключения, поддержка моментальных снимков и отслеживание процессов с помощью групп управления Linux.

Как включить систему?

Systemd теперь используется по умолчанию для текущей версии Ubuntu , которая будет установлена с помощью wsl —install команды по умолчанию.

Чтобы включить систему для любых других дистрибутивов Linux, работающих в WSL 2 (изменение по умолчанию с помощью systemv init):

  1. Убедитесь, что версия WSL — 0.67.6 или более позднюю. (Чтобы проверка, выполните команду wsl —version . Чтобы обновить, запустить wsl —update или скачать последнюю версию из Microsoft Store.)
  2. Откройте командную строку для дистрибутива Linux и введите cd / для доступа к корневому каталогу, а затем ls перечислите файлы. Вы увидите каталог с именем «etc», содержащий файл конфигурации WSL для дистрибутива. Откройте этот файл, чтобы сделать обновление с помощью текстового редактора Nano, введя следующее: nano /etc/wsl.conf
  3. Добавьте эти строки в wsl.conf файл, который теперь открыт для изменения инициализации, используемой для systemd:

[boot] systemd=true 

Enable systemd on WSL 2

После перезапуска дистрибутива Linux система будет запущена. Вы можете подтвердить с помощью команды: systemctl list-unit-files —type=service которая будет отображать состояние всех служб, связанных с дистрибутивом Linux.

Узнайте больше о конфигурации расширенных параметров в WSL, включая разницу между wsl.conf файлами конфигурации (для конкретного дистрибутива) и .wslconfig (глобальными) файлами конфигурации, обновлением параметров автоматического отключения и т. д.

Видео с системной демонстрацией

Корпорация Майкрософт сотрудничает с Каноническим, чтобы обеспечить системную поддержку WSL. См. статью Craig Loewen (PM для WSL в Майкрософт) и Оливер Смит (PM для Ubuntu в WSL в Каноническом) объявит системную поддержку и показать некоторые демонстрации того, что это позволяет.

  • Объявление блога о поддержке systemd
  • Учебники Оливера на основе этих демонстраций в блоге Ubuntu: «Использование оснастки для создания экземпляра Nextcloud в минутах на WSL», «Управление веб-проектами с помощью LXD» и «Запуск Эхо-бота .Net в качестве системной службы в Ubuntu WSL»
  • Демонстрация микрок8s Craig на GitHub

Примеры системы

Ниже приведены несколько примеров приложений Linux, которые зависят от системных приложений:

  • snap: система упаковки программного обеспечения и развертывания, разработанная каноническим для операционных систем, использующих ядро Linux и системную инициализацию. Пакеты называются «snaps», средство командной строки для создания оснастки называется Snapcraft, центральный репозиторий, где оснастки можно скачать или установить, называется «Snap Store», а управляющая программа, необходимая для запуска оснастки (скачивание из магазина, подключение к месту, ограничение и запуск приложений из них) называется «snapd». Вся система иногда называется «snappy». Попробуйте выполнить команду: snap install spotify или snap install postman .
  • microk8s: open-source, low-ops, минимальный рабочий Kubernetes, который автоматизирует развертывание, масштабирование и управление контейнерными приложениями. Следуйте инструкциям по установке MicroK8s в WSL2, проверка руководстве по началу работы или просмотрите видео в Kubernetes в Windows с microK8s и WSL 2.
  • systemctl: служебная программа командной строки, используемая для управления системой и проверки системных служб, а также для взаимодействия со службами в дистрибутиве Linux. Попробуйте выполнить команду: systemctl list-units —type=service чтобы узнать, какие службы доступны и их состояние.

В нескольких связанных руководствах показано, как использовать системные методы:

  • Общие сведения и использование Systemd
  • Systemd Essentials: работа со службами, единицами и журналом
  • Как песочница процессов с системой в Ubuntu 20.04

Как включить системную архитектуру WSL?

Включение поддержки системных необходимых изменений в архитектуре WSL. Так как для системы требуется PID 1, процесс инициализации WSL, запущенный в дистрибутиве Linux, становится дочерним процессом системы. Поскольку процесс инициализации WSL отвечает за предоставление инфраструктуры для обмена данными между компонентами Linux и Windows, изменение этой иерархии требует переосмысления некоторых предположений, сделанных с помощью процесса инициализации WSL. Необходимо внести дополнительные изменения, чтобы обеспечить чистое завершение работы (так как завершение работы контролируется системой сейчас) и обеспечить совместимость с WSLg, компонент WSL, на котором выполняются графические пользовательские интерфейсы Linux (GUIS) или приложения Linux, которые отображаются в окнах, а не в командной строке.

Важно также отметить, что при этих изменениях системные службы не будут поддерживать экземпляр WSL. Экземпляр WSL будет оставаться в живых таким же образом, как и в этом обновлении, который можно узнать больше в этой записи блога о поддержке фоновых задач с 2017 года.

Что такое systemd: примеры использования

systemd — подсистема инициализации и управления службами в Linux, фактически традиционную подсистему init. systemctl — основной инструмент управления systemd.

Systemd опирается на современные Linux- технологии: cgroups, AutoFS, D-Bus, и при этом совместим с исторически устоявшимися механизмами: init- скриптами, стандартными командами shutdown, poweroff и т.п. Предоставляемый systemd функционал позволяет заменить не только систему инициализации, но и ряд других подсистем, в частности: cron, (x)inetd, xdm/kdm/gdm/…, частично даже SELinux как правильно отключить!! Для начинающих.

Модули Systemd

Чтобы понять разницу между всеми этими “модулями” или “юнитами”, надо вспомнить, что systemd, как и все остальное в Linux, является файлом. И все systemd-сущности являются разными файлами (например systemd службы хранят конфигурации в файле с расширением .service, а сокеты — .socket и т.д.). Systemd, если рассматривать как демон, управляет другими демонами и является первым демоном, который запускается во время загрузки ОС.

Базовым элементом systemd являются модули (units). Модули имеют имя и тип. Каждый модуль может требовать для своей работы другие модули, конфликтовать с модулями, запускаться только после или до определенного модуля (директивы конфигурации Requires, Conflicts, Before, After, Wants). Поскольку их конфигурация обычно загружается из файловой системы — названия модулей на самом деле представляют собой имена файлов. Например: модуль avahi.service считывается из конфигурационного файла с тем же именем и естественно, что он реализует работу с демоном Avahi. Из типов модулей определены:

service. Обычный демон, поддерживающий операции start, stop, restart, reload. Может быть представлен родным (native) файлом конфигурации systemd или System V init- скриптом. Для совместимости с SysV в systemd помимо собственных файлов конфигурации для различных сервисов имеется возможность чтения классических скриптов инициализации SysV, а также она умеет разбирать заголовок LSB, если он существует. /etc/init.d является, следовательно, не более, чем просто еще одним источником конфигурации.

socket. При обращении к сокету генерируется событие, для которого можно настроить обработчик. Например, автоматически запускать определенные службы при обращении к заданному сокету. В этом отношении systemd похож на давно известный (x)inetd, однако при этом поддерживает unix domain сокеты и FIFO.

device. Отметив нужные устройства в конфигурации udev, впоследствии можно использовать такие события, как появление и удаление устройства, в качестве событий systemd, назначив на них обработчики. Например, при появлении устройства bluetooth будет запущена соответствующая служба.

Path unit (файловый путь .path) — используется для наблюдения за файлом или директорий на предмет наличия определенного события, и если это событие происходит, то выполняется запуск service-юнита с таким же именем (если не указан другой). Тут стоит привести более конкретный пример, чтобы было понятнее:

[Unit] Description=Smotrim za izmeneniyami v faile [Path] PathChanged=/home/some_path/some_file Unit=changes_applied.service [Install] WantedBy=multi-user.target

Он описывает следующее: Вы наблюдаете за файлом /home/some_path/some_file, и если он меняется, то запускается сервис, определенный в Unit=changes_applied.service.

mount. Модуль реализует точку монтирования в файловой системе. systemd контролирует все точки монтирования (их подключение и отключение), а также может быть использована для монтирования и размонтирования отдельных файловых систем. Файл /etc/fstab используется как дополнительный источник конфигурации для них, в целях обратной совместимости.

automount. Для помеченных таким образом точек монтирования, монтирование выполняется только при обращении к ним.

target. Более гибкий аналог уровней исполнения (runlevels), используемых в System V init. Представляет собой группу служб, объединенных по функциональному назначению. Например, multi-user.target идентичен runlevel 5, а bluetooth.target приводит к инициализации подсистемы bluetooth.

snapshot — во многом похож на target. Позволяет «запомнить» существующую конфигурацию units (запущенных служб, открытых сокетов, смонтированных ФС) с тем, чтобы в дальнейшем восстановить это состояние. Позволяет, например, перейти в emergency shell (сейчас это init 1), а затем полностью восстановить набор запущенных служб. Второй вариант его использования — поддержка режима suspend: достаточно много сервисов не могут корректно работать с этой системой, и зачастую их лучше остановить перед засыпанием, а потом просто запустить.

Расположение файлов сервиса Systemd

Службы Systemd делят на две категории — системные службы, запускаемые от имени суперпользователя. Чтобы ими управлять, необходимо использовать sudo. Вторая категория — пользовательские службы, запускаемые от имени конкретного пользователя. Этот пользователь может иметь полный контроль без sudo.

Файлы системных служб находятся в

/usr/lib/systemd/system /lib/systemd/system /etc/systemd/system

Например, в примере ниже видно что физически файл находится в /usr/lib/systemd/system/, а из других каталогов просто ссылки

stat /etc/systemd/system/multi-user.target.wants/postgresql-13.service File: ‘/etc/systemd/system/multi-user.target.wants/postgresql-13.service’ ->/usr/lib/systemd/system/postgresql-13.service’

Файлы пользовательских служб можно найти в:

/usr/lib/systemd/user /lib/systemd/user /etc/systemd/user $USER/.config/systemd/user

Причем файлы сервисов поставляемые с пакетами обычно находятся в каталогах /lib и /usr/lib, а в /etc/ расположены модифицированные файлы юнитов переопределяющие стандартные настройки

Стандартное использования systemd (systemctl)

systemctl — основной инструмент управления systemd.

Запуск, останов и просмотр статуса какой-либо службы происходит посредством команд. В командах используется служба nginx:

systemctl start nginx systemctl stop nginx systemctl status nginx

Перезапуск командой

systemctl restart nginx

Проверить добавлена ли уже служба nginx в автозагрузку:

systemctl is-enabled nginx

Для добавления сервиса в автозагрузку используется

systemctl enable nginx

Подкоманда enable не запускает службу, а только помечает ее для автоматического запуска при загрузке. Чтобы включить и запустить службу одновременно, используйте параметр –now

systemctl enable --now nginx

Чтобы убрать приложение из автозапуска, соответственно disable. Отключиv службу apparmor это аналог SELinux как правильно отключить!! Для начинающих.

systemctl disable apparmor

В строке Loaded видим ключ enabled.

systemctl status apparmor Loaded: loaded (/etc/init.d/apparmor; bad; vendor preset: enabled)

Можно также «замаскировать» сервис — то есть, лишить модуль возможности запускаться. systemctl mask / systemctl unmask: запрещает (разрешает) все и любые попытки запуска рассматриваемого модуля (либо вручную, либо как зависимость любого другого модуля, включая зависимости цели загрузки по умолчанию).

systemctl mask nginx

Посмотреть дерево зависимостей — от каких процессов зависит cron.

systemctl list-dependencies nginx

Вывести список всех процессов

systemctl

Список запущенны юнитов, без ключа -а будут показаны только те службы которые сейчас работают

systemctl -t service -a или так systemctl --type=service -a

Список запущенны юнитов в Linux.

Список всех имеющихся модулей в системе покажет команда

# systemctl list-units

Просмотр статуса службы, например syslog

# systemctl status syslog.target syslog.target - Syslog Loaded: loaded (/lib/systemd/system/syslog.target; static) Active: active since Thu, 01 Mar 2012 16:18:25 +0000; 18h ago

Рассмотрим модуль файла планировщика cron

Файл модуля cron находится по адресу /lib/systemd/system/cron.service.

[Unit] - директива, указывающая systemd, что эта часть файла является описательной, указывает параметры запуска и т.д. Description=Regular background program processing daemon - описание юнита Documentation=man:cron(8) - указание пути к документации After=remote-fs.target nss-user-lookup.target - параметр, указывающий, что данный юнит должен запускаться после (after) модуля, указанного справа от "=". [Service] - блок конфигурации юнита EnvironmentFile=/etc/default/cron - файл окружения ExecStart=/usr/sbin/cron -f $EXTRA_OPTS - команда для старта IgnoreSIGPIPE=false - параметр для игнорирования SIGPIPE сигнала (SIGPIPE — сигнал, посылаемый процессу при записи в соединение (пайп, сокет) при отсутствии или обрыве соединения с другой (читающей) стороной.) KillMode=process - указывает, как "убивать" процесс. Restart=on-failure - указание, когда необходимо перезагружать сервис. [Install] - блок, описывающий информацию об установке юнита (нужен для команд systemctl enable/disable) WantedBy=multi-user.target - данная директива, является наиболее распространенным способом определения того, как юнит должен быть включен, от чего зависит.

Пример: Создадим модуль запуска самописного скрипта

Создайте скрипт, который вы хотите запускать и дать файлу права на исполнение (chmod +x). В этом примере создан тестовый файл /usr/sbin/love.sh, с таким содержимым:

#!/bin/bash while true do printf "Make love,not war\n" sleep 60 done

Создайте файл /etc/systemd/system/love.service на вашем тестовом Debian:

[Unit] Description=My first super program [Service] #fail ExecStop=/bin/kill -9 $MAINPID #StandardOutput=null #success ExecStart=/bin/bash /usr/sbin/love.sh [Install] WantedBy=multi-user.target

Все готово, теперь для запуска введите:

systemctl daemon-reload systemctl start love.service

Для проверки того что все работает, убедитесь что служба работает, командой:

systemctl status love.service

И также проверьте системный журнал syslog на наличие строки «Started My first super program», командой:

tail -f /var/log/syslog Dec 6 23:32:34 dark systemd[1]: Started My first super program. Dec 6 23:32:34 dark bash[2672]: Make love,not war Dec 6 23:32:39 dark bash[2672]: Make love,not war

Если раскомментировать строку StandardOutput=null, то вывод нашего скрипта love.sh (Make love,not war) перестанет писаться в файл syslog.

Пример: Автозагрузка контейнеров Docker в ОС при помощи systemd

Ваш сервер перезагрузился и все запущенные контейнеры Docker остановились. Чтобы избавиться от необходимости вручную запускать их, можно настроить автозапуск контейнеров. Для этого следует создать текстовые файлы со специальным форматом для сервиса systemd. Рассмотрим пример автозапуска контейнера my-db, для этого создадим файл

nano /etc/systemd/system/my-db.service

[Unit] секция описывает метаданные и зависимости службы.
Description предоставляет описание службы.
Requires и After указывают, что служба зависит от docker.service.

ExecStartPre используется для остановки и удаления контейнера, если он уже существует, перед запуском. Вы можете настроить эти команды в соответствии с вашими требованиями.

ExecStart указывает команду для запуска вашего контейнера.
ExecStop определяет, как остановить контейнер.

[Install] секция указывает, когда служба должна быть запущена. В этом примере служба настроена на запуск при загрузке в многопользовательском режиме.

[Unit] Description=My docker container my-db-container # для успешного запуска нашего контейнера сначала должна быть запущена служба Docker Requires=docker.service After=docker.service [Service] # Если служба завершает работу всегда перезапускать её Restart=always ExecStartPre=-/usr/bin/docker stop ExecStartPre=-/usr/bin/docker rm my-db-container ExecStart=/usr/bin/docker run --name my-db-container my-docker-image ExecStop=/usr/bin/docker stop my-db-container [Install] WantedBy=multi-user.target

После этого остается перезапустить демон systemcmd и включить автозагрузку контейнера mydb, набрав в терминале поочередно команды:

systemctl daemon-reload systemctl start my-db.service systemctl enable my-db.service

Использование таймеров systemd вместо заданий cron

Systemd-таймеры и задания cron, могут, в заданное время, вызывать выполнение различных действий в системе. Например — запуск скриптов командной оболочки или программ. Таймеры могут срабатывать, например, раз в день, причём — только по понедельникам. Ещё один пример — срабатывание таймера каждые 15 минут в рабочее время (с 8 утра до 6 вечера). Но таймеры systemd могут кое-что такое, что недоступно заданиям cron. Например, таймер может вызвать скрипт или программу через заданное время после некоего события. Таким событием может быть загрузка системы или запуск systemd, завершение предыдущей задачи или даже завершение работы сервиса, вызванного ранее по таймеру.

Получить список всех таймеров в системе

systemctl status *timer

Таймеры systemd обладают другими возможностями, которых нет у заданий cron, «одноразовых» или повторяющихся, которые вызываются только с привязкой к реальному времени и к реальным датам. Таймеры systemd можно настроить так, чтобы они вызывались бы на основании изменения состояния других юнитов systemd. Например, таймер можно настроить так, чтобы он срабатывал бы через заданное время после загрузки системы, после входа в неё пользователя, или через заданное время после активации определённого сервиса. Такие таймеры называют монотонными (monotonic). Эти таймеры сбрасываются после каждой перезагрузки системы.

Таймеры systemd можно использовать для решения тех же задач, которые решают с помощью заданий cron. Но systemd даёт больше гибкости в плане настройки календарных и монотонных таймеров.

systemd (Русский)

Состояние перевода: На этой странице представлен перевод статьи systemd. Дата последней синхронизации: 12 июля 2021. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

systemd — набор базовых компонентов Linux-системы. Представляет собой менеджер системы и служб, который выполняется как процесс с PID 1 и запускает остальную часть системы. systemd обеспечивает возможности агрессивной параллелизации, сокетную и D-Bus активацию для запуска служб, запуск демонов по запросу, отслеживание процессов с помощью контрольных групп Linux, обслуживание точек (авто)монтирования, а также предлагает развитую транзакционную логику управления службами на основе зависимостей. systemd поддерживает сценарии инициализации SysV и LSB и работает как замена sysvinit. Среди прочих элементов и функций — демон журнала, утилиты управления базовой конфигурацией системы (имя хоста, дата, языковой стандарт), ведение списков вошедших в систему пользователей, запущенных контейнеров, виртуальных машин, системных учётных записей, каталогов и настроек времени выполнения, а также демоны для управления несложными сетевыми конфигурациями, синхронизации времени по сети, пересылки журналов и разрешения имён.

Примечание: Причины перехода Arch на systemd подробно объяснены на форуме.

Основы использования systemctl

Главная команда для работы с systemd — systemctl. Она позволяет (среди прочего) отлеживать состояние системы и управлять системой и службами. Подробнее см. systemctl(1) .

  • Для управления systemd на удалённой машине команды необходимо выполнять с ключом -H пользователь@хост . Соединение с удалённым процессом systemd будет установлено через SSH.
  • В Plasma для systemctl разработан графический интерфейс systemd-kcmAUR . После установки соответствующий модуль появится в разделе System administration.

Использование юнитов

Юнитами могут быть, например, службы (.service), точки монтирования (.mount), устройства (.device) или сокеты (.socket).

При работе с systemctl обычно необходимо указывать полное имя юнита с суффиксом, например, sshd.socket . Существует несколько возможных сокращений:

  • Если суффикс не указан, systemctl предполагает, что это .service. Например, netctl равнозначно netctl.service .
  • Точки монтирования автоматически преобразуются в юнит .mount. Например, /home равнозначно home.mount .
  • Аналогично точкам монтрования, имена устройств автоматически преобразуются в юнит .device. Например, /dev/sda2 равнозначно dev-sda2.device .

Примечание: Некоторые юниты содержат в названии символ @ (вида название@строка.service ). Это т.н. экземпляры юнита-шаблона, настоящее имя которого не содержит части строка (т.е. имеет вид название@.service ). строка называется идентификатором экземпляра и передаётся юниту-шаблону в качестве аргумента при вызове systemctl: в файле юнита идентификатор заменит спецификатор %i .

Если говорить точнее, systemd сначала попытается найти юнит, название которого полностью совпадёт с название@строка.суффикс , и лишь в случае неудачи создаст экземпляр шаблона название@.суффикс . Тем не менее, такие «конфликты» довольно редки, так как по соглашению символ @ должен использоваться только в названиях юнитов-шаблонов. Также помните, что вызвать юнит-шаблон без идентификатора экземпляра не получится, поскольку в этом случае нечего будет подставить вместо спецификатора %i .

  • Большинство команд ниже также будут работать, если указать несколько юнитов; подробнее см. systemctl(1) .
  • Опция —now в командах enable , disable и mask соответственно запускает, останавливает или маскировует указанный юнит сразу при выполнении команды, а не после перезагрузки.
  • Пакеты могут содержать собственные юниты для различных целей. Если вы только что установили пакет, выполните pacman -Qql название_пакета | grep -Fe .service -e .socket , чтобы их найти.
Действие Команда Примечание
Анализ состояния системы
Состояние системы $ systemctl status
Список запущенных юнитов $ systemctl или
$ systemctl list-units
Список юнитов, запустить которые не удалось $ systemctl —failed
Список установленных файлов юнитов 1 $ 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 2 # systemctl daemon-reload сканировать систему на наличие новых или изменённых юнитов
Включение юнита (автозапуск)
Включить юнит, добавив его в автозапуск # systemctl enable юнит
Включить юнит и сразу запустить # systemctl enable —now юнит
Отключить запуск юнита при загрузке # systemctl disable юнит
Включить юнит заново 3 # systemctl reenable юнит т.е. отключить и снова включить
Маскировка юнита
Замаскировать юнит, сделав невозможным его запуск 4 # systemctl mask юнит
Снять маскировку юнита # systemctl unmask юнит
  1. В руководстве systemd.unit(5) § UNIT FILE LOAD PATH приведён перечень каталогов, в которых могут храниться файлы юнитов.
  2. Перезагружаются только настройки systemd, но не юнитов. Для юнитов необходимо использовать команду reload.
  3. Например, если раздел [Install] изменился с момента последнего включения.
  4. Как вручную, так и по зависимости, что делает маскировку несколько опасной.

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

Для управления питанием от имени непривилегированного пользователя необходим polkit. Если вы находитесь в локальном пользовательском сеансе systemd-logind и нет других активных сеансов, приведенные ниже команды сработают, даже если будут выполнены не от root. В противном случае (например, другой пользователь вошел в систему через tty) systemd автоматически запросит у вас пароль суперпользователя.

Действие Команда
Завершить работу и перезагрузить систему $ systemctl reboot
Завершить работу и выключить компьютер $ systemctl poweroff
Перевести систему в ждущий режим $ systemctl suspend
Перевести систему в спящий режим $ systemctl hibernate
Перевести систему в режим гибридного сна (suspend-to-both) $ systemctl hybrid-sleep

Написание файлов юнитов

Синтаксис файлов юнитов systemd (см. systemd.unit(5) ) вдохновлён desktop-файлами XDG Desktop Entry Specification, а они, в свою очередь, основаны на синтаксисе файлов .ini Microsoft Windows. Файлы юнитов загружаются из целого ряда мест (команда systemctl show —property=UnitPath выведет полный список), ключевыми из которых являются следующие (в порядке увеличения приоритета):

  • /usr/lib/systemd/system/ : юниты, добавленные пакетами при установке;
  • /etc/systemd/system/ : юниты, созданные системным администратором.
  • При запуске systemd в пользовательском режиме пути загрузки будут отличаться.
  • Названия юнитов могут содержать только буквы и цифры ASCII-набора, подчёркивания и точки. Другие символы должны быть экранированы в C-стиле («\x2d») или использоваться исключительно в рамках определённой семантики (‘@’, ‘-‘). Подробнее см. systemd.unit(5) и systemd-escape(1) .

При создании собственных юнитов за образец можно взять юниты установленных пакетов или примеры из systemd.service(5) § EXAMPLES .

Совет: Комментарии в файлах юнитов должны начинаться с символа # и размещаться на отдельной строке. Не используйте комментарии в конце строки, после параметров systemd, иначе юнит не будет работать.

Обработка зависимостей

В systemd зависимости определяются правильным построением файлов юнитов. Простой пример — юниту A требуется, чтобы юнит B был запущен перед запуском самого юнита A. Для этого добавьте строки Requires=B и After=B в раздел [Unit] юнит-файла A. Если зависимость является необязательной, укажите Wants=B и After=B соответственно. Обратите внимание, что Wants= и Requires= не подразумевают After= . Если After= не указать, то юниты будут запущены параллельно.

Зависимости обычно указываются для служб, но не для целей. Так, цель network.target будет «подтянута» ещё на этапе настройки сетевых интерфейсов одной из соответствующих служб, и можно спокойно указывать эту цель как зависимость в пользовательской службе, поскольку network.target будет запущена в любом случае.

Типы служб

Службы различаются по типу запуска, и это следует учитывать при написании юнитов. Тип определяется параметром Type= в разделе [Service] :

  • Type=simple (по умолчанию): systemd запустит эту службу незамедлительно. Процесс при этом не должен разветвляться (fork). Если после данной службы должны запускаться другие, то этот тип использовать не стоит (исключение — служба использует сокетную активацию).
  • Type=forking : systemd считает службу запущенной после того, как процесс разветвляется с завершением родительского процесса. Используется для запуска классических демонов за исключением тех случаев, когда в таком поведении процесса нет необходимости. Укажите параметр PIDFile= , чтобы systemd мог отслеживать основной процесс.
  • Type=oneshot : удобен для сценариев, которые выполняют одно задание и завершаются. Если задать параметр RemainAfterExit=yes , то systemd будет считать процесс активным даже после его завершения.
  • Type=notify : идентичен параметру Type=simple , но с уточнением, что демон пошлет systemd сигнал готовности. Реализация уведомления находится в библиотеке libsystemd-daemon.so.
  • Type=dbus : служба считается находящейся в состоянии готовности после появления указанного BusName в системной шине DBus.
  • Type=idle : systemd отложит выполнение двоичного файла службы до окончания запуска остальных («более срочных») задач. В остальном поведение аналогично Type=simple .

Редактирование файлов юнитов

Не стоит редактировать юнит-файлы пакетов напрямую, так как это приведёт к конфликтам с pacman. Есть два безопасных способа редактирования: создать новый файл, который полностью заменит оригинальный, или создать drop-in файл, который будет применяться поверх оригинального юнита. В обоих случаях после редактирования необходимо перезагрузить юнит, чтобы изменения вступили в силу. Это выполняется либо путем редактирования блока с помощью команды systemctl edit , которая автоматически перезагружает юнит, либо перезагрузкой всех юнитов командой:

# systemctl daemon-reload
  • С помощью systemd-delta можно узнать, какие файлы юнитов были переопределены и что конкретно было изменено.
  • Команда systemctl cat юнит позволит просмотреть содержимое файла юнита и связанных с ним drop-in сниппетов.
Замещение файла юнита

Чтобы полностью заместить файл юнита /usr/lib/systemd/system/юнит , создайте файл с таким же именем /etc/systemd/system/юнит и включите заново юнит для обновления символических ссылок.

# systemctl edit --full юнит 

Эта команда откроет файл /etc/systemd/system/юнит в текстовом редакторе (если файл ещё не существует, будет скопирован оригинал) и автоматически перезагрузит юнит после завершения редактирования.

Примечание: Новые изменённые юниты продолжат работать даже после того, как pacman обновит оригинальные юниты в будущем. Это может усложнить обслуживание системы, поэтому предпочтительнее использовать подход, описанный в следующем разделе.

Drop-in файлы

Чтобы создать drop-in файл для /usr/lib/systemd/system/юнит , создайте каталог /etc/systemd/system/юнит.d/ и поместите в него файлы .conf с добавленными или изменёнными опциями. systemd будет анализировать эти файлы и применять их поверх оригинального юнита.

Самый простой способ — использовать команду:

# systemctl edit юнит 

Команда откроет /etc/systemd/system/юнит.d/override.conf в текстовом редакторе (файл будет создан, если его ещё нет) и автоматически перезапустит юнит после завершения редактирования.

Примечание: Не все опции могут быть заменены в drop-in файле. Например, для изменения опции Conflicts= придётся создать полную замену файла юнита (см. предыдущий раздел).

Откат изменений

Отменить все изменения, сделанные с помощью systemctl edit , можно командой:

# systemctl revert юнит 
Примеры

Например, если вы просто хотите добавить дополнительную зависимость к юниту, можно создать следующий файл:

/etc/systemd/system/юнит.d/customdependency.conf
[Unit] Requires=новая зависимость After=новая зависимость

Другой пример: для замены ExecStart в юните (кроме типа oneshot ) создайте следующий файл:

/etc/systemd/system/юнит.d/customexec.conf
[Service] ExecStart= ExecStart=новая команда

Обратите внимание, что ExecStart необходимо очистить перед присвоением нового значения [1]. Это относится ко всем параметрам, которые позволяют прописать несколько значений, вроде OnCalendar в таймерах.

Пример настройки автоматического перезапуска службы:

/etc/systemd/system/юнит.d/restart.conf
[Service] Restart=always RestartSec=30

Цели

Systemd использует юнит типа цель (target) для группировки юнитов по зависимостям и в качестве стандартизированных точек синхронизации. Они выполняют ту же задачу, что и уровни запуска, но действуют немного по-другому. Каждая цель имеет имя, а не номер, и предназначена для конкретных задач; несколько целей могут быть активны одновременно. Некоторые цели реализованы путём наследования служб из других целей с добавлением собственных. В systemd также имеются цели, имитирующие общие уровни запуска SystemVinit, поэтому вы можете переключаться между целями, используя привычную команду telinit RUNLEVEL .

Получение информации о текущих целях

В systemd для этого предназначена следующая команда (заменяющая runlevel ):

$ systemctl list-units --type=target

Создание пользовательской цели

Уровни запуска, имеющие определённое значение в sysvinit (0, 1, 3, 5 и 6), один в один соответствуют конкретным целям systemd. К сожалению, не существует хорошего способа сделать то же самое для пользовательских уровней 2 и 4. Их использование предполагает, что вы создаёте новый юнит-цель с названием /etc/systemd/system/цель , который берет за основу один из существующих уровней запуска (взгляните, например, на /usr/lib/systemd/system/graphical.target ), создаёте каталог /etc/systemd/system/цель.wants , а после этого — символические ссылки на те службы из каталога /usr/lib/systemd/system/ , которые вы хотите включить при загрузке.

Соответствие уровней SysV целям systemd

Уровнень запуска SysV Цель systemd Примечания
0 runlevel0.target, poweroff.target Выключение системы
1, s, single runlevel1.target, rescue.target Однопользовательский уровень запуска
2, 4 runlevel2.target, runlevel4.target, multi-user.target Уровни запуска, определенные пользователем/специфичные для узла. По умолчанию соответствует уровню запуска 3
3 runlevel3.target, multi-user.target Многопользовательский режим без графики. Пользователи, как правило, входят в систему при помощи множества консолей или через сеть
5 runlevel5.target, graphical.target Многопользовательский режим с графикой. Обычно эквивалентен запуску всех служб на уровне 3 и графического менеджера входа в систему
6 runlevel6.target, reboot.target Перезагрузка
emergency emergency.target Аварийная оболочка

Изменение текущей цели

В systemd цели доступны посредством целевых юнитов. Вы можете переключать их такой командой:

# systemctl isolate graphical.target

Данная команда только изменит текущую цель и не повлияет на следующую загрузку системы. Она соответствует командам Sysvinit вида telinit 3 и telinit 5 .

Изменение цели загрузки по умолчанию

Стандартная цель — default.target , которая по умолчанию ссылается на graphical.target (примерно соответствующего прежнему уровню запуска 5).

Узнать текущую цель можно так:

$ systemctl get-default

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

# systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target. Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target.

Альтернативный способ — добавить один из следующих параметров ядра в загрузчик:

  • systemd.unit=multi-user.target (что примерно соответствует прежнему уровню запуска 3).
  • systemd.unit=rescue.target (что примерно соответствует прежнему уровню запуска 1).

Порядок выбора цели по умолчанию

systemd выбирает default.target в следующем порядке :

  1. Параметр ядра, описанный выше.
  2. Символическая ссылка /etc/systemd/system/default.target .
  3. Символическая ссылка /usr/lib/systemd/system/default.target .

Компоненты systemd

Некоторые (не все) составные части systemd:

  • systemd-boot — простой менеджер загрузки для UEFI;
  • systemd-firstboot — инициализация системных настроек при первой загрузке;
  • systemd-homed — переносимые аккаунты пользователей;
  • systemd-logind — управление сеансами;
  • systemd-networkd — управление сетевыми настройками;
  • systemd-nspawn — приложение для контейнеризации процессов;
  • systemd-resolved — разрешение сетевых имён;
  • systemd-sysusers(8) — создание системных пользователей/групп и добавление пользователей в группы при установке пакетов и загрузке системы;
  • systemd-timesyncd — синхронизация системных часов по сети;
  • systemd/Журнал — системные логи;
  • systemd/Таймеры — таймеры для управления событиями и службами, альтернатива cron.

systemd.mount — монтирование

systemd полностью отвечает за монтирование разделов и файловых систем, описанных в файле /etc/fstab . systemd-fstab-generator(8) преобразует записи из /etc/fstab в юниты systemd; это выполняется при каждой загрузке системы, а также при перезагрузке конфигурации системного менеджера.

systemd расширяет возможности fstab и предлагает дополнительные опции монтирования. Они могут влиять на зависимости юнита монтирования: например, могут гарантировать, что монтирование выполняется только после подключения к сети или после монтирования другого раздела. Полный список опций монтирования systemd (обычно они имеют префикс x-systemd ) описан в systemd.mount(5) § FSTAB .

Примером этих опций может быть т.н. автомонтирование (здесь имеется в виду не автоматическое монтирование во время загрузки, а монтирование при появлении запроса от устройства). Подробнее смотрите fstab#Автоматическое монтирование с systemd.

Автомонтирование GPT-раздела

На UEFI-системах systemd-gpt-auto-generator(8) автоматически монтирует GPT-разделы в соответствии с Discoverable Partitions Specification, поэтому их можно не указывать в файле fstab.

  • Загрузчик должен установить EFI-переменную LoaderDevicePartUUID, по которой можно будет определить системный раздел EFI. Эта возможность поддерживается в systemd-boot, а также в rEFInd (по умолчанию отключена). Это проверяется наличием строки Boot loader sets ESP partition information в выводе команды bootctl .
  • Корневой раздел должен быть на одном физическом диске с системным разделом EFI. Автомонтируемые разделы должны быть на одном физическом диске с корневым разделом. Очевидно, монтируемые разделы должны оказаться на одном диске и с ESP.

Совет: Автомонтирование разделов отключается изменением его GUID-типа или установкой атрибута раздела «do not mount» (бит 63), см. gdisk#Prevent GPT partition automounting.

/var

Для автомонтирования раздела /var его PARTUUID должен совпадать с хэш-суммой SHA256 HMAC, вычисленной на основании UUID типа раздела. В качестве ключа хэша используется machine ID. Необходимый PARTUUID можно получить командой:

$ systemd-id128 -u --app-specific=4d21b016-b534-45c2-a9fb-5c16e091fd2d machine-id 

Примечание: Утилита systemd-id128(1) считывает machine ID из файла /etc/machine-id , поэтому вычислить PARTUUID до установки системы невозможно.

systemd-sysvcompat

Пакет systemd-sysvcompat (зависимость пакета base ) содержит традиционный бинарный файл init. В системах под управлением systemd init — символическая ссылка на исполняемый файл systemd .

Кроме того, в этом пакете находятся 4 команды SysVinit — halt(8) , poweroff(8) , reboot(8) и shutdown(8) . Это символические ссылки на systemctl , и их работа обусловлена логикой systemd. Подробнее см. #Управление питанием.

В systemd-системах отказаться от совместимости с System V можно либо задав параметр загрузки init= (см. BBS#233387), либо с помощью собственных аргументов команды systemctl .

systemd-tmpfiles — временные файлы

Утилита systemd-tmpfiles создает, удаляет и очищает непостоянные и временные файлы и каталоги. Она читает конфигурационные файлы из /etc/tmpfiles.d/ и /usr/lib/tmpfiles.d/ , чтобы понять, что необходимо делать. Конфигурационные файлы в первом каталоге имеют приоритет над теми, что расположены во втором.

Конфигурационные файлы обычно предоставляются вместе с файлами служб и имеют названия вида /usr/lib/tmpfiles.d/программа.conf . Например, демон Samba предполагает, что существует каталог /run/samba с корректными правами доступа. Поэтому пакет samba поставляется в следующей конфигурации:

/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root

Конфигурационные файлы также могут использоваться для записи значений при старте системы. Например, если вы используете /etc/rc.local для отключения пробуждения от устройств USB при помощи echo USBE > /proc/acpi/wakeup , вместо этого вы можете использовать следующий tmpfile:

/etc/tmpfiles.d/disable-usb-wake.conf
# Path Mode UID GID Age Argument w /proc/acpi/wakeup - - - - USBE

Примечание: Этот способ может не сработать для установки опций в /sys , поскольку служба systemd-tmpfiles-setup может запуститься до того, как будут загружены соответствующие модули устройств. В этом случае при помощи команды modinfo модуль вы можете проверить, имеет ли модуль параметр для установки необходимой опции, и установить эту опцию в файле настроек в каталоге /etc/modprobe.d . В противном случае для установки верных атрибутов сразу при появлении устройства придется написать правило udev.

Советы и рекомендации

Программы настройки с графическим интерфейсом

  • systemadm — Графический поисковик юнитов systemd. Выводит список юнитов, возможна фильтрация по типу.
  • SystemdGenie — Утилита управления systemd на основе инструментов KDE.

Запуск сервисов после подключения к сети

Чтобы запустить сервис только после подключения к сети, добавьте такие зависимости в .service файле:

/etc/systemd/system/foo.service
[Unit] . Wants=network-online.target After=network-online.target .

Также должна быть включена служба ожидания сети того приложения, которое управляет сетью; только тогда network-online.target будет соответствовать состоянию сети.

  • В NetworkManager служба NetworkManager-wait-online.service включается вместе с NetworkManager.service . Проверить состояние службы можно командой systemctl is-enabled NetworkManager-wait-online.service . Если служба не включена, то включите заново NetworkManager.service ещё раз.
  • В случае netctlвключите службу netctl-wait-online.service .
  • Для пользователей systemd-networkd юнит systemd-networkd-wait-online.service включается вместе со службой systemd-networkd.service ; проверьте это командой systemctl is-enabled systemd-networkd-wait-online.service . Если нет, то включите заново systemd-networkd.service .

Если служба отправляет DNS-запросы, она должна запускаться также после nss-lookup.target :

/etc/systemd/system/foo.service
[Unit] . Wants=network-online.target After=network-online.target nss-lookup.target .

Чтобы цель nss-lookup.target работала как положено, должна быть служба, которая запускает её параметром Wants=nss-lookup.target и размещает себя перед ней ( Before=nss-lookup.target ). Обычно это выполняет локальный DNS-распознаватель.

Чтобы узнать, какие службы зависят от nss-lookup.target , выполните:

$ systemctl list-dependencies --reverse nss-lookup.target

Включение установленных юнитов по умолчанию

This article or section needs expansion.

Reason: Как это работает для юнитов-экземпляров? (Discuss in Talk:Systemd (Русский))

Arch Linux поставляется с файлом /usr/lib/systemd/system-preset/99-default.preset , в котором указан параметр disable * . Это означает, что systemctl preset отключает по умолчанию юниты и пользователь должен сам их включать после установки пакетов.

Если такое поведение не устраивает, создайте символическую ссылку /etc/systemd/system-preset/99-default.preset на /dev/null для переопределения файла конфигурации. Это заставит systemctl preset включать юниты новых пакетов — вне зависимости от типа — кроме указанных в других файлах из каталога настроек systemctl preset. Пользовательских юнитов это не касается. Подробнее смотрите systemd.preset(5) .

Примечание: Политика включения всех юнитов по умолчанию может привести к проблемам, если в установленном пакете находится несколько взаимоисключающих юнитов. В этом случае в файле preset-настроек придётся явно указать, какие юниты включаться не должны. Подробнее смотрите systemd.preset(5) .

Песочница для приложений

Юнит может быть использован в качестве песочницы для изоляции приложений и их процессов в виртуальном окружении. Systemd использует механизм namespaces, белые и чёрные списки capabilities, а также control groups для контейнеризации процессов при помощи настраиваемых окружений — см. systemd.exec(5) .

Добавление к существующему юниту systemd функциональности песочницы обычно происходит методом проб и ошибок вкупе с использованием различных инструментов логирования — strace , stderr и journalctl(1) . В таких случаях имеет смысл предварительно поискать соответствующую документацию от разработчиков. В качестве отправной точки для поиска путей повышения безопасности изучите вывод команды:

$ systemd-analyze security юнит 

Рекомендации по созданию песочницы с помощью systemd:

  • Параметр CapabilityBoundingSet определяет список разрешённых capabilities, но с его помощью можно также и запрещать некоторые capabilities для определённого юнита.
    • Например, можно задать capability CAP_SYS_ADM , необходимую для создания безопасной песочницы: CapabilityBoundingSet=~ CAP_SYS_ADM

    Уведомление о неработающих службах

    Для уведомления о неудачном запуске службы используется директива OnFailure= в соответствующем файле службы или drop-in файле. Чтобы эта директива возымела эффект для всех служб одновременно, её необходимо добавть в drop-in файл верхнего уровня, см. systemd.unit(5) .

    Создайте drop-in верхнего уровня:

    /etc/systemd/system/service.d/toplevel-override.conf
    [Unit] OnFailure=failure-notification@%n

    Это добавит строку OnFailure=failure-notification@%n в файл каждой службы. Если какой-то_юнит завершится с ошибкой, запустится экземпляр службы failure-notification@какой-то_юнит для создания уведомления (или любой другой задачи, которая была назначена).

    Создайте юнит-шаблон failure-notification@ :

    /etc/systemd/system/failure-notification@.service
    [Unit] Description=Send a notification about a failed systemd unit After=network.target [Service] Type=simple ExecStart=/путь/к/failure-notification.sh %i

    После этого создайте сценарий failure-notification.sh , в котором определите, каким именно способом будет создаваться уведомление (mail, gotify, xmpp). Параметр %i будет заменён на название неудачно завершившегося юнита и будет передан сценарию в качестве аргумента.

    Чтобы предотвратить регрессию экземпляров failure-notification@.service , создайте пустой файл drop-in настроек с именем, совпадающим с названием drop-in файла верхнего уровня (пустой файл «уровня служб» будет иметь приоритет над файлом «верхнего уровня»):

    # mkdir -p /etc/systemd/system/failure-notification@.service.d # touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf

    Решение проблем

    Неудачно запущенные службы

    Следующая команда найдёт все службы, которые не смогли выполнить запуск:

    $ systemctl --state=failed

    Чтобы определить причину, по которой служба не запустилась, необходимо изучить записи её логов. Подробнее см. systemd/Журнал#Фильтрация вывода.

    Диагностика загрузки системы

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

    Диагностика службы

    Если какая-либо служба systemd ведет себя не так, как ожидается, и вы хотите получить дополнительную информацию о том, что происходит, присвойте переменной окружения SYSTEMD_LOG_LEVEL значение debug . Например, чтобы запустить демон systemd-networkd в режиме отладки:

    Добавьте drop-in файл для службы:

    [Service] Environment=SYSTEMD_LOG_LEVEL=debug

    Или, как вариант, пропишите переменную окружения вручную:

    # SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

    После этого перезапустите systemd-networkd и следите за журналом службы с помощью опции -f / —follow .

    Выключение/перезагрузка происходят ужасно долго

    Если процесс выключения занимает очень долгое время (или выглядит зависшим), то, вероятно, виновата служба, которая не может завершить свою работу. Systemd ожидает некоторое время, пока каждая служба прекратит работу самостоятельно, и только потом пробует завершить её принудительно. Если вы столкнулись с такой проблемой, обратитесь к Shutdown completes eventually в systemd-вики.

    По-видимому, процессы с кратким сроком жизни не оставляют записей в логах

    Если команда journalctl -u foounit не даёт вывода для службы с коротким сроком жизни, вместо названия службы используйте её PID. Например, если загрузка службы systemd-modules-load.service завершилась неудачно и команда systemctl status systemd-modules-load показывает, что она была запущена с PID 123, то вы сможете посмотреть вывод процесса в журнале под данным PID, то есть командой journalctl -b _PID=123 . Поля метаданных для журнала вроде _SYSTEMD_UNIT и _COMM собираются асинхронно и полагаются на каталог /proc в случае с действующими процессами. Для решения проблемы требуется внести исправления в ядро, чтобы эти данные можно было собирать через сокет, наподобие SCM_CREDENTIALS . В общем, это баг. Имейте в виду, что быстро падающие службы могут не успеть оставить сообщения в журнале из-за особенностей systemd.

    Время загрузки системы увеличивается с течением времени

    После использования systemd-analyze некоторые пользователи заметили, что время загрузки системы значительно увеличилось. После использования systemd-analyze blame NetworkManager запускался необычно долго.

    Проблема связана с тем, что файл /var/log/journal стал слишком большим. При этом также может уменьшаться скорость работы других команд, например, systemctl status или journalctl . Для решения проблемы можно удалить все файлы из каталога журнала (в идеале — сделав где-нибудь резервные копии, хотя бы временно), а затем ограничить размер журнала.

    systemd-tmpfiles-setup.service не запускается во время загрузки

    Начиная с версии Systemd 219, /usr/lib/tmpfiles.d/systemd.conf определяет ACL-атрибуты для каталогов в /var/log/journal и, следовательно, требует включённой поддержки ACL для той файловой системы, в которой находится журнал.

    Отключение emergency mode на удалённой машине

    Вам может понадобиться отключить emergency mode на удалённой машине, например на виртуальных машинах Azure или Google Cloud. Это связано с тем, что в случае ухода системы в emergency mode она отключится от сети и лишит вас возможности подключения к ней.

    Для отключения этого режима замаскируйте emergency.service и emergency.target .

    Смотрите также

    • Wikipedia:ru:systemd
    • Официальный веб-сайт (англ.)
      • Оптимизации systemd
      • systemd FAQ
      • systemd Советы и трюки
      • Gentoo:Systemd
      • Fedora:Systemd
      • Fedora:How to debug Systemd problems — отладка systemd.
      • Fedora:SysVinit to Systemd Cheatsheet — памятка по переходу с SysVinit на systemd.
      • Debian:systemd

      Retrieved from «https://wiki.archlinux.org/index.php?title=Systemd_(Русский)&oldid=776177»

      34. Система инициализации — systemd

      Мы с вами помним: когда запускается программа — появляется соответствующий процесс. Но если посмотреть список процессов на свежезапущенной операционной системе, мы увидим более сотни процессов, хотя я всего лишь запустил эмулятор терминала, bash и htop. Значит, всё остальное было запущено другими программами.

      То окно, в котором я залогинился — это ведь тоже какая-то программа, благодаря которой я и могу войти в систему. И вот этот графический интерфейс — тоже какая-то программа. Если я открою браузер и зайду на какой-то сайт — я может и не думаю об этом, но чтобы я смог зайти на этот сайт, сработала ещё одна программа, которая отвечает за работу с сетью. Т.е. чтобы я мог выполнить какие-то простые действия, должны работать какие-то программы.

      Они всегда работают на фоне и помогают пользователям удобно пользоваться операционной системой. Все эти программы, которые работают на фоне, называются демонами, или даймонами — и тут отсылка не к библейским демонам, а к древнегреческой мифологии. Что-то типа ангелов хранителей.

      Т.е., чтобы я мог нормально работать, должны работать демоны. Но чтобы они работали, их должен кто-то запустить. Этим занимается специальная программа — система инициализации. Есть различные реализации этой программы, мы с вами рассмотрим systemd, которая используется во многих популярных дистрибутивах, в том числе Centos и RHEL.

      В прошлый раз мы остановились на том, что ядро вместе с initramfs запускает программу /sbin/init:

      ls -l /sbin/init 

      /sbin/init олицетворяет систему инициализации, и, как видите, сейчас она показывает, что системой инициализации является systemd.

      man systemd 

      это первый процесс, запускаемый в пользовательском пространстве. У него PID — 1. Мы упоминали про процесс с pid 1, когда говорили о процессах — если убить родительский процесс, у дочернего процесса родителем станет процесс с номером 1. Так вот, после запуска система инициализации должна запустить демоны. Но это не просто список программ, которые нужно запустить — какие-то программы нужно запускать раньше, чем другие, какие-то программы могут конфликтовать и всё такое. А что делать, если какая-то из программ не запустилась? Нужно же ещё дать возможность пользователям при желании решать, какие программы запускать при включении, какие не запускать. Все эти задачи и стоят перед системой инициализации.

      systemd, кроме того, что является системой инициализации, также отвечает за многое другое, например, за управление сервисами, логами, сетью и т.п. Нужно понимать, что роль системы инициализации, как и говорит название — запуск операционной системы, чтобы всё начало работать как надо. На этом полномочия системы инициализации заканчиваются. Но systemd позиционирует себя как системный и сервисный менеджер, он связывает и заменяет многие компоненты операционной системы. Из-за чего, с одной стороны, многое друг с другом интегрировано, легче разрабатывать и администрировать, а с другой — сложнее заменить один компонент на другой и появляется зависимость дистрибутивов от systemd.

      Очень сложно заменить systemd на что-то другое — придётся многое переделывать. Это противоречит философии Unix-а — пишите программы, которые делают одну вещь и делают её хорошо. В итоге сообщество пользователей разделилось на сторонников и противников использования systemd. Я всё это к тому, что пусть вас не пугает большой функционал systemd, он нацелен на большее количество задач, чем просто инициализировать систему. Поэтому что-то мы рассмотрим сегодня, а что-то останется на потом.

      Демонов много, они по разному запускаются, по разному останавливаются, что-то нужно перезапускать в случае ошибки, что-то не нужно, что-то нужно раньше запустить, что-то позже. Т.е. к ним нужен как массовый подход, чтобы удобно было ими управлять, так и индивидуальный. Поэтому демонов оборачивают в так называемые сервисы. Сервис — что-то типа инструкции по эксплуатации демона. В сервисе указано, как запускать демон, как его останавливать, с какими другими демонами он связан и т.п. Какие-то сервисы приходят вместе с операционной системой, другие сервисы появляются при установке программ, а что-то вы можете и сами написать. Например, если вы работаете в компании, где программисты написали какую-то программу, а вам нужно обеспечить работу этой программы на серверах, то это, скорее всего, ваша задача — написать сервис, чтобы программа нормально стартовала при запуске операционной системы, нормально завершалась и всё такое.

      И так, мы разобрали, что такое сервис. systemd работает с unit-ами, а сервисы — один из типов таких unit-ов. Есть ещё другие типы юнитов — например, юниты устройств, юниты монтирования и т.д. Но нас сейчас интересуют сервисные юниты и таргеты. Таргеты — это тоже юниты, представляющие из себя группу юнитов. target — от слова цель — говорит о конечном результате, достигаемом с помощью группы юнитов. Допустим, чтобы у нас был графический интерфейс, чтобы я мог открыть браузер и зайти на сайт, послушать музыку и т.п. — одного сервиса недостаточно. А вот если я возьму группу сервисов, отвечающих за графический интерфейс, сеть, звук и т.п. — то это будет готовый результат, который я хочу — т.е. это графический target.

      И если мы посмотрим вывод команды:

      systemctl get-default 

      то мы как раз увидим, что systemd по умолчанию грузит таргет с названием graphical.target. А с помощью команды:

      systemctl list-dependencies graphical.target 

      мы как раз увидим, какие юниты нужны для этого таргета. Как видите, графический таргет предполагает использование multi-user таргета, а внутри него огромное количество других юнитов. На серверах, по умолчанию, вместо графического таргета используется multi-user — примерно тоже самое, но нет графического интерфейса, что позволяет сэкономить ресурсы.

      И если мы захотим, чтобы у нас тоже было как на серверах, чтобы всё работало, но без графического интерфейса, мы можем поменять таргет по умолчанию, с помощью команды:

      sudo systemctl set-default multi-user.target 

      Ну и заметим мы это только при запуске. А пока вернём как было:

      sudo systemctl set-default graphical.target 

      Как видите, при выполнении этих команд у нас создаются и удаляются символические ссылки. И тут участвуют 2 директории — /etc/systemd и /usr/lib/systemd. Когда вы устанавливаете какую-то программу или в целом операционную систему, то все файлы юнитов попадают в директорию /usr/lib/systemd. Допустим, посмотрим файл graphical таргета:

      systemctl cat graphical.target 

      Тут у нас описание юнита, путь к документации. Ну и как видите, тут написано Requires=multi-user.target, т.е. для загрузки графического таргета требуется загрузка multi-user таргета. Также тут написано Wants=display-manager.service. Display manager — это та программа, которая у нас спрашивает логин при входе в систему, ну и она же грузит рабочее окружение. Wants означает, что если этот сервис есть, то нужно его загрузить, а вот если он не грузится, или нету такого сервиса, то ничего страшного, таргет всё равно прогрузится. Если проблема с Requires то таргет перестанет грузиться. Также у нас тут Conflicts — то есть этот таргет не может одновременно работать с этими сервисами и таргетами, и что запуск этого таргета остановит работу указанных здесь сервиса и таргета. After означает порядок, после каких сервисов и таргетов грузится этот юнит.

      Ну и AllowIsolate означает, можно ли использовать этот таргет как состояние, к которому можно перейти с помощью команды systemctl isolate. Т.е. таргеты — это группа юнитов, и, в случае с graphical.target или multi-user.target, их можно использовать как состояние загрузки операционной системы — т.е. с графическим интерфейсом или без, но всё же есть все нужное для работы. Но есть, например, таргет сети — network target — опять же, группа юнитов, нужная для работы сети, но на него переключаться бессмысленно, так как это не готовое состояние операционной системы, в котором можно работать, а просто группа юнитов. Для примера, есть resсue.target — это состояние системы, при котором большинство демонов не работает, и это нужно для решения каких-то проблем, допустим, когда система не грузится.

      sudo systemctl isolate resсue.target 

      и, как видите, теперь у меня система просит root пароль для перехода в режим восстановления. Вводим пароль и смотрим htop — как видите, процессов очень мало.

      Ну и чтобы вернуться обратно, я делаю:

      systemctl isolate graphical.target 

      В старых системах инициализации эти состояния, к которым можно было переходить, назывались runlevel-ами. Они были пронумерованы — от 0 до 6. Среди которых 0 это shutdown, 6 это restart, 1 это аналог rescue таргета, 3 это аналог multi-user таргета, 5 — аналог графического таргета, ну и оставшееся это промежуточные состояния. Были директории с соответствующими номерами, в которых лежали скрипты, которые выполнялись при переходе на определённый runlevel. Собственно, это и было основой системы инициализации. Это просто полезно знать, потому что некоторые люди до сих пор говорят о ранлвлах, могут на собеседовании спросить, ну и вы вполне можете наткнуться на другую систему инициализации. Я не буду сравнивать системы инициализации, но, если вам интересно, у Семаева есть ролики про различные системы инициализации, плюс можете почитать по ссылке.

      Мы поговорили о таргетах — группах юнитов. Теперь же давайте посмотрим на какой-нибудь определённый сервисный unit — допустим, gdm — тот самый дисплейный менеджер:

      cat /usr/lib/systemd/system/gdm.service 

      Тут у нас кроме секции Unit появились ещё две секции — Service и Install. В секции [Service] у нас есть информация о том, как сервис запускает демон — ExecStart, т.е. просто запускает команду /usr/sbin/gdm. А вот ExecStopPost запускает команду после остановки сервиса. Как видите, это какой-то скрипт, и вы можете в нём разобраться. Все опции я разбирать не буду, по большей части у разных сервисов могут быть свои опции, знать всё наизусть не надо, всегда можно обратиться к документации. Что может быть интересно так это секция [Install]. Как видите, тут написан Alias=display-manager.service.

      У нас есть две команды — systemctl enable и systemctl disable. Если мы хотим, чтобы какой-то сервис запускался при включении операционной системы, мы запускаем команду systemctl enable и имя сервиса:

      sudo systemctl enable gdm 

      Как видите, никакого вывода не было, потому что этот сервис уже был включён. Если мы хотим убрать из автозапуска этот сервис, делаем:

      sudo systemctl disable gdm 

      В выводе написано, что удалён файл /etc/systemd/system/display-manager.service. Если опять сделаем enable:

      sudo systemctl enable gdm 

      то увидим, что создалась символическая ссылка display-manager.service, которая ведёт на файл gdm.service. Т.е. такое вот название символической ссылки, на основе того, что было написано в Alias в секции Install. Ну и можно посмотреть, включён ли сервис, с помощью команды:

      systemctl is-enabled gdm 

      Что ещё интересно — символическая ссылка создаётся в директории /etc/systemd/system. Если в /usr/lib/systemd у нас файлы этих сервисов, то в /etc/systemd преимущественно символические ссылки, означающие, что данный сервис включён. Ну и если у нас какие-то свои сервисы, написанные нами вручную, то правильнее всего считается класть их именно в /etc/systemd.

      Подводя итоги. Для нормальной работы операционной системы нужны программы, работающие в фоне — демоны. Для запуска демонов при включении компьютера нужна система инициализации, одной из которых является systemd. systemd много чего умеет, помимо запуска демонов. Для правильной работы с демонами используются сервисы. systemd для этого использует service unit-ы и target unit-ы — т.е. группы юнитов. Чтобы сервисы запускались при запуске операционной системы, они должны быть enabled, что мы делали с помощью команды systemctl enable, ну или наоборот — чтобы убрать из автозапупска — systemctl disable. Таким образом операционная система запускает все нужные программы при включении.

      Теперь, объединяя эту и предыдущую тему, вы имеете представление, что именно происходит при запуске компьютера и операционной системы.

      © Copyright 2021, GNU Linux Pro, CC-BY-SA-4.0. Ревизия 5f665cc2 .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *