Вопрос или проблема
Цель:
Я пытаюсь запустить сервер Minecraft при загрузке компьютера с помощью systemd на Fedora. У меня есть несколько самопринятых критериев, которые я должен выполнить, чтобы правильно управлять своим сервером(ами):
- Он должен работать как системный пользователь
minecraft
, которого я создал, с домашним каталогом/opt/minecraft
. Я пытался сделать это, добавив пользователя с помощьюadduser
, а затем добавил строкуUser=minecraft
иWorkingDirectory=/opt/minecraft/
- Он должен быть масштабируемым и работать с произвольным числом серверов. Я пытался сделать это, используя шаблонный сервис, а затем изменив строку
WorkingDirectory
наWorkingDirectory=/opt/minecraft/%i
, чтобы у меня была возможность передать каталог. - Я должен иметь возможность как-то передавать команды ему. В этом я застрял. Я пробовал использовать сокетный юнит и затем подключать его к
/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.
Есть несколько трюков, с которыми вы можете столкнуться:
-
Если вы
systemctl stop minecraft@1_17_1.service
, то это не остановит параллельный сокет. Это значит, что/run/minecraft1_17_1.stdin
будет продолжать работать. На самом деле, если выecho "hello" > /run/minecraft1_17_1.stdin
, он запустит ваш сервис. Я могу представить, что если вы решаете проблему с вашим сервисом, старый сокет может повлиять на ваши тесты. Я предлагаю один из двух вариантов:- Использовать
systemctl stop minecraft@1_17_1.{service,socket}
для его остановки, - Добавить
PartOf=minecraft@%i.service
в секцию[Unit]
сокета. Это заставит его автоматически остановиться, когда сервис остановится.
- Использовать
-
Вы используете
Restart=on-failure
. Это отлично для вашего конечного результата, но это может скрывать вашу первоначальную ошибку. Пока вы устраняете неполадки, рассмотрите возможность временного удаления этого параметра. Тогда, когда он потерпит неудачу, вы увидите первоначальную причину, по которой он не удался. Мой предположительный диагноз заключается в том, что у вас есть законная проблема с запуском сервера, но затем ваш сокет связан с этим первым экземпляром. Затем каждый перезапуск не может привязаться к старому сокету, прежде чем даже попытаться выполнить ExecStart=, и поэтому вы никогда не обнаруживаете, почему он изначально не удался. Обязательно остановите сервис и сокет, затем запустите его и сразу проверьте вывод. Я не удивлюсь, если ваше сообщение об ошибке будет другим. -
Вы описали сервер Minecraft как имеющий графический интерфейс. Это необязательно и внезапно зависит от таких вещей, как ваш
DISPLAY
иXAUTHORITY
. Это вводит много вещей, которые могут сломаться. Рассмотрите возможность вызова вашего сервиса с параметромnogui
вstart.sh
, чтобы исключить эту возможную причину первоначальной ошибки. Если вы ДЕЙСТВИТЕЛЬНО хотите этот графический интерфейс, то вам нужно будет установить переменные средыDISPLAY
иXAUTHORITY
в вашем скрипте (но это не обязательно самое простое), Я рекомендую хотя бы попробовать без графического интерфейса, чтобы увидеть, запустится ли ваш сервис. -
Возможно, вы забыли выполнить
sudo systemctl daemon-reload
во время редактирования ваших файлов. Напоминаю, обязательно выполните это, чтобы systemd прочитал последнюю версию каждого юнита.
Каков стандартный пароль для “minecraft system”, у меня 10-летний сервер, и я забыл свой пароль.
Ответ или решение
Настройка системы systemd для автозапуска сервера Minecraft с возможностью передачи команд
Введение
Для успешной настройки сервиса systemd, который будет автоматически запускать сервер Minecraft на вашей системе Fedora, необходимо учесть несколько ключевых принципов и требований. Рассмотрим их подробнее.
Цели
- Запуск от имени пользователя
minecraft
: сервер должен запускаться под учетной записью, которую вы создали, с домашним каталогом/opt/minecraft
. - Масштабируемость: использование шаблона сервиса для поддержки произвольного количества серверов.
- Передача команд: необходимо реализовать механизм для отправки команд в интерактивный консольный интерфейс сервера.
Решение
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
Отладка
Если при запуске сервиса возникают ошибки, выполните следующие действия:
-
Проверьте состояние сервиса:
systemctl status minecraft@1_17_1.service
-
Изучите журналы:
journalctl -xeu minecraft@1_17_1.service
Рекомендуемые методы отладки:
- Убедитесь, что вы отключили автоматический перезапуск во время отладки, чтобы увидеть исходную ошибку.
- Если есть проблемы с доступом, выполните корректировку прав на сокет и рабочую директорию.
Заключение
Следуя предложенной инструкции, вы сможете успешно настроить и управлять множественными серверами Minecraft, используя систему unit-файлов systemd
. Это решение достаточно масштабируемо и позволит вам гибко управлять своими игровыми серверами.