RE:NODE

VDS15 мин чтения

Несколько игровых серверов на одном VDS: порты, пользователи, systemd

Четыре-пять игровых серверов на одной машине: карта портов, пользователь на каждый, юниты systemd с лимитами, LinuxGSM, разнесённые обновления и backup, и когда не стоит связываться.

0 прочтений

Запускать несколько игровых серверов на одном VDS - вполне разумная затея, но для одного-двух серверов она почти никогда не окупается. Пока серверов меньше трёх, управляемый тариф на каждую игру обходится дешевле в деньгах, стоит вам оценить собственные часы дороже нуля, а в вечерах не стоит вообще ничего. Аргументы в пользу одной машины появляются при четырёх, пяти или шести серверах: когда память начинает полезно объединяться, когда все серверы хочется держать на одном адресе и когда с Linux вы уже на «ты».

Если вы решились, работа состоит из пяти частей: карта портов, которую вы записываете до установки чего бы то ни было, один непривилегированный пользователь на каждый сервер, юнит systemd на каждый сервер с ограничениями по ресурсам, способ отправлять команды без панели и разнесённые по времени обновления и backup, чтобы пять процессов не молотили один и тот же диск в четыре утра. В этой статье разобрано всё это, а также LinuxGSM и вариант с установкой панели на собственную машину.

Честно ответьте, нужно ли вам это#

Начнём отсюда, потому что остальная часть статьи - это много работы, которую глупо делать не по той причине.

Управляемый игровой тариф отдаёт вам сервер примерно через минуту после того, как пройдёт оплата: с готовой установкой, выделенными портами, консолью, файловым менеджером, SFTP, задачами по расписанию и слотами для backup. VDS отдаёт вам пустую машину с Debian и пароль root в течение суток. Всё остальное в этой статье - это разница между двумя предыдущими предложениями, и в первый раз она занимает примерно выходные.

Отдельные управляемые тарифыОдин VDS
Время до запуска первого сервераОколо минуты1-3 часа
ПамятьФиксирована на тариф, оплачивается независимо от использованияОбщая на всё
ПортыВыделяются на тариф, ещё можно добавить на вкладке NetworkЛюбой порт, какой захотите
Консоль для каждого сервераВстроена, отдельная на каждыйRCON, tmux или собирайте сами
Доступ к перезапуску для другаSubuser с ограниченными правамиУчётная запись SSH или скрипт
Обновления и патчиНе ваша заботаВаша, по расписанию
Падение в 3 часа ночиЗа сервером следят и перезапускаютТо, что сделает Restart=

Честная граница проходит по форме использования памяти, а не по количеству серверов. Пять серверов по 2 ГБ, большую часть недели простаивающих, прекрасно объединяются на VDS с 16 ГБ, потому что тот, у которого случился всплеск, занимает память у четырёх спокойных. Два сервера, каждому из которых по-настоящему нужно по 6 ГБ и которые загружены, не объединяются совсем, и вы купили себе работу системного администратора зря. В статье выбор между VDS и игровой панелью разобрана вся арифметика, включая то, сколько съедает сама операционная система ещё до запуска чего-либо.

И ещё одно, что не очевидно, пока не сделаешь: второй игровой сервер добавить легко, а пятый - нет. Каждый приносит диапазон портов, который нужно помнить, расписание обновлений, backup, свой формат конфигурации и свой способ принимать команды. Работа растёт не линейно.

Расчёт: что на самом деле поместится#

Вас ограничивают два числа, и обычно люди проверяют не то, что нужно.

Память - простой случай. Вычтите 300-400 МБ на минимальный Debian или Ubuntu без ничего лишнего, а если добавите Docker, веб-сервер или мониторинг, то больше, и разделите остаток. Реалистично, VDS на 8 ГБ даёт около 7 ГБ под игровые серверы.

А вот процессор - это то ограничение, которое бьёт. Почти каждый игровой сервер считает свой мир в одном потоке. Четыре сервера, тикающие одновременно, требуют четырёх потоков, каждый из которых достаточно быстр, и никакое общее число ядер не поможет, если ядра медленные. На машине с двумя vCPU два нагруженных игровых сервера чувствуют себя нормально, а четыре мешают друг другу в часы пик, даже когда памяти с запасом. Это тот же эффект, что описан в статье общий процессор и шумные соседи, только теперь шумный сосед - это вы сами.

Размер VDSКомфортная нагрузкаНеудобная нагрузка
8 ГБ, 2 vCPUДва-три небольших сервера, пики разнесеныЧетыре нагруженных сервера одновременно
16 ГБ, 4 vCPUЧетыре-пять, либо один большой мир с модами и два маленькихВосемь чего угодно
24 ГБ, 6 vCPUШесть, либо смешанный набор с базой данных и веб-приложениемДюжина, что бы ни говорила память

Рассчитывайте на пик, а не на среднее. Пять серверов, каждый из которых в простое занимает 800 МБ, а на пике 3 ГБ, не переживут вместе вечер пятницы на 16 ГБ, а получившийся kill по нехватке памяти убьёт тот сервер, который в тот момент был самым большим, а не тот, который её вызвал. В статье swap и OOM killer объясняется, как принимается это решение и как на него повлиять.

Карта портов, записанная заранее#

Сделайте это до установки чего бы то ни было. Пять минут сейчас сэкономят вам день, потраченный на сервер, который запускается, ничего не занимает и пишет в лог строку «address already in use», которую вы не заметите ещё час.

ИграПорты по умолчаниюПримечания
Minecraft Java25565/tcpПлюс 25575/tcp, если включите RCON
Valheim2456/udp, 2457/udpПорт запросов всегда равен игровому плюс один
Palworld8211/udpЗадаётся через -port
Counter-Strike 227015/udp, 27015/tcpПлюс 27020/udp для GOTV
Terraria7777/tcpОдин порт, без порта запросов
Factorio34197/udpОдин порт UDP
TCP 25565UDP 2456UDP 27015Игрокиразные игрыПубличный IP203.0.113.10MinecraftTCP 25565ValheimUDP 2456-2457CS2UDP 27015Диск NVMeобщий для всех
Один адрес, несколько серверов, одна карта портов

Карта держится на трёх правилах. Выделяйте каждому серверу блок, а не одно число, потому что большинство игр тихо хотят второй порт для запросов или третий - для функции, которую вы включите позже. Оставляйте промежутки: разносите на десять-двадцать, а не на единицу. И запишите всё это в файл на самой машине, потому что через восемь месяцев вы будете пытаться вспомнить, чей сервер занимает 27025.

Игры на движке Source - неудобный случай. Двум экземплярам на одной машине нужны разные значения -port, +tv_port и +clientport, а если задать только первое, два сервера будут драться за один сокет GOTV, и завершается это ошибкой, которую лог описывает плохо. В статье порты игровых серверов простыми словами рассказано, зачем нужны порты запросов и что происходит, когда достижим только один из пары.

Затем откройте ровно эти порты и больше ничего:

bash
$ ufw default deny incoming$ ufw allow 22/tcp$ ufw allow 25565/tcp          # Minecraft$ ufw allow 2456:2457/udp      # Valheim game and query$ ufw allow 8211/udp           # Palworld$ ufw enable$ ufw status numbered

Порты RCON - исключение: не открывайте их в интернет. Привяжите RCON к 127.0.0.1 и заходите через SSH-туннель, это ничего не стоит и снимает целый класс проблем. В статье RCON без риска объяснено, почему открытый порт RCON с угадываемым паролем - самый быстрый способ потерять сервер, а руководство по файрволу ufw описывает остальной набор правил.

Один пользователь на сервер#

Эту часть люди пропускают и потом жалеют. У каждого игрового сервера должен быть свой непривилегированный пользователь и своё дерево каталогов. Ничто не запускается от root, и ничто не запускается от того же пользователя, что и что-то другое.

bash
$ adduser --disabled-password --gecos "" --home /srv/valheim valheim$ adduser --disabled-password --gecos "" --home /srv/minecraft minecraft$ chown -R valheim:valheim /srv/valheim$ sudo -u valheim -i           # become that user to install or edit

Причина в изоляции. Игровые серверы запускают моды и плагины, написанные посторонними людьми, иногда загружают контент, присланный игроками, и выставляют наружу сетевые службы, разбирающие недоверенный ввод. Когда один из них взломан - а статья как держать сервер с модами в чистоте - более полный разговор об этом опасении, - радиус поражения должен быть одним каталогом, а не всей машиной. Отдельный пользователь означает и то, что случайный rm -rf в не том терминале закончится ошибкой доступа, а не успехом.

Есть и практическая польза. ps aux и systemd-cgtop становятся читаемыми, потому что по столбцу пользователя сразу видно, какой сервер грузит процессор. Отдельные установки Steam лежат в отдельных домашних каталогах, поэтому steamcmd +force_install_dir /srv/valheim/server и +force_install_dir /srv/pz/server никогда не столкнутся. Шаблон скрипта обновления есть в статье SteamCMD простыми словами.

systemd - это супервизор#

Не tmux, не screen, не nohup. Процесс, запущенный в терминальном мультиплексоре, не стартует при загрузке, не перезапускается после падения и невидим для всего, что вы настроите потом. Используйте юнит systemd, причём шаблонный, чтобы добавление пятого сервера сводилось к копированию одного файла окружения, а не файла юнита.

/etc/systemd/system/gameserver@.service
[Unit]Description=Game server: %iAfter=network-online.targetWants=network-online.target[Service]User=%iGroup=%iWorkingDirectory=/srv/%iEnvironmentFile=/etc/gameservers/%i.envExecStart=/srv/%i/start.shRestart=on-failureRestartSec=20KillSignal=SIGINTTimeoutStopSec=120CPUQuota=150%MemoryHigh=3500MMemoryMax=4GNice=-5[Install]WantedBy=multi-user.target

%i - это имя экземпляра, поэтому systemctl enable --now gameserver@valheim запускает /srv/valheim/start.sh от пользователя valheim с загруженным /etc/gameservers/valheim.env. Один файл юнита, одна строка на сервер.

Настоящую работу здесь делают четыре директивы:

  • KillSignal=SIGINT - та, которую пропускают чаще всего и которая стоит людям миров. Многие игровые серверы сохраняются при штатном прерывании и теряют всё после последнего автосохранения при SIGKILL. Юнит по умолчанию шлёт SIGTERM и сдаётся через 90 секунд; TimeoutStopSec=120 даёт большому миру время дописать данные.
  • CPUQuota=150% ограничивает сервер полутора ядрами. Именно эта настройка не даёт одному модифицированному миру задушить остальные четыре во время рейда, и это главная причина предпочесть systemd собственному надзору LinuxGSM.
  • MemoryMax задаёт серверу собственный потолок. Упёршись в него, погибает только эта cgroup, а не самый крупный процесс на машине, и это куда лучший исход, чем глобальный kill по нехватке памяти.
  • Restart=on-failure с RestartSec в пятнадцать-двадцать секунд. Не ставьте always с задержкой в одну секунду: сервер, который не может запуститься, будет крутиться бесконечно и забьёт диск логами.

Затем проверьте, что на самом деле всё потребляет:

bash
$ systemctl status gameserver@valheim$ journalctl -u gameserver@valheim -f$ systemd-cgtop$ systemctl list-units 'gameserver@*'

systemd-cgtop - это top в разрезе служб, и на машине с пятью серверами он быстрее всего показывает, какой из них пошёл не так. Остальной синтаксис файла юнита разобран в статье службы systemd для ваших приложений.

Отправка команд без панели#

Это неудобство, о котором никто не предупреждает. В панели у каждого сервера есть консоль. На VDS у процесса под управлением systemd нет терминала, в который можно печатать, а journalctl только читает.

Есть два рабочих ответа. Если игра поддерживает RCON, используйте его, привязанным к localhost:

bash
$ mcrcon -H 127.0.0.1 -P 25575 -p "$RCON_PASS" "say Restart in 5 minutes" "save-all"$ ssh -L 25575:127.0.0.1:25575 deploy@203.0.113.10   # tunnel from your laptop

Если нет - запускайте сервер внутри сессии tmux, принадлежащей его пользователю, и управляйте им через send-keys:

bash
$ sudo -u valheim tmux send-keys -t valheim "save" Enter$ sudo -u valheim tmux attach -t valheim      # detach again with Ctrl-b d

Именно так поступает LinuxGSM, и это работает, хотя юнит systemd получается немного странным. Что бы вы ни выбрали, автоматизируйте то, что делаете часто, - объявление, сохранение, остановку, - потому что делать это вручную на пяти серверах во время обновления - верный способ пропустить шаги.

LinuxGSM: что он даёт и где заканчивается#

LinuxGSM - это набор shell-скриптов, который устанавливает, настраивает, обновляет, резервирует и мониторит выделенные серверы для более чем сотни игр. Он по-настоящему хорош, бесплатен, а для смешанного набора экономит часы чтения инструкций по установке каждой игры.

bash
$ wget -O linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh$ bash linuxgsm.sh vhserver          # creates the vhserver script$ ./vhserver install$ ./vhserver start$ ./vhserver details                 # ports, paths, status$ ./vhserver update$ ./vhserver backup$ ./vhserver console

У каждой игры есть короткий код: vhserver для Valheim, mcserver для Minecraft, gmodserver для Garry's Mod, tf2server для Team Fortress 2 и так далее. Настройки лежат в lgsm/config-lgsm/<code>/<code>.cfg и переопределяют поставляемые значения по умолчанию так же, как jail.local делает это для fail2ban.

LinuxGSM отказывается работать от root, и тем самым сам обеспечивает правило «один пользователь на сервер». Его команда details печатает точные порты, нужные игре, - это самый быстрый способ составить описанную выше карту портов.

Два честных ограничения. Во-первых, его команда monitor рассчитана на запуск из cron каждые несколько минут и с удовольствием перезапустит сервер, который в этот же момент пытается перезапустить systemd. Выберите одного супервизора: либо юниты systemd с Restart=on-failure и без записи monitor в cron, либо собственный мониторинг LinuxGSM и без юнита systemd. Если включить оба, сервер перезапустится дважды, а лог будет лишён всякого смысла.

crontab -u vhserver -e
*/5 * * * * /srv/valheim/vhserver monitor > /dev/null 2>&10 4 * * * /srv/valheim/vhserver update > /dev/null 2>&1

Во-вторых, LinuxGSM не даёт ограничений по ресурсам. Он запускает процесс, но не ограничивает ни процессор, ни память. На машине с одним-двумя серверами это нормально. На машине с пятью строки CPUQuota и MemoryMax из примера выше - это разница между одним плохим сервером и пятью плохими, поэтому большинство людей всё равно приходят к юнитам systemd, а LinuxGSM используют только для установки и обновлений. Синтаксис расписания, если пять полей вам незнакомы, разобран в статье выражения cron простыми словами.

Обновления, backup и перезапуски, разнесённые во времени#

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

  • Разнесите backup. Архив tar мира на 40 ГБ - это длительное чтение и длительная запись на одном устройстве. Пять одновременно его насыщают. Ставьте их с интервалом двадцать минут.
  • Разнесите перезапуски. Перезапуск всего в 05:00 означает, что каждый сервер загружает свой мир одновременно, а это самое тяжёлое, что каждый из них делает. В статье расписания перезапусков, которые помогают разобрано, каким серверам перезапуск вообще полезен, потому что некоторым - нет.
  • Не обновляйте сервер с модами автоматически. Патч игры в день выхода ломает все моды, пока авторы не подтянутся. Обновляйте чистые серверы автоматически, а серверы с модами - вручную, после проверки, сохранив копию рабочей папки с модами. Что делать, когда обновление мода всё сломало - это процедура восстановления.

Таймер systemd аккуратнее cron для такой работы, потому что лог оказывается в журнале рядом со службой, которую он резервирует:

bash
$ tar -czf /srv/backups/valheim-$(date +%F-%H%M).tar.gz -C /srv/valheim worlds_local$ find /srv/backups -name 'valheim-*.tar.gz' -mtime +14 -delete$ restic -r sftp:backup@198.51.100.5:/srv/restic backup /srv/valheim/worlds_local

Ключевое здесь - место назначения. Backup на том же диске, что и сервер, защищает от повреждённого сохранения и ни от чего больше: ни от удалённого каталога, ни от вышедшего из строя диска, ни от ошибки, совершённой в полночь. Отправляйте его в другое место и время от времени восстанавливайте что-нибудь, чтобы убедиться, что оно работает, потому что backup, который никто не восстанавливал, - это гипотеза. Статья проверка восстановления до того, как оно понадобится - это десятиминутная версия этой привычки.

Наконец, сама машина. Еженедельный apt update && apt full-upgrade, включённые автоматические обновления безопасности, файрвол с запретом по умолчанию, вход по SSH только по ключам и fail2ban на порту SSH. Ничего из этого не происходит само, а машина с пятью игровыми серверами - более интересная цель, чем машина с одним. Чек-лист - это первый час на новом VDS, а повседневное чтение - команды Linux для администраторов серверов.

Или поставьте панель на собственный VDS#

Типичное желание - получить и то и другое: доступ root и настоящий интерфейс, чтобы другие могли перезапускать серверы без ключа SSH. Обычно выбирают Pterodactyl, и его вполне можно установить, но чётко представляйте, что вы на себя берёте.

Он состоит из двух компонентов. Панель - это приложение на Laravel, которому нужны веб-сервер, PHP с расширениями, MySQL-совместимая база данных, Redis и Composer. Wings - это демон на Go, которому нужен Docker; он общается с панелью через собственный порт, а SFTP отдаёт отдельно. По умолчанию в upstream API Wings слушает 8080, его SFTP - 2022, а панель - 80 и 443.

Это пять-шесть служб, которые нужно держать обновлёнными, сертификат для имени хоста панели и образ Docker на каждую игру. Закладывайте около 1 ГБ памяти ещё до запуска первого игрового сервера. На VDS с 24 ГБ это погрешность округления; на тарифе с 8 ГБ это восьмая часть вашей машины, потраченная на инфраструктуру, а не на игроков. В статье что даёт панель Pterodactyl архитектура разобрана подробнее.

Разумное правило: ставьте панель на собственную машину, когда хостинг для других людей - это ваш продукт и вы берёте за него деньги. Не ставьте её только ради того, чтобы три друга могли нажать Restart. На управляемом тарифе RE:NODE это учётная запись subuser с детальными правами - только консоль, только файлы, без биллинга - с ролью, которую можно ограничить по времени, и с журналом действий на каждый сервер. Как это настроить, рассказано в статье subuser и принцип наименьших привилегий, и это занимает около двух минут.

Вот честный итог всей статьи. Каждый управляемый тариф получает одну и ту же панель с той же консолью, файловым менеджером, отдельным SFTP на сервер, расписаниями и слотами backup, а сервер появляется примерно через минуту после того, как пройдёт оплата. VDS даёт полный доступ root, подготовленный вручную и выдаваемый в течение 24 часов, и всё описанное выше становится вашим делом. Выбирайте то, что соответствует тому, сколько серверов вы на самом деле запускаете и сколько своей недели хотите вернуть себе.

FAQ#

Сколько игровых серверов помещается на одном VDS?

Считайте быстрые потоки, а не гигабайты. Большинство игровых серверов считают мир в одном потоке, поэтому машина с двумя vCPU спокойно тянет два-три сервера с пиками в разное время, а машина с шестью vCPU - пять-шесть. Память задаёт жёсткий потолок; процессор задаёт тот, который вы действительно почувствуете.

Могут ли все они использовать один IP-адрес?

Да. Это обычная схема, и именно поэтому так важна карта портов. Каждый сервер занимает свой порт на одном и том же адресе, а игроки подключаются по address:port. Одним номером порта для данного протокола может владеть только один сервер.

Стоит ли использовать Docker для каждого сервера?

Можно, это даёт чистую изоляцию и удобные ограничения, но добавляет образ, который надо поддерживать на каждую игру, и подвох с файрволом: Docker публикует порты, прописывая собственные правила, которые проверяются раньше правил ufw, поэтому контейнер может быть доступен, даже когда файрвол говорит, что порт закрыт. Где возможно, привязывайте к 127.0.0.1. Подробности - в статье Docker на VDS.

Достаточно ли tmux, чтобы сервер продолжал работать?

Для того, за чем вы следите сами, - да. Для чего-либо постоянного - нет. Сессия tmux не стартует после перезагрузки и не перезапускается после падения. Используйте юнит systemd, а tmux оставьте для консоли, если у игры нет RCON.

Что происходит, когда один сервер съедает всю память?

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

Это дешевле, чем отдельные управляемые тарифы?

Иногда. Меньше чем на трёх серверах - почти никогда, если считать часы. Больше чем на пяти - как правило да, потому что память объединяется и вы платите за машину, а не за пять отдельных потолков. Посчитайте оба варианта, затем добавьте к стороне VDS реалистичное число часов в месяц, прежде чем сравнивать.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000