systemd Часть 2: Управление юнитами, зависимостями и целями

Этой вторая часть о systemd и юнитах.


В этой статье разберем управление юнитами, зависимостями и целями.


Управление юнитами через systemd

Для управления юнитами используется команда systemctl

Вот как это делается?

Для примера установим пакет php-fpm:
[root@server2]# yum install -y php-fpm.x86_64

Запускаем сервис php-fpm.service:
systemctl start php-fpm

Как я узнал, что сервис называется именно так и что вообще при установке пакета создался и сервис?

В первой части статьи было сказано:

/usr/lib/systemd/system 
Системные юнит-файлы. Это юниты из установленных пакетов RPM — всякие nginx, apache, mysql и прочее. 

Поэтому вводим и получаем:
[root@server2 system]# ls -l /usr/lib/systemd/system | grep php
-rw-r--r--. 1 root root  314 Oct 31  2018 php-fpm.service

Значит юнит-файл service уже создан пакетом:
[root@server2 system]# systemctl status php-fpm.service
● php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

Запускаем:
[root@server2 system]# systemctl start php-fpm.service

Снова смотрим статус:
 php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2019-08-15 14:19:59 +10; 46s ago
 Main PID: 14058 (php-fpm)
   Status: "Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec"
   CGroup: /system.slice/php-fpm.service
           ├─14058 php-fpm: master process (/etc/php-fpm.conf)
           ├─14059 php-fpm: pool www
           ├─14060 php-fpm: pool www
           ├─14061 php-fpm: pool www
           ├─14062 php-fpm: pool www
           └─14063 php-fpm: pool www

Aug 15 14:19:59 server2 systemd[1]: Starting The PHP FastCGI Process Manager...
Aug 15 14:19:59 server2 systemd[1]: Started The PHP FastCGI Process Manager.

Сервис успешно запущен. Но чтобы он всегда запускался при загрузке системы, поставим его в автозагрузку.

[root@server2 system]# systemctl enable php-fpm.service
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.

Используя команду systemctl status вы можете увидеть такие состояния:


 Статус

 Описание

 Loaded

Юнит-файл был обработан и юнит активен

 Active(running)

Сервис запущен

 Active(exited)

Успешно завершена одноразовая настройка

 Active(waiting)

Запуск и ожидание события

 Inactive

Не запущен

 Enabled

Будет запущен во время загрузки системы

 Disable

Не будет запущен во время загрузки системы

 Static

Этот юнит не может быть запущен, но может быть запущен другим юнитом автоматически.

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


 Команда

 Описание

 systemctl --type=service
 
Показать только сервисные юниты

 systemctl list-units --type=service 
 
Показать все активные сервисные юниты (тот же результат, что и предыдущая команда)

 systemctl list-units --type=service --all 
 
Показать как неактивные так и активные сервисные юниты

 systemctl --failed --type=service

Показать все сервисы, которые не удалось запустить (Failed)

 systemctl status -l свой-сервис.service
 
Показать детальную информацию о каком-либо сервисе

Управление зависимостями

Юниты systemctl во многих случаях имеют зависимости. Некоторые юниты будут запускаться как зависимость от других юнитов, и событие, когда запрашивается один конкретный юнит, может вызвать запуск другого юнита.

Примером является сервис cups.service. Эта служба может быть запущена сама по себе, но она также может быть запущена на юнитах cups.path и cups.socket, что может привести к повторному запуску службы.

На примере всё того же php-fpm посмотрим список зависимостей:
Так как список большой, то отобразил только несколько строк.

[root@server2 system]# systemctl list-dependencies php-fpm
php-fpm.service
 ├─-.mount
 ├─system.slice
 └─basic.target
   ├─microcode.service
   ├─rhel-dmesg.service
   ├─selinux-policy-migrate-local-changes@targeted.service
   ├─paths.target
   ├─slices.target
   │ ├─-.slice
   │ └─system.slice
   ├─sockets.target
   │ ├─dbus.socket
   │ ├─dm-event.socket
   │ ├─rpcbind.socket
   │ ├─systemd-initctl.socket
   │ ├─systemd-journald.socket
   │ ├─systemd-shutdownd.socket
●   │ ├─systemd-udevd-control.socket
●   │ └─systemd-udevd-kernel.socket
   ├─sysinit.target
●   │ ├─dev-hugepages.mount
   │ ├─dev-mqueue.mount
●   │ ├─kmod-static-nodes.service
●   │ ├─lvm2-lvmetad.socket
●   │ ├─lvm2-lvmpolld.socket
●   │ ├─lvm2-monitor.service
   │ ├─plymouth-read-write.service
●   │ ├─plymouth-start.service
●   │ ├─proc-sys-fs-binfmt_misc.automount
   │ ├─rhel-autorelabel.service

Введите systemctl list-dependencies, за которым следует имя юнита, чтобы узнать, какие у него есть зависимости, и добавьте параметр --reverse, чтобы узнать, какие юниты зависят от этого юнита.
[root@server2 system]# systemctl list-dependencies --reverse sshd
sshd.service
 └─multi-user.target
●   └─graphical.target
Кроме зависимостей, некоторые юниты могут конфликтовать с другими юнитами.
Примеры:
  • mount и umount юниты не могут быть загружены совместно;
  • ifconfig и NetworkManager сервис;
  • iptables и firewalld;
  • cronyd и ntpd.
Если юнит конфликтует с другим юнитом, то это надо обозначить в юнит-файле.

Другой способ, чтобы быть уверенным, что конфликтующие юниты никогда не будут загружены одновременно в одной и той же системе это использовать команду systemctl mask <нужный-сервис>.service. Когда вы выполните команду, то запуск юнита переадресуется символьной ссылкой на /dev/null и юнит больше никогда не запустится. 

Чтобы отменить это, выполните systemctl umask <нужный-сервис>.service.

Изолирующие цели

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

Чтобы посмотреть все загруженные цели, введем:

[root@server2 ~]# systemctl --type=target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION
basic.target           loaded active active Basic System
cryptsetup.target      loaded active active Local Encrypted Volumes
getty.target           loaded active active Login Prompts
local-fs-pre.target    loaded active active Local File Systems (Pre)
local-fs.target        loaded active active Local File Systems
multi-user.target      loaded active active Multi-User System
network-online.target  loaded active active Network is Online
network-pre.target     loaded active active Network (Pre)
network.target         loaded active active Network
nfs-client.target      loaded active active NFS client services
nss-user-lookup.target loaded active active User and Group Name Lookups
paths.target           loaded active active Paths
remote-fs-pre.target   loaded active active Remote File Systems (Pre)
remote-fs.target       loaded active active Remote File Systems
rpc_pipefs.target      loaded active active rpc_pipefs.target
rpcbind.target         loaded active active RPC Port Mapper
slices.target          loaded active active Slices
sockets.target         loaded active active Sockets
swap.target            loaded active active Swap
sysinit.target         loaded active active System Initialization
timers.target          loaded active active Timers

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

21 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Некоторые из целей в системе играют важную роль, поскольку их можно запускать (изолировать) для определения уровня запуска системы и которые можно установить в качестве цели по умолчанию.

Это следующие цели:
  • poweroff.target - уровень запуска 0
  • rescue.target - уровень запуска 1
  • multi-user.target - уровень запуска 3
  • graphical.target - уровень запуска 5
  • reboot.target - уровень запуска 6
Если посмотреть содержимое каждой из этих целей, то там будет строка AllowIsolate=yes. Это значит, что вы можете переключать текущее состояние системы на одну из этих целей с помощью systemctl isolate.

Переходим в /usr/lib/systemd/system, вводим grep Isolate *.target:
[root@server2 ~]# cd /usr/lib/systemd/system
[root@server2 system]# grep Isolate *.target
ctrl-alt-del.target:AllowIsolate=yes
default.target:AllowIsolate=yes
emergency.target:AllowIsolate=yes
graphical.target:AllowIsolate=yes
halt.target:AllowIsolate=yes
initrd-switch-root.target:AllowIsolate=yes
initrd.target:AllowIsolate=yes
kexec.target:AllowIsolate=yes
multi-user.target:AllowIsolate=yes
poweroff.target:AllowIsolate=yes
reboot.target:AllowIsolate=yes
rescue.target:AllowIsolate=yes
runlevel0.target:AllowIsolate=yes
runlevel1.target:AllowIsolate=yes
runlevel2.target:AllowIsolate=yes
runlevel3.target:AllowIsolate=yes
runlevel4.target:AllowIsolate=yes
runlevel5.target:AllowIsolate=yes
runlevel6.target:AllowIsolate=yes
system-update.target:AllowIsolate=yes

Видим список изолированных целей. Далее изолируем цель systemctl isolate rescue.target и тем самым запустим систему в режиме восстановления.

Система перейдет в режим восстановления:

Комментариев 3

  1. Офлайн
    vlad
    vlad 13 августа 2022 10:01
    + 0 -
    Как запускать один юнит от другого? Например есть service a и service b, service b должен стартовать и работать только при условии что service a стартовал и/или работает. Если service a остановился, service b тоже должен остановиться.

    [Unit]
    After=service-a.service
    Requires=service-a.service

    Вот это лишь позволяет остановить service b, при остановке service a. Но при его старте systemctl start service a, service b не стартует.
    1. Офлайн
      yatakoi 15 августа 2022 02:48
      + 0 -
      А зачем вам такое? Вы добавили в автозагрузку сервис а и сервис б. Когда система загрузится у вас запустится сначала сервис а, а потом сервис б.

      Никто вручную не запускает сервисы - только при начальной инициализации.
  2. Офлайн
    bAd3d
    bAd3d 30 марта 2023 08:15
    + 0 -
    Да с чего бы это вдруг, есть событийные сервисы. Которые запускаются, например, по расписанию. Тут уже может потребоваться взаимосвязь одного юнита от другого. 

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

Недорогой сайт поможет купить диплом в Омске, а также возможна доставка в любой регион прямо в руки.