ProCloud Yandex
11.08.2023
читать 20 минут

Как использовать Systemctl для управления службами и блоками Systemd

/upload/iblock/7eb/edbjqhr49drmbwgylxk2oribzbt5vozp/87d7ec_b6a851ed381046b7848155246d397cf0pmv2_%281%29.jpg

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

В этом гайде мы детально рассмотрим команду systemctl — важнейший инструмент управления системой инициализации. Мы изучим методы управления службами, проверки статуса, изменения состояния системы и взаимодействия с конфигурационными файлами.

Важно отметить, что не все дистрибутивы Linux внедрили systemd в качестве системы инициализации по умолчанию. Если при использовании этого руководства вы столкнулись с ошибкой bash: systemctl is not installed, вероятно, на вашей машине используется другая система инициализации.

Управление службами

Основная цель системы инициализации в том, чтобы инициализировать компоненты, которые должны быть запущены после загрузки ядра Linux (известные как компоненты «пользовательского пространства»). Данная система также применяется для управления службами и демонами для сервера в любой момент, когда система работает. Исходя из этого, мы начнем с изучения основных операций по управлению службами.

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

Для задач по управлению службами целевым модулем будут модели службы, которые имеют файлы модулей с суффиксом .service. Однако для большинства команд управления службами вы можете опустить суффикс .service, так как systemd достаточно умна, чтобы понять, что вы, вероятно, хотите работать со службой, используя команды управления службами.

Запуск и остановка служб

Чтобы запустить службу systemd, используя инструкции в файле модуля службы, используйте команду start. Если вы работаете от имени пользователя без прав root, вам придется использовать sudo, так как это повлияет на состояние операционной системы:

sudo systemctl start application.service

Как мы упоминали выше, systemd будет искать файлы *.service для команд управления службами, поэтому команда может быть введена таким образом:

sudo systemctl start application

Хотя вы можете использовать указанный выше формат для общего администрирования, для ясности мы будем использовать суффикс .service для остальных команд, чтобы явно указывать цель, над которой мы работаем.

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

sudo systemctl stop application.service

Перезапуск и перезагрузка

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

sudo systemctl restart application.service

Если рассматриваемое приложение способно перезагрузить файлы конфигурации (без перезапуска), можно выдать команду reload для инициализации этого процесса:

sudo systemctl reload application.service

Если вы не уверены, что служба имеет функциональность для перезагрузки своей конфигурации, вы можете выдать команду reload-or-restart. Это приведет к перезагрузке конфигурации, если она доступна. В противном случае служба будет перезапущена для выбора новой конфигурации:

sudo systemctl reload-or-restart application.service

Включение и отключение служб

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

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

sudo systemctl enable application.service

Это создаст символическую ссылку из системной копии служебного файла (обычно в /lib/systemd/system или /etc/systemd/system) в то место на диске, где systemd ищет файлы для автозапуска (обычно /etc/systemd/system/some_target.target.wants). Мы рассмотрим, что такое цель позже в этом руководстве).

Чтобы отключить автоматический запуск службы, вы можете ввести:

sudo systemctl disable application.service

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

Помните, что включение службы не запустит ее в текущем сеансе. Если вы хотите запустить службу и включить ее при загрузке, необходимо дать обе команды, start и enable.

Проверка статуса служб

Чтобы проверить статус службы в вашей системе, можно использовать команду status:

systemctl status application.service

При этом вы получите статус службы, иерархию контрольных групп и первые несколько строк журнала.

Например, при проверке статуса сервера Nginx вы можете видеть следующий вывод:

Output
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 Main PID: 495 (nginx)
   CGroup: /system.slice/nginx.service
           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
           └─496 nginx: worker process
Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

Это дает вам хороший обзор текущего статуса приложения и уведомляет о наличии каких-либо проблем или необходимости выполнения каких-либо действий.

Также есть методы для проверки определенных статусов. Например, чтобы проверить, активен ли модуль в данный момент, можно использовать команду is-active:

systemctl is-active application.service

Это вернет текущий статус модуля, который обычно active или inactive. Код выхода будет «0», если он активен, и результат будет проще парсить в скрипты оболочки.

Чтобы увидеть, включен ли модуль, можно использовать команду is-enabled:

systemctl is-enabled application.service

Это выведет информацию о том, что служба enabled или disabled, и снова установит код выхода на «0» или «1» в зависимости от вопроса команды.

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

systemctl is-failed application.service

Это вернет active, если он работает должным образом, или failed, если возникла ошибка. Если модуль был намеренно остановлен, может вернуться unknown или inactive. Статус выхода «0» означает, что произошел сбой, а статус выхода «1» указывает на какой-либо другой статус.

Обзор состояния системы

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

Список текущих модулей

Чтобы увидеть список всех активных модулей, о которых знает systemd, можно использовать команду list-units:

systemctl list-units

Это покажет вам список всех модулей, которые у systemd активны в системе. Результат будет выглядеть примерно так:

Output
UNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
atd.service                               loaded active running ATD daemon
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
dbus.service                              loaded active running D-Bus System Message Bus
dcron.service                             loaded active running Periodic Command Scheduler
dkms.service                              loaded active exited  Dynamic Kernel Modules System
[email protected]                        loaded active running Getty on tty1
. . .

Вывод содержит следующие столбцы:

  • UNIT: имя модуля systemd
  • LOAD: указывает на то, парсила ли systemd конфигурацию модуля. Конфигурация загруженных модулей сохраняется в памяти.
  • ACTIVE: краткое состояние активности модуля. Обычно это довольно стандартный способ сообщить, запущен модуль или нет.
  • SUB: это состояние более низкого уровня, которое указывает более подробную информацию о модуле. Это часто зависит от типа модуля, состояния и фактического метода работы модуля.
  • DESCRIPTION: краткое текстовое описание того, чем является модуль/что делает.

Поскольку команда list-units показывает по умолчанию только активные модули, для всех вводов выше отобразится loaded в столбце LOAD и active в столбце ACTIVE. Это отображение фактически является поведением по умолчанию systemctl при вызове без дополнительных команд, поэтому вы увидите то же, что и при вызове systemctl без аргументов:

systemctl

Мы можем использовать systemctl для вывода различной информации путем добавления дополнительных флагов. Например, чтобы увидеть все модули, которые загрузила система systemd (или пыталась загрузить), независимо от их активности в данный момент, можно использовать флаг --all следующим образом:

systemctl list-units --all

Это отобразит все модули, которые загрузила или пыталась загрузить система systemd независимо от текущего состояния системы. Некоторые модули становятся неактивными после работы, а некоторые модули, которые система systemd пыталась загрузить, могут не быть найдены на диске.

Вы можете использовать другие флаги для фильтрации этих результатов. Например, мы можем использовать флаг --state= для указания состояния LOAD, ACTIVE или SUB, которое мы хотим увидеть. Вам потребуется сохранить флаг --all, чтобы systemctl позволила отображать неактивные модули:

systemctl list-units --all --state=inactive

Другим распространенным фильтром является фильтр ---type=. Мы можем задать systemctl только для отображения модулей интересующего нас типа. Например, чтобы увидеть только активные модули службы, мы можем использовать:

systemctl list-units --type=service

Список все файлов модулей

Команда list-units отображает только модули, которые система systemd пыталась парсить или загрузить в память. Поскольку systemd будет считывать только те модули, которые считает необходимыми, это необязательно будут все модули, доступные в системе. Чтобы увидеть все доступные файлы модулей в путях systemd, включая те, что система systemd пыталась загрузить, можно использовать команду list-unit-files:

systemctl list-unit-files

Модули являются представлениями ресурсов, о которых знает systemd. Поскольку система systemd необязательно считывала все определения модуля в этом виде, она представляет информацию только о самих файлах. Вывод содержит два столбца: файл модуля и состояние.

Output
UNIT FILE                                  STATE   
proc-sys-fs-binfmt_misc.automount          static  
dev-hugepages.mount                        static  
dev-mqueue.mount                           static  
proc-fs-nfsd.mount                         static  
proc-sys-fs-binfmt_misc.mount              static  
sys-fs-fuse-connections.mount              static  
sys-kernel-config.mount                    static  
sys-kernel-debug.mount                     static  
tmp.mount                                  static  
var-lib-nfs-rpc_pipefs.mount               static  
org.cups.cupsd.path                        enabled
. . .

Состояние будет, как правило, enabled, disabled, static или masked. В этом контексте static обозначает, что файл модуля не содержит раздел insitall, который используется для включения модуля. Эти модули как таковые не могут быть включены. Обычно это означает, что модуль выполняет разовое действие или используется только как зависимость другого модуля и не должен работать самостоятельно.

Сразу рассмотрим, что означает masked.

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

До сих пор мы работали со службами и отображали информацию о модулях и файлах модулей, о которых знает systemd. Однако мы можем узнать более конкретную информацию о модулях, используя некоторые дополнительные команды.

Отображение файла модуля

Чтобы отобразить файл модуля, который система systemd загрузила в систему, можно использовать команду cat (она была добавлена в версию systemd 209). Например, чтобы увидеть файл модуля демона-планировщика atd, можно ввести следующее:

systemctl cat atd.service Output
[Unit]
Description=ATD daemon
[Service]
Type=forking
ExecStart=/usr/bin/atd
[Install]
WantedBy=multi-user.target

Вывод — это файл модуля, известный выполняемому в настоящее время процессу systemd. Это может быть важно, если вы недавно модифицировали файлы модуля или если вы переопределяете определенные опции во фрагменте файла модуля (мы рассмотрим это позже).

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

Чтобы увидеть дерево зависимостей модуля, можно использовать команду list-dependencies:

systemctl list-dependencies sshd.service

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

Output
sshd.service
├─system.slice
└─basic.target
  ├─microcode.service
  ├─rhel-autorelabel-mark.service
  ├─rhel-autorelabel.service
  ├─rhel-configure.service
  ├─rhel-dmesg.service
  ├─rhel-loadmodules.service
  ├─paths.target
  ├─slices.target
. . .

Рекурсивные зависимости отображаются только для модулей .target, которые указывают состояние системы. Чтобы рекурсивно перечислить все зависимости, добавьте флаг --all.

Чтобы отобразить обратные зависимости (модули, зависящие от указанного модуля), можно добавить в команду флаг --reverse. Другие полезные флаги --before и --after могут быть использованы для отображения модулей, которые зависят от указанного модуля, соответственно, перед ними и после.

Проверка свойств модуля

Чтобы увидеть свойства более низкого уровня модуля, можно использовать команду show. При этом будет выведен список свойств, заданных для указанного модуля с помощью формата key=value:

systemctl show sshd.service Output
Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .

Если вы хотите отобразить одно свойство, можно передать флаг -p с именем свойства. Например, чтобы увидеть конфликты, которые есть у модуля sshd.service, можно ввести следующее:

systemctl show sshd.service -p Conflicts Output
Conflicts=shutdown.target

Маскировка и снятие маскировки модулей

В разделе управления службами мы узнали, как остановить или отключить службу, но systemd также имеет возможность отметить модуль как полностью незапускаемый, автоматически или вручную, связав его с /dev/null. Это называется маскировкой модуля, и она возможна с помощью команды mask:

sudo systemctl mask nginx.service

Это не позволит запустить службу Nginx автоматически или вручную, пока она замаскирована.

Если вы проверите list-unit-files, вы увидите, что служба теперь указана как замаскированная:

systemctl list-unit-files Output
. . .
kmod-static-nodes.service              static  
ldconfig.service                       static  
mandb.service                          static  
messagebus.service                     static  
nginx.service                          masked
quotaon.service                        static  
rc-local.service                       static  
rdisc.service                          disabled
rescue.service                         static
. . .

Если вы попытаетесь запустить службу, вы увидите следующее сообщение:

sudo systemctl start nginx.service Output
Failed to start nginx.service: Unit nginx.service is masked.

Чтобы снять маскировку модуля и сделать его доступным для использования снова, используйте команду unmask:

sudo systemctl unmask nginx.service

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

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

Несмотря на то, что конкретный формат файлов модулей выходит за рамки этого руководства, systemctl предоставляет встроенные механизмы для редактирования и модификации файлов модулей при необходимости изменений. Эта функция добавлена в версию systemd 218.

Команда edit по умолчанию откроет фрагмент файла модуля для интересующего модуля:

sudo systemctl edit nginx.service

Это будет пустой файл, который можно использовать для переопределения или добавления директив в определение модуля. Каталог будет создан в каталоге /etc/systemd/system, который содержит название модуля с добавлением .d. Например, для nginx.service будет создан каталог под названием nginx.service.d.

В этом каталоге будет создан фрагмент под названием override.conf. При загрузке модуля systemd в памяти соединит фрагмент переопределения с полным файлом модуля. Директивы фрагмента получат приоритет над найденными в оригинальном файле модуля.

Если вы хотите редактировать весь файл модуля, а не создавать фрагмент, можно передать флаг --full:

sudo systemctl edit --full nginx.service

Это загрузит текущий файл модуля в редактор, где его можно редактировать. После выхода из редактора измененный файл будет записан в /etc/systemd/system, что будет иметь приоритет над определением модуля системы (обычно находится где-то в /lib/systemd/system).

Чтобы удалить какие-либо сделанные добавления, удалите либо каталог конфигурации модуля .d или модифицированный служебный файл из /etc/systemd/system. Например, для удаления фрагмента можно ввести следующее:

sudo rm -r /etc/systemd/system/nginx.service.d

Чтобы удалить весь отредактированный файл модуля, добавим:

sudo rm /etc/systemd/system/nginx.service

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

sudo systemctl daemon-reload

Настройка состояния системы (уровень запуска) с помощью целей

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

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

Например, swap.target используется для указания того, что переключение готово к использованию. Модули, являющиеся частью этого процесса, могут синхронизироваться с этой целью путем указания в своей конфигурации, что они WantedBy= или RequiredBy= swap.target. Модули, которым требуется возможность переключения, могут указывать это состояние с помощью спецификаций Wants=, Requires= и After= для указания характера их отношений.

Получение и настройка цели по умолчанию

Процесс systemd имеет цель по умолчанию, которую он использует при загрузке системы. Удовлетворение каскада зависимостей от этой одной цели приведет систему в желаемое состояние. Чтобы найти цель по умолчанию для вашей системы, введите:

systemctl get-default Output
Multi-user.target

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

sudo systemctl set-default graphical.target

Список доступных целей

Вы можете получить список имеющихся целей в вашей системе, введя:

systemctl list-unit-files --type=target

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

systemctl list-units --type=target

Изолирование целей

Можно запустить все модули, связанные с целью, и остановить все модули, не являющиеся частью дерева зависимостей. Команда, необходимая для этого, называется соответственно isolate. Она аналогична изменению уровня запуска в других системах инициализации.

К примеру, если вы работаете в графической среде с активным graphical.target, можно закрыть графическую систему и перевести систему в состояние многопользовательской командной строки путем изоляции multi-user.target. Поскольку graphical.target зависит от multi-user.target, а не наоборот, все графические модули будут остановлены.

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

systemctl list-dependencies multi-user.target

Если вы удовлетворены модулями, которые будут сохранены в активном состоянии, можно изолировать цель, введя:

sudo systemctl isolate multi-user.target

Использование комбинации быстрого ввода для важных событий

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

Например, чтобы перевести систему в режим спасения (один пользователь), можно использовать команду rescue вместо isolate rescue.target:

sudo systemctl rescue

Это обеспечит дополнительную функцию предупреждения всех подключенных пользователей о событии.


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

sudo systemctl halt

Для инициализации полного отключения можно использовать команду poweroff:

sudo systemctl poweroff

Перезапуск можно начать с помощью команды reboot:

sudo systemctl reboot

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

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

sudo reboot

Заключение

К этому моменту вы должны уже ознакомиться с некоторыми базовыми возможностями команды systemctl, которая позволяет взаимодействовать и контролировать экземпляр systemd. Утилита systemctl будет главной точкой взаимодействия для управления службами и состоянием системы.

Хотя systemctl работает главным образом с основным процессом systemd, в экосистеме systemd есть другие компоненты, которые контролируются другими утилитами. Другие возможности, такие как управление журналами и сеансы пользователя, обрабатываются отдельными демонами и утилитами управления (journald/journalctl и logind/loginctl соответственно). Знакомство с этими другими инструментами и демонами упростит задачу управления.

Новости
27 декабря 202327.12.2023
Продуктовый дайджест 2023
20 декабря 202320.12.2023
читать 2 минутычитать 2 мин
Новые тарифы и возможности