В статье мы подробнее посмотрим на юниты SystemD с типом Target. Объединим в 1 таргет несколько юнитов и познакомимся с загрузочными таргетами.
Юниты SystemD типа target
Ранее, мы узнали что система инициализации SystemD состоит из юнитов. А также мы познакомились с юнитом типа service. Теперь узнаем про другой тип юнитов SystemD — про target. Таргеты позволяют объединить различные юниты в группу. Например, можно создать target который будет запускать сразу несколько служб.
В отличие от сервисов, этот тип юнитов имеют только 2 блока — [Unit] и [Install]. Отдельного блока [target] не существует.
Вот так, например, можно объединить службы ssh и apache2:
alex@ubu:~$ sudo nano /etc/systemd/system/ssh-apache.target [Unit] Description=ssh apache target Requires=ssh.service Requires=apache2.service [Install] WantedBy=multi-user.target
В примере выше мы создали ssh-apache.target и использовали для этого следующие параметры:
- Description — описание юнита.
- Requires — в этом параметре указывается юнит, который должен запуститься при запуске таргета. Если необходимо запускать несколько служб, то нужно использовать несколько таких параметров, как в нашем примере.
- WantedBy — на каком загрузочном таргете запускать этот юнит. Про загрузочные таргеты будет написано чуть ниже.
Проверим работу созданного нами таргета. Для этого, во-первых, выключим обе службы и убедимся что они выключены:
alex@ubu:~$ sudo systemctl stop apache2.service alex@ubu:~$ sudo systemctl stop ssh.service alex@ubu:~$ systemctl status apache2.service ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Active: inactive (dead) since Fri 2022-07-22 12:02:18 MSK; 11s ago alex@ubu:~$ systemctl status ssh.service ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: inactive (dead) since Fri 2022-07-22 12:02:24 MSK; 13s ago
Во-вторых, после создания нового юнита, обязательно нужно выполнить команду systemctl daemon-reload:
alex@ubu:~$ sudo systemctl daemon-reload
Теперь запустим созданный ssh-apache.target. И проверим статус таргета и связанных служб:
alex@ubu:~$ sudo systemctl start ssh-apache.target alex@ubu:~$ systemctl status ssh-apache.target ● ssh-apache.target - ssh apache target Loaded: loaded (/etc/systemd/system/ssh-apache.target; disabled; vendor preset: enabled) Active: active since Fri 2022-07-22 12:05:00 MSK; 29s ago alex@ubu:~$ systemctl status apache2.service ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-07-22 12:05:00 MSK; 45s ago alex@ubu:~$ systemctl status ssh.service ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-07-22 12:05:00 MSK; 1min 18s ago
Таргеты можно не только запускать и останавливать, но и включать их в автозагрузку:
alex@ubu:~$ sudo systemctl enable ssh-apache.target
В примере я использовал совсем не связанные службы. Но таким образом вы можете объединить, например службу 1С и службу баз данных postgres. Или службы какого-нибудь веб приложения: apache2, php и mariadb.
Загрузочные таргеты (Boot targets)
В Linux есть так называемые режимы запуска, в первой системе инициализации они назывались «Уровни запуска» (runlevel). В SystemD они называются загрузочными таргетами, или boot targets.
Помните, в Windows есть режим безопасной загрузки и обычной загрузки. Так вот, в Linux это работает примерно также. На каждом уровне — запускаются или останавливаются определённые службы. В отличие от Windows, в Linux можно переходить из одного уровня в другой не перезагружаясь. Хотя перезагрузка — это один из уровней запуска. И даже выключение — это тоже определённый уровень запуска.
Можно настроить определенный уровень запуска, как уровень по умолчанию. Именно в этом режиме будет загружаться ваша система.
Чтобы посмотреть список существующих загрузочных таргетов можно использовать следующую команду:
alex@ubu:~$ ls -l /lib/systemd/system/runlevel*.target lrwxrwxrwx 1 root root 15 июн 7 10:49 /lib/systemd/system/runlevel0.target -> poweroff.target lrwxrwxrwx 1 root root 13 июн 7 10:49 /lib/systemd/system/runlevel1.target -> rescue.target lrwxrwxrwx 1 root root 17 июн 7 10:49 /lib/systemd/system/runlevel2.target -> multi-user.target lrwxrwxrwx 1 root root 17 июн 7 10:49 /lib/systemd/system/runlevel3.target -> multi-user.target lrwxrwxrwx 1 root root 17 июн 7 10:49 /lib/systemd/system/runlevel4.target -> multi-user.target lrwxrwxrwx 1 root root 16 июн 7 10:49 /lib/systemd/system/runlevel5.target -> graphical.target lrwxrwxrwx 1 root root 13 июн 7 10:49 /lib/systemd/system/runlevel6.target -> reboot.target
В примере выше как раз видна связь загрузочных таргетов SystemD и уровней запуска (runlevel). То-есть каждый уровень запуска — это символьная ссылка на определённый таргет.
А для перехода в другой режим нужно выполнить systemctl isolate <название_таргета>, например:
alex@ubu:~$ sudo systemctl isolate rescue.target alex@ubu:~$ sudo systemctl isolate multi-user.target
Таргет по умолчанию — это default.target. И он является символьной ссылкой на один из загрузочных таргетов:
alex@ubu:~$ ls -l /lib/systemd/system/default.target lrwxrwxrwx 1 root root 16 июн 7 10:49 /lib/systemd/system/default.target -> graphical.target
Как видите, серверная Ubuntu, также как и Debian, по умолчанию загружается в графическом режиме (graphical.target). Хотя графику я не устанавливал.
Давайте посмотрим на этот юнит:
alex@ubu:~$ cat /lib/systemd/system/default.target [Unit] Description=Graphical Interface Documentation=man:systemd.special(7) Requires=multi-user.target Wants=display-manager.service Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target display-manager.service AllowIsolate=yes
Разберём некоторые параметры:
- Requires=multi-user.target — при запуске этого юнита, будет запущен юнит multi-user.target.
- Wants=display-manager.service — этот юнит ожидает запуска службы display-manager.service, но не требует её запуска. То-есть графику он подождёт, но если она не установлена, то всё равно запустится.
- Conflicts=rescue.service rescue.target — параметр Conflicts означает, что если указанный юнит выполняется, то этот не будет запущен. А режим rescue.target — это режим восстановления, чем-то похож на Безопасный режим в Windows. Получается что если запущен режим восстановления (rescue.target), то нельзя запускать графический режим (graphical.target).
- After — по очерёдности юнит должен запускаться после указанных юнитов, но не требует их запуска.
- AllowIsolate — если этот юнит можно использовать в команде systemctl isolate <название таргета>, то здесь нужно поставить yes. То есть, с помощью этого параметра, мы указываем что это именно boot target.
Есть ещё один способ узнать default target в настоящий момент. Для этого можно использовать следующую команду:
alex@ubu:~$ systemctl get-default graphical.target
Список загрузочных таргетов
Теперь, когда вы поняли что такое загрузочные таргеты, давайте по ним пробежимся:
- poweroff.target — выключение системы.
- rescue.target — режим восстановления. В нем запускается минимум сервисов и не запускается сеть. Необходим для восстановление работы системы. Похож на загрузку в безопасном режиме в Windows.
- multi-user.target — многопользовательский режим.
- graphical.target — многопользовательский режим с поддержкой графики. Но если графика не установлена, то этот таргет работает как multi-user.target. Он является таргетом по умолчанию и в Debian 11 и в Ubuntu 22.04.
- reboot.target — перезагрузка.
- default.target — режим, который будет загружаться по умолчанию, является символической ссылкой на один из boot tatget.
Для установки default.target можно воспользоваться командой systemctl set-default -f <Имя таргета>.
После перезагрузки система загрузится именно в default.target. Если указать в качестве default.target — reboot.target, то получим постоянную перезагрузку. Не нужно так делать!!!
Итог
Мы научились создавать свой собственный таргет для объединения служб. И познакомились с загруочными таргетами.
Узнали новые команды systemctl:
- systemctl daemon-reload — нужно выполнять после создания юнита (любого типа), или после редактирования уже созданного;
- systemctl get-default — узнать текущий загрузочный таргет по умолчанию, в который система загрузится в следующий раз;
- systemctl set-default -f <Имя таргета> — установить загрузочный таргет, как таргет по умолчанию;
- systemctl isolate <название таргета> — перейти в другой загрузочный таргет.
Думаю теперь стал понятнее параметр WantedBy в блоке [Install]. Мы его используем и при создании своих сервисов и своих таргетов. Именно в нем мы указываем, на каком загрузочном таргете запускать этот юнит, если для юнита включен автозапуск.
Про таргеты вы также можно почитать в официальной документации Systemd — здесь.