Как мне настроить сервис systemd для автоматического запуска сервера и передачи команд ему?

Вопрос или проблема

Цель:

Я пытаюсь запустить сервер Minecraft при загрузке компьютера с помощью systemd на Fedora. У меня есть несколько самопринятых критериев, которые я должен выполнить, чтобы правильно управлять своим сервером(ами):

  1. Он должен работать как системный пользователь minecraft, которого я создал, с домашним каталогом /opt/minecraft. Я пытался сделать это, добавив пользователя с помощью adduser, а затем добавил строку User=minecraft и WorkingDirectory=/opt/minecraft/
  2. Он должен быть масштабируемым и работать с произвольным числом серверов. Я пытался сделать это, используя шаблонный сервис, а затем изменив строку WorkingDirectory на WorkingDirectory=/opt/minecraft/%i, чтобы у меня была возможность передать каталог.
  3. Я должен иметь возможность как-то передавать команды ему. В этом я застрял. Я пробовал использовать сокетный юнит и затем подключать его к /run/minecraft%I, но не смог это заставить работать. Если вы не знакомы с серверами Minecraft, у них есть этот интерактивный консольный интерфейс, в который вы можете вводить команды. Раньше я использовал tmux send, когда сервер работал в сессии tmux, но проблема в том, что он не запускается автоматически и выглядит неэстетично.

Попытанное решение:

/usr/local/lib/systemd/system/[email protected]:

[Unit]
Description=Сервер Minecraft: %i

# запускать только после готовности сети
After=network-online.target
Wants=network-online.target

[Service]
Type=simple

# перезапуск, если сервер крашится
Restart=on-failure
RestartSec=5s

# установить входные и выходные данные на сокетный юнит и журнал соответственно
Sockets=minecraft@%i.socket
StandardInput=socket                     
StandardOutput=journal
StandardError=journal

# установить пользователя и каталог на правильные значения
User=minecraft
WorkingDirectory=/opt/minecraft/%i/

# выполнить скрипт запуска для указанного сервера
ExecStart=/bin/bash /opt/minecraft/%i/start.sh

[Install]
WantedBy=default.target

/usr/local/lib/systemd/system/[email protected]:

[Unit]
Description=Сокет для сервера Minecraft: %i

[Socket]
# слушать пайп для ввода
ListenFIFO=%t/minecraft%I.stdin

Service=minecraft@%i.service

Проблема:

Когда я пытаюсь запустить сервер с помощью sudo systemctl start minecraft@1_17_1.service (я установил сервер в /opt/minecraft/1_17_1/), он терпит неудачу:

Работа для minecraft@1_17_1.service не удалась из-за недоступных ресурсов или другой системной ошибки.
Смотрите "systemctl status minecraft@1_17_1.service" и "journalctl -xeu minecraft@1_17_1.service" для получения подробной информации.

Это побудило меня выполнить systemctl status minecraft@1_17_1.service:

● minecraft@1_17_1.service - Сервер Minecraft: 1_17_1
     Загружено: загружено (/usr/local/lib/systemd/system/[email protected]; включен; предустановка вендора: отключена)
     Активно: активируется (автоперезапуск) (Результат: ресурсы) с Thu 2021-11-04 14:37:27 EDT; 163ms назад
TriggeredBy: × minecraft@1_17_1.socket
        CPU: 0

А также journalctl -xeu minecraft@1_17_1.service

Nov 04 14:51:01 riley-fedora systemd[1]: minecraft@1_17_1.service: Не получен сокет.
Nov 04 14:51:01 riley-fedora systemd[1]: minecraft@1_17_1.service: Не удалось выполнить задачу 'start': Неверный аргумент
Nov 04 14:51:01 riley-fedora systemd[1]: minecraft@1_17_1.service: Неудача с результатом 'resources'.
░░ Тема: Юнит не удался
░░ Определено: systemd
░░ Поддержка: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Юнит minecraft@1_17_1.service вошел в состояние 'неудачи' с результатом 'resources'.
Nov 04 14:51:01 riley-fedora systemd[1]: Не удалось запустить сервер Minecraft: 1_17_1.
░░ Тема: Задача запуска для юнита minecraft@1_17_1.service не удалась
░░ Определено: systemd
░░ Поддержка: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Задача запуска для юнита minecraft@1_17_1.service завершилась с ошибкой.
░░ 
░░ Идентификатор задачи 55890, результат задачи - неудача.

Я увидел, что система, похоже, была недовольна моим файлом [email protected], так что я выполнил systemctl status minecraft@1_17_1.socket:

× minecraft@1_17_1.socket - Сокет для сервера Minecraft: 1_17_1
     Загружено: загружено (/usr/local/lib/systemd/system/[email protected]; статический)
     Активно: неудача (Результат: ресурсы)
   Срабатывает: ● minecraft@1_17_1.service
     Прослушивание: /run/minecraft1_17_1.stdin (FIFO)

Nov 04 14:52:35 riley-fedora systemd[1]: minecraft@1_17_1.socket: Неудача с результатом 'resources'.
Nov 04 14:52:35 riley-fedora systemd[1]: Не удалось прослушать сокет для сервера Minecraft: 1_17_1.
Nov 04 14:52:41 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось открыть FIFO /run/minecraft1_17_1.stdin: Отказано в доступе
Nov 04 14:52:41 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось прослушивать сокеты: Отказано в доступе
Nov 04 14:52:41 riley-fedora systemd[1]: minecraft@1_17_1.socket: Неудача с результатом 'resources'.
Nov 04 14:52:41 riley-fedora systemd[1]: Не удалось прослушать сокет для сервера Minecraft: 1_17_1.
Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось открыть FIFO /run/minecraft1_17_1.stdin: Отказано в доступе
Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось прослушивать сокеты: Отказано в доступе
Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Неудача с результатом 'resources'.
Nov 04 14:52:46 riley-fedora systemd[1]: Не удалось прослушать сокет для сервера Minecraft: 1_17_1.

Таким образом, похоже, проблема связана с правами доступа к пайпу, который я использовал.

Для верности я выполнил journalctl -xeu minecraft@1_17_1.socket

Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось открыть FIFO /run/minecraft1_17_1.stdin: Отказано в доступе
Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Не удалось прослушивать сокеты: Отказано в доступе
Nov 04 14:52:46 riley-fedora systemd[1]: minecraft@1_17_1.socket: Неудача с результатом 'resources'.
░░ Тема: Юнит не удался
░░ Определено: systemd
░░ Поддержка: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Юнит minecraft@1_17_1.socket вошел в состояние 'неудачи' с результатом 'resources'.
Nov 04 14:52:46 riley-fedora systemd[1]: Не удалось прослушать сокет для сервера Minecraft: 1_17_1.
░░ Тема: Задача запуска для юнита minecraft@1_17_1.socket не удалась
░░ Определено: systemd
░░ Поддержка: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Задача запуска для юнита minecraft@1_17_1.socket завершилась с ошибкой.
░░ 
░░ Идентификатор задачи 58598 и результат задачи - неудача.

Вопрос:

Что я делаю не так? Я потратил около 4 часов на ах вторую, третью и даже четвертую страницы Google без решения. Я в растерянности, так что любая помощь будет очень полезна.

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

# /etc/systemd/system/[email protected]
[Service]
ExecStart=cat -
User=stew
Sockets=sockinst@%i.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal
# /etc/systemd/system/[email protected]
[Socket]
ListenFIFO=%t/sockinst%I.stdin
Service=sockinst@%i.service

Затем запуск этого работает:

stew /etc/systemd/system $ systemctl start sockinst@1_1.service
stew /etc/systemd/system $ echo "Hello" > /run/sockinst1_1.stdin 
stew /etc/systemd/system $ systemctl status sockinst@1_1.{service,socket}
● sockinst@1_1.service - Тестирование сокетов экземпляров 1_1
     Загружено: загружено (/etc/systemd/system/[email protected]; статический)
     Активно: активно (работает) с пятницы, 2021-11-05 10:35:41 CET; 37s назад
TriggeredBy: ● sockinst@1_1.socket

systemd[1]: Запущено тестирование сокетов экземпляров 1_1.
cat[11623]: Hello

● sockinst@1_1.socket - Сокет для экземпляра 1_1
     Загружено: загружено (/etc/systemd/system/[email protected]; статический)
     Активно: активно (работает) с пятницы, 2021-11-05 10:35:41 CET; 37s назад
   Срабатывает: ● sockinst@1_1.service
     Прослушивание: /run/sockinst1_1.stdin (FIFO)

systemd[1]: Прослушивание сокетов для экземпляра 1_1.

Есть несколько трюков, с которыми вы можете столкнуться:

  1. Если вы systemctl stop minecraft@1_17_1.service, то это не остановит параллельный сокет. Это значит, что /run/minecraft1_17_1.stdin будет продолжать работать. На самом деле, если вы echo "hello" > /run/minecraft1_17_1.stdin, он запустит ваш сервис. Я могу представить, что если вы решаете проблему с вашим сервисом, старый сокет может повлиять на ваши тесты. Я предлагаю один из двух вариантов:

    1. Использовать systemctl stop minecraft@1_17_1.{service,socket} для его остановки,
    2. Добавить PartOf=minecraft@%i.service в секцию [Unit] сокета. Это заставит его автоматически остановиться, когда сервис остановится.
  2. Вы используете Restart=on-failure. Это отлично для вашего конечного результата, но это может скрывать вашу первоначальную ошибку. Пока вы устраняете неполадки, рассмотрите возможность временного удаления этого параметра. Тогда, когда он потерпит неудачу, вы увидите первоначальную причину, по которой он не удался. Мой предположительный диагноз заключается в том, что у вас есть законная проблема с запуском сервера, но затем ваш сокет связан с этим первым экземпляром. Затем каждый перезапуск не может привязаться к старому сокету, прежде чем даже попытаться выполнить ExecStart=, и поэтому вы никогда не обнаруживаете, почему он изначально не удался. Обязательно остановите сервис и сокет, затем запустите его и сразу проверьте вывод. Я не удивлюсь, если ваше сообщение об ошибке будет другим.

  3. Вы описали сервер Minecraft как имеющий графический интерфейс. Это необязательно и внезапно зависит от таких вещей, как ваш DISPLAY и XAUTHORITY . Это вводит много вещей, которые могут сломаться. Рассмотрите возможность вызова вашего сервиса с параметром nogui в start.sh, чтобы исключить эту возможную причину первоначальной ошибки. Если вы ДЕЙСТВИТЕЛЬНО хотите этот графический интерфейс, то вам нужно будет установить переменные среды DISPLAY и XAUTHORITY в вашем скрипте (но это не обязательно самое простое), Я рекомендую хотя бы попробовать без графического интерфейса, чтобы увидеть, запустится ли ваш сервис.

  4. Возможно, вы забыли выполнить sudo systemctl daemon-reload во время редактирования ваших файлов. Напоминаю, обязательно выполните это, чтобы systemd прочитал последнюю версию каждого юнита.

Каков стандартный пароль для “minecraft system”, у меня 10-летний сервер, и я забыл свой пароль.

Ответ или решение

Настройка системы systemd для автозапуска сервера Minecraft с возможностью передачи команд

Введение

Для успешной настройки сервиса systemd, который будет автоматически запускать сервер Minecraft на вашей системе Fedora, необходимо учесть несколько ключевых принципов и требований. Рассмотрим их подробнее.

Цели

  1. Запуск от имени пользователя minecraft: сервер должен запускаться под учетной записью, которую вы создали, с домашним каталогом /opt/minecraft.
  2. Масштабируемость: использование шаблона сервиса для поддержки произвольного количества серверов.
  3. Передача команд: необходимо реализовать механизм для отправки команд в интерактивный консольный интерфейс сервера.

Решение

1. Создание шаблонного сервиса Minecraft

Для начала создадим файл сервиса, например, /etc/systemd/system/minecraft@.service:

[Unit]
Description=Minecraft server: %i
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=minecraft
WorkingDirectory=/opt/minecraft/%i/
ExecStart=/bin/bash /opt/minecraft/%i/start.sh
StandardInput=socket
StandardOutput=journal
StandardError=journal
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
2. Создание сокета для передачи команд

Далее создайте файл сокета /etc/systemd/system/minecraft@.socket:

[Unit]
Description=Socket for Minecraft server: %i

[Socket]
ListenFIFO=%t/minecraft%i.stdin
Service=minecraft@%i.service

[Install]
WantedBy=sockets.target

Этот сокет будет слушать команды, которые мы будем отправлять на сервер.

3. Настройка прав доступа

Для того чтобы сокет работал, необходимо обеспечить корректные права доступа. Папка /run должна быть доступна для записи пользователю minecraft. Создайте папку с нужными правами:

sudo mkdir /run/minecraft
sudo chown minecraft:minecraft /run/minecraft
4. Проверка и перезагрузка конфигурации systemd

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

sudo systemctl daemon-reload
5. Запуск и активация службы

Теперь активируйте сокет и запустите его:

sudo systemctl enable minecraft@1_17_1.socket
sudo systemctl start minecraft@1_17_1.socket

Передача команд

Для отправки команд в сервер Minecraft, используйте следующую команду:

echo "ваша команда" > /run/minecraft1_17_1.stdin

Отладка

Если при запуске сервиса возникают ошибки, выполните следующие действия:

  1. Проверьте состояние сервиса:

    systemctl status minecraft@1_17_1.service
  2. Изучите журналы:

    journalctl -xeu minecraft@1_17_1.service
Рекомендуемые методы отладки:
  • Убедитесь, что вы отключили автоматический перезапуск во время отладки, чтобы увидеть исходную ошибку.
  • Если есть проблемы с доступом, выполните корректировку прав на сокет и рабочую директорию.

Заключение

Следуя предложенной инструкции, вы сможете успешно настроить и управлять множественными серверами Minecraft, используя систему unit-файлов systemd. Это решение достаточно масштабируемо и позволит вам гибко управлять своими игровыми серверами.

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

Капча загружается...