как создать сервис linux

У меня появился Linux на домашнем компьютере, и я поспешил обжиться в новой ОС. Она была установлена с systemd init process. Это было мое первое знакомство с этим новым инструментом. Cвой ноутбук я использую для каждодневной жизни и для программирования. Мне хотелось включать рабочие программы (Apache2 и MySQL) только на время, пока я их использую, чтобы не тратить впустую ресурсы своего компьютера. Дополнительно, для тестирования я написал bash скрипт, который выгружает содержимое одной из MySQL БД c жесткого диска в ОЗУ (в tmpfs) – так тесты выполняются значительно быстрее. По идее, я мог бы начинать свой рабочий день вот так:

Но мне хотелось сделать вещи “как надо”.

Чего я хотел?

Что я сделал?

В итоге я объединил Apache2 и MySQL в один target. Это позволило запускать оба сервиса одной командой. А свой mysqld-tmpfs скрипт я декларировал в виде сервиса в глазах systemd. Будучи сервисом, я уверен, что systemd выполнит его корректную остановку, если система пойдет на перезагрузку или еще в какую-то нештатную ситуацию, и моя БД без потерь сохранится на жесткий диск.

Что такое service?

Это некоторая программа, которая выполняется в фоне и предоставляет полезную функциональность. К примеру, Apache веб сервер. Сервисы можно запускать и останавливать. Некоторые сервисы могут запускаться и останавливаться автоматически по определенным событиям (загрузка ОС, выгрузка ОС и тп). Так же их можно запускать/останавливать вручную. Сервис декларируется в /etc/systemd/system/my-name.service файлах (с суффиксом “.service”).

Что такое target?

Target в systemd очень похож на runlevel в openRC, но это все-таки разные вещи. Во-первых, target позволяет группировать 1 и более сервисов в единый блок. Группируя сервисы в targets, ими проще управлять. Во-вторых, systemd автоматически включает/выключает targets по событиям. “Включение” target означает включение всех сервисов, которые он объединяет в себе. К примеру, если в systemd настроен target по умолчанию my-favorite.target, то при загрузке системы systemd включит все сервисы, которые задекларированы внутри my-favorite.target. В какой-то момент в консоли можно набрать:

Все сервисы из my-another.target будут включены, и все включенные сервисы не из my-another.target будут выключены. Это очень похоже на переключение runlevel в openRC. Однако, systemd поддерживает включение более чем 1 target. Вот пример:

После выполнения этих команд в системе будет работать объединение сервисов из my-favorite.target и my-another.target.

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

В итоге у меня получился вот такой mysqld-tmpfs.service файл:

И вот такой programming.target файл:

Какие были проблемы?

Декларации “чужих” сервисов можно менять создавая файлы /etc/systemd/system/name-i-alter.service.d/*.conf. Я просто создал /etc/systemd/system/apache2.service/auto-stop.conf и /etc/systemd/system/mysqld.service.d/auto-stop.conf и поместил туда ту строку.

Другая проблема, на которую я, наткнулся была в том, что systemd не очень любит symlinks. Я не большой любитель “загаживать” системные директории типа /etc, /bin, /usr своими локальными продуктами жизнедеятельности, поэтому изначально я попытался свой /etc/systemd/system/mysqld-tmpfs.service сделать symlink на /root/scripts/mysqld-tmpfs.service файл, т.е. хранить сам файл в домашнем каталоге root пользователя. Но systemctl команда отказывалась работать с таким сервисом выдавая малопонятные ошибки. Оказалось, что определенную часть своей внутренней кухни systemd делает именно на symlinks, и ему тогда “трудно” отличать внутреннюю кухню (свои symlinks) от сторонних *.service файлов (если они тоже являются symlinks). Удалив symlink из /etc/systemd/system/mysqld-tmpfs.service и скопировав туда содержимое настоящего файла, я решил эту проблему. Более подробное описание этой проблемы можно прочитать тут: bugzilla.redhat.com/show_bug.cgi?id=955379

Результат

Я достиг своей цели. Начиная рабочий день:

Когда нужно выполнить тесты на своем проекте:

Когда я хочу демонтировать БД из tmpfs в жесткий диск (хотя на практике я так почти не делаю, а просто оставляю БД в tmpfs на целый день, и при выключении systemd за меня запускает демонтировку из tmpfs в жесткий диск):

Когда я закончил работать и хочу остановить рабочие программы:

Cheat sheet

Надеюсь, эта статья кому-то поможет при осваивании systemd. Я попытался сделать ее компактной, и если упустил из внимания какие-то дополнительные вопросы, спрашивайте в комментариях!

Источник

Как создать свой сервис для Linux

как создать сервис linux. Смотреть фото как создать сервис linux. Смотреть картинку как создать сервис linux. Картинка про как создать сервис linux. Фото как создать сервис linux

Основы создания сервиса Linux

Если вы еще никогда не делали свои сервисы, начнем с основ. Systemd оперирует абстрактными единицами (unit), которые бывают разных типов, могут предоставлять различные ресурсы (процессы, сокеты, абстрактные «цели») и требовать других ресурсов для запуска.

Сервисы типа oneshot — долой rc.local

Когда-то основным способом добавить выполнение команд в загрузку системы было дописать их в /etc/rc.local. Очевидный недостаток — нет способов следить, насколько успешно они выполнились. В systemd легко создать для такой цели свой сервис типа oneshot, и им можно будет управлять через systemctl, как любым другим. В этом случае systemd выполнит команду и посчитает запуск сервиса успешным, если она завершилась с кодом ноль.

Сохраним следующий файл в /lib/systemd/system/dumb-test.service :

Создание сервиса из любой программы

Для демонстрации напишем программу на Python, которая просто выводит сообщение в бесконечном цикле. Сохраним в /usr/local/bin/test.py следующее:

Затем создадим для нее файл сервиса в /lib/systemd/system/smart-test.service :

Теперь можно запустить наш сервис и убедиться, что он работает:

Зависимости и порядок запуска

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

Порядок запуска сервисов

Однако опция After=bar.service сама по себе не поставит сервис на загрузку. Более того, она никак не повлияет на решение запускать foo, даже если запуск bar завершится неудачей.

Причина существования этих опций — способность systemd запускать сервисы параллельно.

Для примера возьмем типичный веб-сервер с набором из веб-приложения FCGI, СУБД и обратного прокси. В каком порядке запускать процесс FCGI и обратный прокси, не так важно. Запросы будут работать, только когда они оба запущены, но «неверный порядок» никак не помешает им запуститься.

Зависимости

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

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

Внедрение в зависимости к чужим сервисам

В системах с System V init добавить что-то в зависимости к чужому сервису можно было, лишь отредактировав его скрипт. Такие изменения, очевидно, не переживут обновления системы, поэтому сделать их постоянными можно было бы только пересборкой пакета.

Источник

Добавить сервис в systemd

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

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

Для примера мы установили OpenVPN, для которого по умолчанию используется механизм запуска System V. Во время установки пакета в каталог /etc/init.d будет скопирован скрипт инициализации, который будет отвечать за автоматический запуск приложения после перезагрузки. Если в один прекрасный день OpenVPN упадет, без дополнительных настроек, нужно будет каждый раз запускать этот процесс вручную.

Секция [Unit]

Далее указываем порядок загрузки, после какого сервиса systemd запустить наш юнит:

Секция [Service]

Задаем тип сервиса:

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

Указывают если служба запускается однократно и процесс разветвляется с завершением родительского процесса.

Рабочий каталог приложения:

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

Задаем приоритет убийства процесса при нехватке памяти:

Команды запуска, остановки и перезапуска сервиса:

Таймаут запуска или остановки сервиса:

Контроль запуска сервиса и автоматический запуск в случае крєша:

Секция [Install]

Уровень запуска сервиса:

В итоге мы получили следующий юнит:

Добавляем юнит в каталог:

Включаем, запускаем и смотрим статус юнита:

А теперь привожу примеры работающих юнитов.

Источник

Меня бесит, что я всегда спокоен

Как создать свою службу в Linux

Шаг 1. Создание скрипта

Вот шаблон, чтобы не запутаться:

Шаблон от разработчиков находится по адресу /etc/init.d/skeleton

Обратите внимание на блок, ограниченный метками [ ### BEGIN INIT INFO ] и [ ### END INIT INFO ]. Он выделен жирным.

Этот блок полностью закомментирован, то есть при выполнении скрипта его содержимое игнорируется. Однако, он содержит инструкции для утилиты update-rc.d, которая прочитает их, поймёт и раскидает ссылки на этот скрипт по уровням запуска системы.

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

Этот блок обязателен для скрипта, управляющего сервисом. Остановимся на нём подробнее.

Все строки между ними должны быть в формате:

# Инструкция: арг1 [арг2. ]

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

Список инструкций
Данный список взят по одной из ссылок в конце записи, описания нуждаются в доработке

Уровни запуска определяют, в какие из каталогов /etc/rcX.d будут помещены ссылки на текущий скрипт.

Для отслеживания зависимостей важны инструкции Provides, Required- и Should-. Остальные не используются. На основе зависимостей утилита update-rc.d (или insserv) упорядочивает скрипты в каталоге определённого уровня запуска ( /etc/rcX.d ).

Список виртуальных объектов
Та же хрень, что и с предыдущим списком

Шаг 2+3. Оформление скрипта в качестве службы

Допустим, имя нашего самописного скрипта somestuff. Именно так, somestuff, без всяких расширений.
Делаем его исполняемым:

Копируем в хранилище сервисных скриптов:

И делаем прописку в каталогах уровней запуска:

update-rc.d somestuff defaults

Полный путь давать не надо, только имя в /etc/init.d/

Для выписки (удаления всех симлинков на этот скрипт из всех каталогов уровней запуска) делаем:

Источник

Как создать сервис linux

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

Юниты systemd и их разновидности.

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

В контексте systemd юниты — это отдельные объекты, которыми управляет эта система. Как и игровые войска, они имеют свои разновидности, у каждой из которых есть свое предназначение. Если вы читали предыдущие статьи, то знаете как минимум одну разновидность таких объектов — сервисы. Вот некоторые другие виды юнитов, о которых я, возможно, расскажу в следующих статьях:

Основными директориями для хранения юнитов в Ubuntu 16.04 являются:

Скриншот выше демонстрирует содержимое директории с файлами юнитов.

Файлы юнитов содержат разделы с набором параметров и их значений, разделенных знаком «=». Слева название параметра, справа значение, все предельно просто. Для начала создадим файл с названием my_backup.service и поместим его в /etc/systemd/system. Впишем в него следующие строки:

Идея этого решения принадлежит человеку с ником mezcalero из IRC чата systemd.

Давайте разберем представленный выше код.

Раздел [Unit] хранит общие сведения о юните. В данном случае он содержит только описание (Description).

Раздел [Service] объединяет сведения, необходимые для выполнения юнитом его задач. Type определяет тип сервиса (не путайте его с разновидностями юнитов), oneshot означает, что сервис должен выполнить разовую задачу и завершиться. ExecStop указывает скрипт, который должен быть выполнен перед остановкой сервиса. Есть еще ExecStart, этот параметр используется чаще и определяет команду, которая должна быть выполнена сразу после запуска сервиса. RemainAfterExit=true предписывает systemd считать процесс активным после его завершения.

Секция [Install] содержит сведения о том, при каких обстоятельствах должен быть запущен сервис. WantedBy=multi-user.target устанавливает запуск при обычной загрузке компьютера.

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

Приведенный выше код нужно поместить в файл /usr/local/bin/my_backup, а затем сделать его исполняемым:

Хотя наш скрипт совсем простой, давайте все же разберем его. Первая строка — обязательное начало любого bash скрипта. Вторая получает текущую дату и время в определенном нами формате и помещает ее в переменную current_date. Третья запускает архиватор и сообщает ему, что и куда архивировать. Кстати, не забудьте подставить свои пути вместо русского текста.

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

Перезагрузите компьютер и проверьте, появился ли архив в указанном месте.

По желанию можно настроить сохранение резервных копий вне локального компьютера, например, в облачном хранилище. В этом случае может потребоваться проверка подключения к сети и доступности самого хранилища. Можно также настроить создание резервных копий не перед выключением, а по расписанию с помощью юнита timer. Возможно, в следующих статьях я продолжу эту тему и покажу, как это можно сделать, а заодно — продемонстрирую работу юнитов других типов.

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

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

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

Источник

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *