mail@vecdev.ru

Шпаргалка по управлению сервисами CentOS 7 с помощью systemd

Иконка systemd

systemd – подсистема инициализации и управления службами в операционной системе Linux. Сразу договоримся, что инициализация - это действия, совершаемые при загрузке системы. Systemd спроектирован обратно совместимым со скриптами инициализации SysV init и, одновременно, предоставляет дополнительные функции, такие как параллельный запуск системных сервисов во время загрузки, активацию демонов по требованию, поддержку логики управления сервисами, основанной на зависимостях и реакции на изменение состояния.

Кстати, именно это является главной причиной ненависти некоторых людей к systemd - нарушения принципа "unix-way".

Примечание: unix-way - принцип, согласно которому, одна программа - одна функция. Т.е. каждая программа должна выполнять одну функцию, но делать это достаточно хорошо, а не иметь 100500 плохо написанных функций.

В этой статье мы рассмотрим основы управления сервисами в systemd для пользователя CentOS 7 версии.

Вводная часть

systemd написана немецким программистом Леннартом Поттерингом с целью избавления от shell-скриптов SysV init, распараллеливания загрузки операционной системы и создания единой точки контроля всего происходящего в операционной системе.

Подсистема оперирует специально оформленными файлами конфигурации — модулями (англ. unit). Файлы модулей располагаются в одной из следующий директорий (в порядке приоритета):

  • /etc/systemd/system/ — модули, созданные и управляемые системным администратором;
  • /run/systemd/system/ — модули, созданные динамически (т.е. на лету);
  • /usr/lib/systemd/system/ — модули из установленных пакетов RPM (поставляемые вместе с приложениями).

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

На сегодняшний день systemd поддерживает следующие типы модулей:

  • .target — позволяет группировать модули, воплощая концепцию уровней запуска (т.н. runlevels);
  • .service — аналог демона или что-либо, что можно запустить;
  • .mount — отвечает за монтирование файловых систем (имя юнита должно соотвествовать пути до точки монтирования);
  • .automount — позволяет отложить монтирование файловых систем до фактического обращения к точке монтирования (должен существовать *.mount-юнит с тем же именем);
  • .swap — отвечает за подключение файла или устройства подкачки;
  • .timer — позволяет запускать модули по расписанию, аналог cron (по умолчанию запускаться будет *.service-юнит с тем же именем);
  • .socket — предоставляет службам поддержку механизма сокет-активации, аналог xinetd. Запуск юнита при подключении к указанному сокету (по умолчанию запускаться будет *.service-юнит с тем же именем);
  • .slice — группирует другие юниты в дереве cgroups, позволяя иерархично задавать ограничения по используемым ресурсам;
  • .device — позволяет реагировать на подключение устройств (имя юнита генерируется из sysfs-имени устройства);
  • .path — запуск юнита по событию доступа к какому-либо пути в файловой системе (по умолчанию запускаться будет *.service-юнит с тем же именем).

Примечение: cgroups - это способ объединения процессов, чтобы установить для них какие-то правила или ограничения. Например, ограничения на процессор или память.

Основные функции systemd

Помимо простого запуска и контроля служб, systemd предлагает некоторые другие удобные функции, для использования которых ранее системным администраторам приходилось прибегать к помощи дополнительных программ-демонов.

Среди таких функций:

  • сокет-активация служб (заменяет inetd);
  • запуск сервисов по расписанию (заменяет cron);
  • работа с аппаратным сторожевым таймером (заменяет watchdog);
  • смена корня (заменяет chroot);
  • автомонтирование томов и сетевых ресурсов (заменяет mount и fstab);
  • journalctl — служба журналирования;
  • systemd-analyze — анализ скорости запуска служб;
  • systemd-boot — UEFI загрузчик (замена grub).

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

В предыдущих версиях CentOS использовалась SysV или Upstart. Скрипты инициализации располагались в директории /etc/rc.d/init.d/. Такие скрипты обычно писались на Bash и позволяли администратору управлять состоянием сервисов и демонов. В CentOS 7 скрипты инициализации были заменены сервисными юнитами.

По способу использования сервисные юниты .service напоминают скрипты инициализации. Для просмотра, старта, остановки, перезагрузки, включения или выключения системных сервисов используется команда systemctl. Команды service и chkconfig по-прежнему включены в систему, но только по соображениям совместимости.

При использовании systemctl указывать расширение файла не обязательно.

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

  • systemctl start name.service — запуск сервиса;
  • systemctl stop name.service — остановка сервиса;
  • systemctl restart name.service — перезапуск сервиса;
  • systemctl try-restart name.service — перезапуск сервиса (только если он запущен);
  • systemctl reload name.service — перезагрузка конфигурации сервиса;
  • systemctl status name.service — проверка и вывод текущего состояния сервиса (запущен или нет);
  • systemctl is-active name.service — проверка, запущен ли сервис с простым ответом: active или inactive;
  • systemctl list-units --type service --all — отображение статуса всех сервисов;
  • systemctl enable name.service — активирует сервис (позволяет стартовать во время запуска системы);
  • systemctl disable name.service — деактивирует сервис;
  • systemctl reenable name.service — деактивирует сервис и сразу активирует его;
  • systemctl is–enabled name.service — проверяет, активирован ли сервис;
  • systemctl list-unit-files --type service — отображает все сервисы и проверяет, какие из них активированы;
  • systemctl mask name.service — заменяет файл сервиса симлинком на /dev/null, делая модуль недоступным для systemd;
  • systemctl unmask name.service — возвращает файл сервиса, делая модуль доступным для systemd.

Управление systemd на удаленной машине

systemd позволяет управлять удаленной машиной по SSH. Для управления служит команда:

systemctl --host user_name@host_name command

где user_name – имя пользователя, host_name – имя хоста, которым осуществляется удаленное управление, а command – выполняемая команда systemd.

Типичный systemd .service

В этом разделе рассмотрим пример написания простого сервиса systemd. За детальной информацией обо всех параметрах файла .service можно обратиться в соответствующий раздел документации по systemd (man systemd.service).

[Unit]
Description=Daemon to detect crashing apps
After=syslog.target

[Service]
ExecStart=/usr/sbin/abrtd
Type=forking

[Install]
WantedBy=multi-user.target

Посмотрим на секцию [Unit].

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

В секции [Service] содержится информация о том, что именно делает наш сервис.

Используемый параметр ExecStart указывает на исполняемый файл нашего сервиса. В Type мы указываем, как сервис уведомляет systemd об окончании запуска.

Финальная секция [Install] содержит информацию о цели, в которой сервис должен стартовать. В данном случае мы говорим, что сервис должен быть запущен, когда будет активирована цель multi–user.target.

Это минимальный работающий файл сервиса systemd. Написав свой, для тестирования поместите его в /etc/systemd/system/имя_сервиса.service.

Затем, выполните команду

systemctl daemon-reload

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

Разбираемся с зависимостями требования/порядка

Для примера рассмотрим модуль типа service - sshd.service

Можно просто открыть файл в текстовом редакторе или использовать утилиту cat, но гораздо удобнее сделать это средствами самого systemd:

systemctl cat sshd.service
Содержимое модуля sshd.service

Взглянем на содержимое раздела [Unit]. Параметр Description мы уже знаем.

After= и парный ему Before= это зависимости порядка. Все довольно просто и понятно, запускать данный юнит до или после указанных.

Wants= это так называемые зависимости требования. Всего их две, и второй – это Requires=.

И том и в другом случае, наш модуль хочет, чтобы сервис или программа, указанные в параметре (назовем его зависимым модулем), были запущенны, но при этом, если указано Wants=, то наш модуль не проверяет результат запуска зависимого модуля. Даже если зависимый модуль не смог запуститься. Requires= таких вольностей не прощает и просто прекратит запуск нашего модуля, если зависимый модуль вернул ошибку запуска.

В случае с сервисом sshd, будет предпринята попытка запуска зависимого модуля sshd-keygen, но исход запуска проверен не будет.

Важно!

Зависимости порядка и зависимости требования НЕ связаны между собой. В данном примере, сказано, что sshd.service должен запуститься после network.target. Однако, наш модуль не будет инициировать его запуск! Тем не менее, если по каким-то причинам network.target будет запущен (например, его запустил другой сервис), то и наш модуль будет запущен сразу после него.

Секция [Service] описывает тип юнита service. В других типах своё. Например, в юнитах типа socket есть секция [Socket].

ExecStart= указывает как запустить

ExecReload= указывает как перечитать конфиг

KillMode= описывает как будет убит процесс. Конкретно в этом случае сказано, что сигнал убийства будет послан только главному процессу, а как быть со своими потомками ему решать.

Restart= описывает когда сервис будет перезапускать процесс при падении (или других катаклизмах). В мане есть табличка, которая объясняет всё немного лучше.

Коды выхода и из влияние на директиву Restart

Секция [Install] используется командами systemctl enable/disable для добавления симлинка в нужный target.

Конкретно в этом случае, при выполнении команды

systemctl enable sshd.service

в папке multi-user.target будет создан симлинк на sshd.service и при выполнении данного target-a sshd будет запущен.

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

Но что, если мы хотим совсем выключить модуль, чтобы нельзя было запустить даже как зависимость? Для этого модули из /usr/lib/systemd/system и /run/systemd/system можно замаскировать командой

systemctl mask unit_name

Это команда создает симлинк на /dev/null в /etc/systemd/system с именем маскируемого модуля. Напомню, этот каталог имеет наивысший приоритет. Тут проявляется ограничение - нельзя замаскировать модуль из папки /etc/systemd/system.

Обратная команда

systemctl unmask unit_name

просто удаляет симлинк.

Заключение

В этой статье мы научились управлять сервисами CentOS 7.

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

Успешного использования CentOS 7!


Частный разработчик сайтов Vector Dev
Комментарии