Search
Write a publication
Pull to refresh

Comments 17

докер это конечно хорошо.
Но вместо того чтобы создать нормальный примитивный сервис (как раз systemd с этим очень хорошо справляется), пляски с бубном с докером

в случае с OxideMod, установленном поверх RustDedicated, предполагается, что папка oxide должна быть в корне. Сервис, который вы предлагаете создать, позволяет создать изолированную папку oxide, которая не будет перезаписана другим таким же сервисом ?

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

Можно создать два сервиса, и каждому прописать свою WorkingDirectory.

[werwolf@power] ~  
❯ systemctl cat valheim-server@.service 
# /usr/lib/systemd/system/valheim-server@.service
[Unit]
Description=Valheim dedicated server
Wants=network-online.target
After=multi-user.target network.target network-online.target

[Service]
Type=simple
User=valheim
Group=valheim
Environment="LD_LIBRARY_PATH=/var/lib/valheim/%i/linux64"
EnvironmentFile=/etc/valheim-%i.conf
WorkingDirectory=/var/lib/valheim/%i
ExecStartPre=+/usr/bin/steamcmd +login $STEAM_LOGIN +force_install_dir /var/lib/valheim/%i +app_update 896660 validate +exit
ExecStartPre=+/usr/bin/chown -R valheim:valheim /var/lib/valheim
ExecStart=/var/lib/valheim/%i/valheim_server.x86_64 -name $SERVER_NAME -port $PORT -world $WORLD_NAME -password $PASSWORD
Restart=always
RestartSec=30
TimeoutStartSec=300
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
ProtectSystem=strict
ProtectHome=read-only
SystemCallFilter=~@mount
ReadWritePaths=/var/lib/valheim/%i

[Install]
WantedBy=multi-user.target

примерно вот так

systemctl start valheim-server@XXX.service вызовет запуск юнита в котором все %i заменятся на XXX, тоесть будет создана директория /var/lib/valheim/XXX в неё будет установлен valheim dedicated server, в ней же он будет запущен, и только в неё же он сможет писать, а все необходимые переменные будут взяты из файла /etc/valheim-XXX.conf.

писал на память, может чего-то и опечатался, или упустил, но думаю общий смысл понятен.

systemd решает ВСЕ ваши проблемы с запуском сервисов, совершенно незачем для этого использовать docker. локально docker в первую очередь это инструмент тестирования. он больше имеет смысл в составе кубового кластера где нужно быстренько скалировать, где нужно чтобы работали life и health метрики (кстати, аналог health есть и у systemd, гуглить sd_notify). в общем не в ту сторону вы копнули.

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

1) зачем тащить на сервер дополнительный софт?
2) зачем тащить на сервер дополнительный рантайм пусть и в образе контейнера?
3) зачем нужны дополнительные абстракции?
4) зачем переусложнять конфигурацию сервиса и добавлять дополнительные точки отказа?

по большому счёту разворачивание сервисов в докере это НЕ плохо, просто зачастую это оверинженеринг без которого можно было обойтись. вроде бы не страшно что вы заняли на сервере пару лишних мегобайт дискового пространства и пару мегобайт ОЗУ, но из таких вот "да пусть будет" складываются привычки, а плохие привычки имеют свойство в будущем стрелять в ногу. конечно же иногда есть весомые причины развернуть что либо именно в контейнере, но в вашем кейсе я таких не вижу.

а как в вашем случае быть с обновлениями нескольких серверов ? и отдельно интересует, как происходит автоматизация через крон - вы прописываете для каждой директории /var/lib/valheim/XXX отдельное правило в crontab или это можно как-то обобщить (по типу перебора всех подпапок в bash-скрипте, вызова там обновлений и уже этот скрипт вызывать в кроне?)

с моим подходом я устанавливаю обновления всего раз в месяц (force wipe) в одну единственную папку и эти изменения автоматически затрагивают все имеющиеся инстансы серверов.

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

не берусь утверждать что это лучшее и/или самое правильное решение, но лучше я ничего не придумал за те 5 минут что потратил на эту задачу (самое обидное что играть то я не играю, некогда, для друзей держу несколько серверов)

почему было сделано именно так: одна из задач которую я решал делая этот сервис было опакетить его покласть в репозитории дистрибутива сервер для игры, поскольку нет явного разрешения класть серверную часть игры в репозиторий (и уж тем более исходников для сборки) это был самый простой и ничего не нарушающий путь.

правда версия с несколькими инстансами в репозитории не попала, я всё ещё ленюсь допроверить все возможные подводные камни, но одноинстансовый вариант уже давно там и его можно установить как пакет родным пакетным менеджером opensuse - zypper, возможно в будущем я так же опакечу для красношляпых и для deb, но пока на это времени просто нет. зато этот service легко модифицировать под любой сервер ставящийся силами steamcmd.

спасибо за развернутый ответ. Именно это я имел ввиду когда писал что докер излишен в данном случае

и это работало исправно, пока сервер был всего один. Но серверов стало два. И выключение всех серверов каждый раз, когда я выключаю один из них - меня не устраивало. Вот тут-то и появился он.

То есть вместо того, чтобы заменить pkill на kill, и вырубать нужный сервер по его process ID, вы замутили целый докер, а не разобравшись как пробросить каталог внутрь, замутили синхронизацию с рамдиском.

Давайте я решу все ваши проблемы, поправив run-server.sh

#!/bin/bash
WORKDIR=$(dirname $0)
PIDFILE=${WORKDIR}/server.pid

if [ "$1" == "start" ]; then
  [ -e ${PIDFILE} ] && echo "Server is already running" && exit 1

SEED=$(cat ${WORKDIR}/server/$IDENTITY/seed.txt)
  cp -R ${WORKDIR}/server/$IDENTITY/oxide/* ${WORKDIR}/oxide
  ./set-permissions.sh &
  ./watch-oxide-dir.sh &

  ${WORKDIR}/RustDedicated -batchmode \
    +server.hostname "$HOSTNAME" \
    +server.identity "$IDENTITY" \
    +server.maxplayers $MAXPLAYERS \
    +server.worldsize $WORLDSIZE \
    +server.seed "$SEED" \
    +server.tags "$SERVER_TAGS" \
    +server.url "$SERVER_URL" \
    +server.port $SERVER_PORT \
    +server.queryport $QUERY_PORT &
  echo $! > ${PIDFILE}
elif [ "$1" == "stop" ]; then
  [ ! -e "${PIDFILE}" ] && echo "Server is not running" && exit 0
  read PID<${PIDFILE}
  if ps $PID >/dev/null 2>&1; then
    kill $PID
  else
    echo "Server is not running and previous shutdown was not graceful"
  fi
else
  echo "Usage: $0 start|stop"
fi

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

замутили целый докер

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

Ну тем что вам пришлось
1. устанавливать докер
2. докеризировать сервер, что включает в себя и сеть и проброс дисков
3. вместо проброса дисков, вы нашли возможность использовать рамдрайв, но его надо синхронизировать - сделали еще лишний скрипт
4. усложнили поддержку своего сервера.


И вместо всего этого - можно просто удалить процесс по PID.

но корневая папка oxide-то все еще общая в вашем случае. Т.е. если я запущу второй сервер - он перезапишет эту папку и будет конфликт. И в итоге придется вернуться к изначальному подходу - т.е. копировать папку для каждого нового сервера.

Пожалуйста, исправьте меня, если я ошибаюсь.

проброс дисков

можете уточнить, что вы называете "пробросом дисков" ? монтирование (volumes) ? Если да, то несовсем понятен ваш следующий пункт

вместо проброса дисков, вы нашли возможность использовать рамдрайв

я и пробрасываю диск (вся папка Rust_Server) и использую рамдрайв (исключительно для одной подпапки, которая должна быть локальной для каждого запущенного сервера).

Т.е. не "вместо", а "вместе с" в данном случае будет корретнее.

усложнили поддержку своего сервера

можете развить эту мысль ? в чем сложность поддержки ?

Простите, а как вы раньше запускали два сервера?

Если вы хотели сделать какие-то папки общими для всех серверов - сделайте линками. Просто я не знаком с архитектурой серверов, что там можно обобщать, что нельзя. Но я уверен что Докер - это явно не тот инструмент, если вы хотели сэкономить место на дисках, и ln тут будет и быстрее и проще.

Хотите больше игроков? Отключите EAC. Я знаю всего один сервер сейчас где можно играть из-под Линукса, остальные не пускают из-за того что EAC не пашет в wine.

А зачем хранить все файлы RustDedicated и Oxide локально?

Может вынести их установку в Dockerfile, а отдельно хранить только конфиги и каталоги Oxide/plugins для каждого сервера (подключенные к разным веткам git) и подмонтировать их в контейнеры в соответствующие каталоги (через volumes)?

В таком случае при получении изменений с репозитория с плагинами они сразу будут видны в контейнере.

P.S.: с серверами раста сталкивался лет 5 назад, может какие-то моменты не учел.

Sign up to leave a comment.

Articles