Как создать конфигурацию службы 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 ответ
Я рыскал по сети в поисках элементов, которые мне нужны, чтобы создать свой собственный набор
systemd
unit, шаблон и целевые файлы. Этот вопрос был в куче результатов поиска. В этом случае, вместо того, чтобы искать помощи, я думаю, что могу помочь.
У меня нет 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