Запускать любой исполняемый файл как службу Systemd в Linux
Вы когда-нибудь задумывались, как создать службу Linux для управления исполняемыми файлами?
Эта статья изначально была написана в моем личном блоге abhinand5.github.io
Иногда вы можете создать приложение, и по своей природе может быть важно, чтобы оно работало вечно. Например, серверная программа, в которой простои просто недопустимы, или агент, который всегда должен работать в фоновом режиме, не требуя какого-либо ручного вмешательства для запуска, остановки или перезапуска. Есть несколько способов сделать это — держать его работающим вечно. Но в этой статье я расскажу о стандартном Linux-способе сделать это — его также можно использовать в производственной среде. Конечно, я не говорю о (почти) самоуправляемых средах, таких как docker, AWS Lambda, Heroku и т. Д.… Речь пойдет только о простых старых серверах / рабочих столах Linux.
Что такое systemd?
Systemd — это системный менеджер и инструмент инициализации, который стал широко популярным в последние годы. Systemd также является системой инициализации по умолчанию в большинстве известных дистрибутивов Linux. Так что знание того, как создать службу в systemd , может быть не так уж и плохо. Некоторые из популярных дистрибутивов, которые по умолчанию работают на systemd, включают:
- Arch Linux
- Debian Jesse или новее
- CentOS 7 / RHEL 7 или новее
- Ubuntu 16.04 или новее
- Fedora 15 или новее
Основная цель системы инициализации, такой как systemd , — инициализировать компоненты, требующие внимания, после загрузки самого ядра Linux. Но он также предлагает механизм для управления системными службами и демонами, пока система работает, в форме systemctl , что и является тем, что нас интересует. Однако я не собираюсь слишком углубляться в детали того, как работает systemd, это само по себе требует нескольких статей.
Существует множество служб, которые ОС запускает в любой момент, например, служба настройки клавиатуры, которая позволяет использовать клавиатуру с желаемой раскладкой в консоли. Есть несколько из этих сервисов, которые всегда работают в фоновом режиме, чтобы вам было удобнее работать.
Вы можете увидеть список всех сервисов, используя команду ниже
$ systemctl list-units --type=service
Как видно из изображения выше, Postgres или любая другая система управления базами данных также работает в Linux как служба. Вы можете проверить статус любой услуги вот так,
$ systemctl status postgresql
Вы могли заметить, что системные службы заканчиваются расширением .service , это не что иное, как файлы, которые используются для определения службы в systemd . systemctl достаточно умен, чтобы понимать, что вы ищете услугу, и правильно отображать статус, однако вы можете добавить расширение .service в качестве хорошей практики.
Вы можете просмотреть содержимое служебного файла следующим образом:
Этот файл формально известен как файл модуля, который используется для описания системной службы. Об этом мы поговорим в следующем разделе.
Создание собственного сервиса systemd
Волшебный файл, который позволяет нам создать службу systemd, называется модульным файлом. Я говорю волшебный, потому что его намного проще написать и настроить. Для работающей службы этот файл должен присутствовать только в следующих каталогах
Это каталоги, из которых systemd будет загружать информацию. В основном нас интересует /etc/systemd/system , где могут находиться системные модули, созданные администратором.
В этой статье я буду использовать простой эхо-сервер, написанный на Python, который я преобразовал в двоичный файл с помощью pyinstaller , чтобы показать вам, как запустить исполняемый файл как службу. В качестве альтернативы мы также увидим, как напрямую запустить файл python из сценария оболочки и превратить его в службу systemd.
Вот простой сервер Python, который я использую,
На данный момент вы можете начать создание файла модуля здесь, а затем, наконец, когда это будет сделано, переместите его в /etc/systemd/system каталог.
Создание юнит-файла с названием вашего сервиса
Вы можете редактировать его любым редактором по вашему выбору, я буду использовать редактор inbuilt nano , чтобы не усложнять.
Мы можем начать с определения описания создаваемой нами услуги.
[Unit] Description=Service that keeps running the echo-server from startup.
Затем мы должны определить, когда служба должна запускаться (уровень выполнения).
[Install] WantedBy=multi-user.target
multi-user.target обычно определяет состояние системы, при котором все сетевые службы запущены и система принимает вход в систему, но локальный графический интерфейс не запускается. Это типичное состояние системы по умолчанию для серверных систем, которые могут быть монтируемыми в стойку безголовыми системами в удаленной серверной. Это просто еще один способ сказать, что служба должна запускаться на уровнях выполнения 3, 4 и 5.
Если для запуска вашей службы требуется подключение к Интернету, вам следует подождать, пока не будут установлены основные сетевые функции. Этого можно добиться, включив следующую строку в раздел [Unit] файла.
Теперь пора определить сам сервис, это делается в разделе [Service] файла модуля.
[Service] Type=simple ExecStart=/home/abhi/Dev/echo-server/server WorkingDirectory=/home/abhi/Dev/echo-server Restart=always RestartSec=5 StandardOutput=syslog StandardError=syslog SyslogIdentifier=%n
Теперь посмотрим, что делает каждая строка в этом разделе.
Это означает, что мы указываем, как запустить службу, используя ExecStart в следующей строке, где мы указываем путь к двоичному исполняемому файлу, который systemd будет использовать для запуска службы. Существуют также другие типы служб, например forking , которые используются, когда служба создает дочерний процесс, почти сразу же выходя из родительского процесса. Это говорит systemd , что процесс все еще выполняется, хотя родительский процесс завершился. Это наиболее часто используемые типы, о других типах вы можете ознакомиться в документации systemd .
WorkingDirectory=/home/abhi/Dev/echo-server
Вы также можете указать рабочий каталог службы, что необязательно.
Restart=always RestartSec=5
Это означает, что служба будет перезапущена автоматически через 5 секунд, если служба выйдет из строя или прервется в любое время. Это может быть особенно полезно для серверов и агентов, работающих в фоновом режиме.
StandardOutput=syslog StandardError=syslog SyslogIdentifier=%n
Приведенные выше строки помогают автоматически перенаправлять вывод службы в файл журнала.
Запуск Сервиса и его мониторинг
Теперь, когда юнит создан, мы можем переместить его в каталог /etc/systemd/system .
На скриншоте выше я перемещаю файл модуля в правильный каталог и проверяю его, передавая команду ls в каталоге systemd с именем файла созданного нами файла модуля.
Затем давайте перезагрузим systemctl , чтобы сделать наш новый файл модуля видимым.
$ sudo systemctl daemon-reload
Теперь включите нашу службу, используя команду ниже,
$ sudo systemctl enable echo-server.service
Если все настроено правильно, вы должны получить такой вывод, в котором говорится, что создана символическая ссылка.
Теперь, наконец, вы можете запустить свою службу с помощью этой команды,
$ sudo systemctl start echo-server.service
Это не выведет на терминал никаких выводов.
Затем попробуйте проверить статус службы с помощью этой команды,
$ sudo systemctl status echo-server.service
Если все работает правильно, вы сможете увидеть статус службы как активный и работающий. Поздравляю! Вы создали свою первую службу Linux.
Если вы хотите увидеть журналы службы,
$ journalctl -f -u echo-server.service
Теперь вы можете перезагрузиться, чтобы проверить, запускается ли служба автоматически.
Как видно на этом изображении, система загрузилась менее минуты назад, и мы видим, что служба запустилась автоматически всего 39 секунд назад, что впечатляет.
Запустить сценарий оболочки как службу (альтернатива)
Этот метод может быть полезен, если у вас нет отдельного исполняемого двоичного файла для вашего приложения. Сначала создайте сценарий оболочки, запускающий вашу программу. В этом случае мы должны написать команду python, которая выполняет нашу программу.
Создайте сценарий оболочки с именем по вашему выбору.
Теперь отредактируйте сценарий оболочки и добавьте команду, запускающую вашу программу.
#!/bin/bash SCRIPT_PATH=/home/abhi/Dev/echo-server/server.py PYTHON_PATH=/home/abhi/.local/bin/.virtualenvs/main/bin/python $PYTHON_PATH $SCRIPT_PATH exit 1
Вы можете знать путь к скрипту, но не знаете путь Python. Этот сценарий оболочки будет работать, даже если вы используете виртуальную среду Python (venv). Если вы не используете venv, просто выполните команду ниже, в противном случае активируйте venv, а затем выполните команду ниже, добавив вывод как PYTHON_PATH в сценарий оболочки.
Не забудьте разрешить исполняемому файлу скрипта, иначе это не сработает.
$ chmod +x start-echo-server.sh
Теперь сохраните этот сценарий оболочки и переместите его в /usr/sbin каталог. Почему там? Потому что именно здесь мы должны разместить общие общесистемные двоичные файлы, для запуска которых требуются права администратора.
$ sudo mv start-echo-server.sh /usr/sbin
Теперь вам нужно изменить только одну строку в файле модуля — ExecStart
В остальном процедура точно такая же. Если вам удалось создать сервис, вы должны получить такой статус.
Удаление службы systemd
Теперь посмотрим, как полностью удалить сервис из системы.
$ systemctl stop echo-server.service
2. Отключите службу.
$ systemctl disable echo-server.service
3. Удалите файл модуля.
$ sudo rm /etc/systemd/system/echo-server.service
4. Перезагрузите systemctl.
5. Удалите сценарий оболочки (необязательно, если вы использовали сценарий оболочки)
$ sudo rm /usr/sbin/start-echo-server.sh
6. Удалите неисправные блоки (необязательно)
Заключение
Возможность создавать эти службы может быть действительно полезной во многих случаях, это всего лишь один пример, в котором я показал вам, как это сделать, но этот метод можно использовать для решения нескольких задач, где systemd службы могут выполнять работу элегантно в большинстве случаев. без использования сторонних инструментов.
Большое спасибо за чтение до конца. Если вам понравилась статья, не стесняйтесь нажимать на значок хлопка, который мотивирует меня писать больше хороших статей.