systemd: основные приемы работы с юнит-файлами
Оригинал: systemd unit file basics
Автор: Bryan Sutherland
Дата публикации: 28 октября 2015 г.
Перевод: А.Панин
Дата перевода: 12 ноября 2015 г.
Добро пожаловать в серию статей о системе инициализации systemd, в которой мы разбираемся с тем, как работает эта центральная часть вашей системы Fedora. В данной статье речь пойдет о юнит-файлах ( unit files ).
Являясь пользователем дистрибутива Fedora с большим опытом, я до недавнего времени особо не задумывался о том, как на самом деле работает система инициализации systemd. Система инициализации systemd разделена на множество программных компонентов, что значительно упрощает процедуру управления компонентами вашей системы. systemd использует юнит-файлы для конфигурации и управления системными ресурсами, такими, как процессы и ваша файловая система. Благодаря этим файлам вы можете использовать systemd для конфигурации вашей системы Fedora в соответствии с вашими пожеланиями.
Юнит-файлы: что это такое?
Юнит-файлы в вашей системе описывают параметры системы инициализации systemd, которая используется в процессе ее загрузки и работы. Каждый из файлов соответствует отдельному действию или компоненту — или юниту ( unit ) в терминологии systemd. Каждый из юнит-файлов является простым текстовым файлом с описанием юнита, его назначения, операций, которые должны быть выполнены до и после его запуска, а также других деталей.
Юнит-файлы могут храниться в нескольких различных директориях вашей файловой системы. systemd осуществляет поиск системных юнит-файлов в директориях в следующей последовательности:
Юнит-файлы из директорий, расположенных выше в списке, имеют приоритет перед юнит-файлами с аналогичными именами из директорий, расположенных ниже в списке. Эта схема является довольно удобной, так как она позволяет вам вносить изменения в файлы из директории /etc, которая как раз предназначена для хранения файлов конфигурации системы. Вы должны по возможности избегать внесения изменений в файлы из директории /usr. Данная директория предназначена для хранения неизменных файлов, поставляющихся в комплекте с приложениями.
Также systemd может работать в контексте пользователей и управлять ресурсами отдельных пользователей, в дополнение управлению ресурсами системы. Юнит-файлы пользовательских юнитов по аналогии хранятся в директориях /etc/systemd/ , /run/sustemd/ и /usr/lib/systemd/ . Упомянутые директории имеют аналогичный приоритет.
Вы можете получить информацию об этих юнит-файлах с помощью команды systemctl . Если вы хотите увидеть список всех юнит-файлов, установленных в вашей системе, выполните следующую команду:
Каждый юнит-файл содержит пары параметр-значение в формате ИмяПараметра=значение , разделенные на секции, выделенные с помощью заголовков в формате [ИмяСекции] . Эти пары параметр-значение описывают принцип работы юнита, а также способ взаимодействия systemd с ним.
Существует множество типов юнитов, которые известны systemd. Двумя наиболее часто используемыми типами юнитов, с которыми приходится работать пользователям систем, являются юниты служб ( service units ) и юниты целей ( target units ). Для вывода списка юнит-файлов вашей системы каждого из типов следует использовать команду systemctl :
Юниты служб
Данные юниты описывают процесс, который может быть запущен и отслеживаться с помощью systemd. Юниты служб являются наиболее часто используемыми юнитами при повседневной работе с системой. Управление данными юнитами может осуществляться с помощью команды systemctl от лица пользователя root:
- start : запускает службу, представленную в виде юнита systemd
- stop : пытается «корректно» завершить работу службы
- status : выводит подробную информацию о состоянии службы
- restart : перезапускает (завершает работу и впоследствии запускает) указанную службу
- enable : активирует юнит-файл (создает символьные ссылки) в различных директориях для запуска службы в процессе загрузки системы
- disable : деактивирует юнит-файл (удаляет символьные ссылки) для того, чтобы соответствующая служба не запускалась автоматически
В следующем примере приведено содержимое юнит-файла sshd.service . Он позволяет systemd управлять демоном sshd, который предназначен для обеспечения удаленного доступа к вашей системе по протоколу SSH (Secure Shell).
Этот юнит-файл содержит как часто используемые, так и специфичные для юнита данной службы параметры. Часто используемыми параметрами, использованными в данном файле, являются описание службы и информация о расположении документации. Разумеется, в данном файле используются и такие параметры, которые не будут описаны в данной статье. Но вы наверняка догадаетесь, что параметр ExecStart , к примеру, предназначен для запуска демона sshd при активации юнита.
Процессы системных служб
Одной интересной возможностью systemd является механизм мониторинга состояния процессов, которые запускаются после активации юнитов служб. Для того, чтобы узнать, мониторинг каких процессов осуществляется, следует использовать команду systemctl status . Например, ниже приведен вывод этой команды при проверке состояния юнита sshd.service :
Очевидно, что процесс, запущенный при активации данного юнита, имеет идентификатор (PID) 1090. Мониторинг состояния процесса силами systemd будет продолжаться и после использования данной команды.
Обратите внимание на то, что при запуске службы данный процесс был помещен в группу управления с соответствующим именем. Группа управления (control group или «cgroup») позволяет systemd осуществлять управление группами ассоциированных процессов. В следующих статьях серии мы поговорим о том, как данная возможность может использоваться для регулирования производительности и установки ограничений ресурсов для процессов служб.
Благодаря наличию информации о процессах каждой из служб, systemd может помочь вам при работе с некорректно работающими службами. Обычно при остановке службы используется команда systemctl , как упоминалось ранее. Например, для остановки службы веб-сервера может использоваться следующая команда:
Но что случится в том случае, если служба не ответит на запрос завершения работы и не будет каким-либо образом взаимодействовать с systemd? Для таких случаев утилита systemctl предоставляет встроенную реализацию команды kill :
Юниты целей
Юниты целей используются для связывания и группировки других юнитов с целью описания соответствующего состояния системы. Некоторые из этих юнитов могут быть юнитами служб. Другие юниты могут быть дополнительными юнитами целей со своими собственными группами юнитов.
Ниже приведен пример содержимого файла юнита цели multi-user.target .
Обратите внимание на то, что этот файл юнита цели не содержит команды для исполнения. Вместо нее он содержит списки юнитов (в данном случае в основном юнитов целей) и используется для объединения этих юнитов. Данный файл описывает следующее правила:
- Цель multi-user.target требует, чтобы была успешно достигнута цель basic.target .
- В том случае, если исполняется служба, соответствующая юниту rescue.service , или достигнута цель, соответствующая юниту rescue.target , данный юнит будет остановлен и наоборот.
- Достижение цели multi-user.target начинается сразу после начала инициирования достижения цели basic.target и после запуска службы rescue.target и достижения цели rescue.target в случае активации последних.
Кроме того, данный юнит цели содержит параметр AllowIsolate . Этот параметр позволяет вашей системе рассматривать юнит цели multi-user.target в качестве цели процесса загрузки системы благодаря выполнению команды systemctl isolate .
Юниты целей позволяют группировать другие юниты не только на основе содержимого соответствующих файлов юнитов. Файл юнита цели может использовать директорию .wants для размещения ссылок на юниты, которые должны запускаться вместе с юнитом цели. Например, файл /usr/lib/systemd/system/multi-user.target имеет ассоциированную директорию /usr/lib/systemd/system/multi-user.target.wants . Эта директория содержит ссылки на юниты (не только юниты служб, но и юниты других целей), которые будут исполняться при инициировании достижения соответствующей цели. Каждый из этих юнитов может иметь свои зависимости, а также такие параметры, как приведенный выше параметр Requires, позволяющий указать юниты, которые должны быть запущенны для запуска рассматриваемого юнита.
Полезные информационные ресурсы
Вы можете воспользоваться страницей руководства для ознакомления с подробным описанием стандартных параметров секции Unit файлов юнитов:
Также существует документация, относящаяся к файлам юнитов служб и целей. Вы можете ознакомится с ней, выполнив следующие команды:
Если вы ищете дополнительную информацию о приемах работы с процессами и группами управления с использованием инструментов systemd, ознакомьтесь с данной полезной записью из блога автора systemd .
Источник
/4te.me
Здесь покажу как писать инитники для автозапуска какого-либо демона в системе с systemd.
Systemd оперирует unit-файлами в качестве конфигурационных файлов. Это как .conf-файл для upstart или init-скрипты для initd. Unit-файлы также могут описывать и другие системные сущности, но в данном случае они нас интересуют как конфиг для автостарта сервиса. В Ubuntu 16.04 они лежат в /etc/systemd/ . Напишем свой unit-файл.
Допустим у нас есть программа, которую мы хотим запускать как демон. Вот здесь я писал как создать telegram-бота. У меня получился исполняемый файл, который запускается и висит ждет сообщений. Теперь хочу чтобы он как демон стартовал при загрузке системы.
Создаем такой файл:
и кладем его в /etc/systemd/system/telegram-bot.service
Конфиг похож на обычный ini-файл:
After — запускать этот юнит после определенных демонов или целей (цель — это набор юнитов). Здесь указан network.target , это значит, что демон запустится после того как поднимутся сетевые интерфейсы.
Type — тип того, как запускается демон. Чаще всего используется simple , forking или one-shot . simple — демон запускается и начинает ожидать на консоле и не отфоркивается. forking — демон запускается, потом форкается и завершает родительский процесс. Многие программы именно так и запускаются, чтобы перейти в background режим. Например, nginx запускается по такой схеме. one-shot — используется для запуска скриптов которые запускаются, отрабатывают и завершаются. В моем случае это не скрипт и программа не форкается , поэтому тип — simple
ExecStart — команда для запуска демона.
Restart — рестартовать демон, если он завершится/упадет. При always systemd будет перезапускать демон независимо от того почему он завершился. Можно указать on-failure , тогда будет перезапускаться если демон вышел с ненулевым кодом возврата или был завершен по сигналу (kill DAEMONPID)
WantedBy — говорим, что запускать этот демон когда система грузится в multi-user режиме
Далее делаем релоад systemd:
И добавляем созданный юнит в автозагрузку:
Все. Сервис добавлен в автозагрузку, но еще не запущен. Запустим:
Источник
Systemd за пять минут
Наша компания занимается администрированием веб-серверов на базе CentOS. Довольно часто наши клиенты используют веб-приложения на базе python, ruby или java. Для автозапуска подобных приложений есть готовые шаблоны для написания стартап-скриптов. Но прогресс не стоит на месте, вышел уже второй релиз CentOS 7 и, следуя старой традиции «не ставить dot-zero релизы на продакшен», мы начинаем предлагать клиентам сервера на базе CentOS 7.1 (1503).
В CentOS7, так же как и в его родителе RHEL7, используется systemd — менеджер системы и служб для Linux, совместимый со скриптами инициализации SysV и LSB. systemd обеспечивает возможности агрессивной параллелизации и много всего прочего.
Огромный монстр с множеством возможностей, гибкими настройками и мегабайтами документации…
Но что делать, если стоит задача быстро-быстро, вот прямо вчера, сделать автозапуск некоего сервиса?
Давайте выжмем из документации минимально необходимый набор информации для создания простых старт-стоп скриптов.
Systemd запускает сервисы описанные в его конфигурации.
Конфигурация состоит из множества файлов, которые по-модному называют юнитами.
Все эти юниты разложены в трех каталогах:
/usr/lib/systemd/system/ – юниты из установленных пакетов RPM — всякие nginx, apache, mysql и прочее
/run/systemd/system/ — юниты, созданные в рантайме — тоже, наверное, нужная штука
/etc/systemd/system/ — юниты, созданные системным администратором — а вот сюда мы и положим свой юнит.
Юнит представляет из себя текстовый файл с форматом, похожим на файлы .ini Microsoft Windows.
[Название секции в квадратных скобках]
имя_переменной = значение
Для создания простейшего юнита надо описать три секции: [Unit], [Service], [Install]
В секции Unit описываем, что это за юнит:
Названия переменных достаточно говорящие:
Далее следует блок переменных, которые влияют на порядок загрузки сервисов:
Запускать юнит после какого-либо сервиса или группы сервисов (например network.target):
After=syslog.target
After=network.target
After=nginx.service
After=mysql.service
В итоге переменная Wants получается чисто описательной.
Если сервис есть в Requires, но нет в After, то наш сервис будет запущен параллельно с требуемым сервисом, а не после успешной загрузки требуемого сервиса
В секции Service указываем какими командами и под каким пользователем надо запускать сервис:
(по умолчанию): systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы.
systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. Данный тип используется для запуска классических демонов.
Также следует определить PIDFile=, чтобы systemd могла отслеживать основной процесс:
Команды на старт/стоп и релоад сервиса
ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb —daemon
ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart
Тут есть тонкость — systemd настаивает, чтобы команда указывала на конкретный исполняемый файл. Надо указывать полный путь.
Таймаут в секундах, сколько ждать system отработки старт/стоп команд.
Попросим systemd автоматически рестартовать наш сервис, если он вдруг перестанет работать.
Контроль ведется по наличию процесса из PID файла
В секции [Install] опишем, в каком уровне запуска должен стартовать сервис
multi-user.target или runlevel3.target соответствует нашему привычному runlevel=3 «Многопользовательский режим без графики. Пользователи, как правило, входят в систему при помощи множества консолей или через сеть»
Вот и готов простейший стартап скрипт, он же unit для systemd:
myunit.service
Кладем этот файл в каталог /etc/systemd/system/
Смотрим его статус systemctl status myunit
Видим, что он disabled — разрешаем его
systemctl enable myunit
systemctl -l status myunit
Если нет никаких ошибок в юните — то вывод будет вот такой:
Запускаем сервис
systemctl start myunit
Смотрим красивый статус:
systemctl -l status myunit
Если есть ошибки — читаем вывод в статусе, исправляем, не забываем после исправлений в юните перегружать демон systemd
Источник