Как создать конфигурацию службы systemd с несколькими экземплярами?

Я пытаюсь настроить systemd так, чтобы он мог запускать несколько экземпляров одного и того же сервиса, но мне кажется, что я что-то делаю не так, и ресурсы документации не совсем ясны.

созданный /lib/systemd/system/confluence@.service файл с этим содержанием:

[Unit]
Description=Confluence %i
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/confluence-%i/bin/start-confluence.sh
ExecStartPre=/opt/atlassian/confluence-%i/bin/setenv.sh prestart

ExecStop=/opt/atlassian/confluence-%i/bin/stop-confluence.sh

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%i/work/catalina.pid

[Install]
WantedBy=multi-user.target

Пока все хорошо, systemctl enable confluence.test сообщил об успехе (и да, /opt/atlassian/confluence-test/ "случается" содержит то, что ему нужно.

Тем не менее, когда я пытаюсь запустить службу с помощью systemctl start confluence Я получил:

root@atlas:/lib/systemd/system# systemctl start confluence@test.service
Job for confluence@test.service failed. See "systemctl status confluence@test.service" and "journalctl -xe" for details.
root@atlas:/lib/systemd/system# systemctl status confluence@test.service
● confluence@test.service - Confluence test
   Loaded: loaded (/lib/systemd/system/confluence@.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Fri 2015-10-09 13:25:28 BST; 7s ago
  Process: 16352 ExecStartPre=/opt/atlassian/confluence-%i/bin/setenv.sh prestart (code=exited, status=203/EXEC)

Oct 09 13:25:28 atlas systemd[1]: Starting Confluence test...
Oct 09 13:25:28 atlas systemd[1]: confluence@test.service: control process exited, code=exited status=203
Oct 09 13:25:28 atlas systemd[1]: Failed to start Confluence test.
Oct 09 13:25:28 atlas systemd[1]: Unit confluence@test.service entered failed state.
Oct 09 13:25:28 atlas systemd[1]: confluence@test.service failed.

Почему-то кажется, что systemd не раскрывает "%i", который должен быть именем экземпляра.

1 ответ

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

У меня нет Confluence, и я не буду устанавливать его для тестирования, поэтому я в основном предполагаю, что касается первой части.

Я считаю, что проблема в том, что %iспецификатор экранирован и может создавать неверные пути в командах. Если это вся проблема, переход на неэкранированную версию, %I, было бы самым простым решением. Ваш файл /lib/systemd/system/confluence@.service тогда станет:

[Unit]
Description=Confluence %I
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/confluence-%I/bin/start-confluence.sh
ExecStartPre=/opt/atlassian/confluence-%I/bin/setenv.sh prestart

ExecStop=/opt/atlassian/confluence-%I/bin/stop-confluence.sh

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%I/work/catalina.pid

[Install]
WantedBy=multi-user.target

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

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

Создайте /opt/atlassian/conflencectl с этим:

#!/usr/bin/env bash
# Check that there is a command to execute
if ( ! test -n "$1" ) {
  exit 1
}

# Check that there is an instance name to use
if ( ! test -n "$2" ) {
  exit 1
}

# Make the directory name stub for this instance
InstanceDirName="confluence-$2"

# Execute the proper command, based on the command from the unit file
case $1 in
  Start)
    /opt/atlassian/$InstanceDirName/bin/start-confluence.sh;
    ;;
  StartPre )
    /opt/atlassian/$InstanceDirName/bin/setenv.sh prestart;
    ;;
  Stop )
    /opt/atlassian/$InstanceDirName/bin/stop-confluence.sh;
    ;;
  *)
    exit 1;
esac

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

Твой systemd unit файл становится таким:

[Unit]
Description=Confluence %I
After=postgresql.service nginx.service

[Service]
Type=forking
ExecStart=/opt/atlassian/conflencectl "Start" "%i"
ExecStartPre=/opt/atlassian/conflencectl "StartPre" "%i"

ExecStop=/opt/atlassian/conflencectl "Stop" "%i"

TimeoutStopSec=5min
PIDFile=/opt/atlassian/confluence-%I/work/catalina.pid

[Install]
WantedBy=multi-user.target

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

Вы не можете иметь отдельный скрипт запуска / остановки для каждого экземпляра.

Я бы предложил ExecStart=/opt/atlassian/confluence/bin/start-confluence.sh

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

То же самое касается ExecStartPre а также ExecStop

Другие вопросы по тегам