Agones (от др.-греч. agon — «соревнование») позволяет развернуть кластер игрового сервера используя Kubernetes с возможностью Auto-Scaling. Этот open-source проект был создан в 2018 году, уже набрал 2500 звезд, был на Google I/O 2019, и на Хабре, к великому удивлению, еще не был упомянут. В топике описан краткий экскурс в архитектуру и инструкция по запуску тестового сервера на локальной машине. Если интересно, добро пожаловать под кат, вперед!


Agones logo

Описание проекта


Agones представляет собой Custom Resource (расширение Kubernetes API).


Проект в действительности требует большего внимания, так как позволяет запускать единичный игровой сервер (GameServer) или же целый "флот" серверов (Fleets) посредством конфигурационных yaml файлов, через Agones API. В свою очередь, каждый сервер дает оповещения о его жизненном цикле (GameServer lifecycles), описывая текущий статус (health checking, connection information). Сервера в кластере имеют возможность автоматического масштабирования (Fleet Autoscaling), которые интегрированы с базовыми возможностями Kubernetes. В дополнение, есть вывод статистики на панели (dashboard) с помощью Prometheus, Grafana или Stackdriver, экспортируются метрики посредством OpenCensus, что позволяет добавить собственный экспортер. Пример dashboard'a в Stackdriver:


image


Архитектура, основные элементы


Сам по себе Agones берет на себя задачу запуска, автоматического расширения и хостинга игровых серверов используя в основе Kubernetes. Это позволяет сосредоточиться на разработке самого сервера многопользовательской игры, вместо разработки ее инфраструктуры и дальнейшей поддержки. Можно использовать любой игровой сервер, который может быть запущен на linux, причем он может быть написан на любом языке программирования.


Agones Kubernetes API делится на три основных пакета (packages), в каждом из которых находятся ресурсы: agones.dev (GameServer, GameServerSet, Fleet), allocation.agones.dev (GameServerAllocation), autoscaling.agones.dev (FleetAutoscaler). Как и в других ресурсах Kubernetes для их запуска используется yaml файлы.


Краткое описание каждого ресурса:


  • GameServer — создает некий шаблон, который позволяет использовать обычные Pod параметры, с некоторыми дополнениями, такие как hostPort и containerPort для игрового сервера. Agones SDK предоставляет дополнительный контейнер "помощник" (sidecar), с которым GameServer в процессе будет постоянно общаться
  • GameServerSet — структура данных для нескольких GameServer, очень схоже с отношением между Depoyment и ReplicaSet
  • Fleet — создает несколько готовых GameServer, используется GameServerAllocation для распределения ресурсов
  • GameServerAllocation — запрашивает GameServer из Fleet для использования и помечает, что он готов для использования игроками, благодаря этому GameServer не будет автоматически удален
  • FleetAutoscaler — автоматически расширяет или, наоборот, уменьшает количество серверов во Fleet

Диаграмма (отсюда) показывает жизненный цикл GameServer ресурса:



Фиолетовыми стрелками отмечена работа Agones SDK, красным — API пользователя, синим — контроллер игрового сервера, желтым — контроллер приложения.


Установка


В данном и последующих разделах используются команды с инструкции на официальном сайте, с некоторыми дополнениями. Рекомендуется использовать Kubernetes версии 1.12 (протестировано разработчиками). Для теста на локальном компьютере можно использовать minikube, который потребует kubectl и гипервизор (Hyper-V или VirtualBox) поддерживаемый операционной системой.


Для установки кластера и Agones необходимо запустить следующие команды:


minikube profile agones #создадим профиль под названием agones
minikube start --kubernetes-version v1.12.10 --vm-driver hyperv #virtualbox
minikube status #статус кластера для созданного профиля
kubectl create namespace agones-system #создадим пространство имен для agones
kubectl apply -f https://raw.githubusercontent.com/googleforgames/agones/release-1.0.0/install/yaml/install.yaml

Последняя команда скачивает конфигурационный файл Agones создающий Custom Resource Definitions (CRD) через Kubernetes API.


Запуск GameServer


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


#создание GameServer ресурса
kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.0.0/examples/simple-udp/gameserver.yaml
kubectl get gameservers #список всех GameServer
minikube ip #адрес для подключения к серверу
kubectl describe gameserver #параметры и статус каждого GameServer
kubectl get gs #более удобная команда, список всех GameServer

Для подтверждения того, что сервер работает можно использовать NetCat, для linux программа обычно идет в поставке с системой, для windows её нужно скачать, к примеру здесь. NetCat нужно запустить с параметром -u (UDP запрос), указывая адрес minikube (лучше скопировать адрес с команды minikube ip) и активный порт GameServer:


echo "hello" | nc -u $(minikube ip) 7331

Если после запуска команды в консоли появится ответ "ACK: hello", то сервер работает, его можно выключить следующей командой, которая инициализирует :


echo "EXIT" | nc -u $(minikube ip) 7331

Статус сервера проверяется командой kubectl describe gameserver, он должен поменяться на Shutdown.


Вносим изменения в GameServer


Используя предыдущий пример изменим ответ сервера. Для начала скопируем репозиторий проекта:


git clone git@github.com:googleforgames/agones.git

В файле agones/examples/simple-udp/main.go поменяем строку 159 на


respond(conn, sender, "ACKNOWLEDGED: "+txt+"\n")

Из корневой папки проекта запустим следующее, чтобы создать docker image и сохранить его в minikube. Для windows предварительно нужно запустить minikube docker-env | Invoke-Expression, для linux eval $(minikube docker-env). Это позволит создавать docker images напрямую в minikube.
Создадим docker image:


docker build -t agones-go:modified -f .\examples\simple-udp\Dockerfile .

Эта команда может занять некоторое время, так как весь репозиторий проекта будет копироваться в image. Этого можно избежать, если в директории оставить только папку sdks, файл main.go и Dockerfile.


Далее в examples\simple-udp\gameserver.yaml изменим строку 28 на image: agones-go:modified и создадим новый GameServer:


kubectl create -f .\examples\simple-udp\gameserver.yaml

Проверим изменения и выключим сервер:


echo "hello" | nc -u 172.17.113.72 7331
echo "EXIT" | nc -u 172.17.113.72 7331

Если после запуска команд в консоли появится ответ "ACKNOWLEDGED: hello", то внесенные изменения прошли успешно.


Запускаем сервер локально


Итерировать изменения для удобной разработки можно и без Kubernetes, используя только Agones SDK. Во время работы игрового сервера SDK общается через TCP с маленьким gRPC сервером, который Agones запускает в контейнере под тем же namespace. Такой контейнер в Kubernetes называется sidecar. Поэтому, для локальной разработки необходимо запустить процесс SDK. Для этого потребуется запустить его исходный файл с параметром -local, который включает режим 'local mode'. Этот режим говорит процессу быть в пассивном режиме и никуда не подсоединяться, только лишь выводить логи в консоль, чтобы можно было видеть, что делает SDK во время работы игрового сервера.


Скачать последний agonessdk-server можно в релизах официального репозитория проекта. По умолчанию, после запуска SDK сервера создается болванка конфигурации GameServer, которая используется для GameServer() и WatchGameServer() SDK запросов. При запуске можно указать и собственный конфигурационный файл в формате yaml или json, для этого потребуется параметр -file или его сокращенная версия -f вместе с параметром -local.


.\sdk-server --local -f .\examples\simple-udp\gameserver.yaml
sdk-server : {"ctlConf":{"Address":"localhost","IsLocal":true,"LocalFile":".\\examples\\simple-udp\\gameserver.yaml","Timeout":0,"Test":""},"grpcPor
t":59357,"httpPort":59358,"message":"Starting sdk sidecar","severity":"info","source":"main","time":"2019-09-29T12:45:59.8379817+02:00","version":"1.0.0"}
{"filePath":"C:\\agones-release-1.0.0\\examples\\simple-udp\\gameserver.yaml","message":"Reading GameServer 
configuration","severity":"info","time":"2019-09-29T12:45:59.8479789+02:00"}
{"message":"Starting SDKServer grpc service...","severity":"info","source":"main","time":"2019-09-29T12:45:59.8529791+02:00"}
{"message":"Starting SDKServer grpc-gateway...","severity":"info","source":"main","time":"2019-09-29T12:46:00.1555756+02:00"}

Продолжение следует...

Комментарии (8)


  1. Sazonov
    29.09.2019 20:09

    Спасибо за статью.
    Сборка C++ SDK на винде несколько нетривиальна из-за зависимостей. Лучше всего иметь уже собранный protobuf и gRPC, тогда всё будет ок. Кода в самом sdk мало, там в основном кодогенерация, поэтому всё компилируется вполне тривиально.
    В ином случае, cmake скрипт попытается сам скачать и собрать требуемые зависимости. Из-за зоопарка компиляторов и возможных вариантов сборки это может быть несколько проблематично. К примеру, для успешной сборки gRPC требуется OpenSSL, а собирать его под винду с помощью mingw — то ещё удовольствие.
    Если вы посоветуете какой-либо стабильный package manager, который умеет protobuf+gRPC под мак/линукс/винду, то я постараюсь его прикрутить.
    gRPC тот ещё монстр, к сожалению из коробки там очень мало опций и единственный способ получить полноценный cmake package — это собрать его целиком.


    1. AlexZ005 Автор
      29.09.2019 23:15

      Согласен, компиляция на Windows может стоить долгих изысканий, но и на Linux достаточно приключений с версиями библиотек. Количество кода в SDK действительно вполне адекватно.
      Однако, стоит учитывать, что серверная часть все же компилируется во время создания docker image (вместе с gRPC и protobuf), а поверх уже можно накладывать и код игрового сервера. Если итерирывать на уровне GameServer ресурса в Windows, это несколько упрощает задачу, в этом и есть вся прелесть контейнеризации процессов.
      Спасибо за предложение помочь, правда package manager будет сложно так сразу предложить, если и нужно компилировать игровой код сервера на локальной машине, то думаю будет логичней использовать туже операционную систему и конфигурацию, что использует Dockerfile.
      Очень интересно какой вариант в опросе будет превалировать в итоге.


      1. Sazonov
        30.09.2019 10:25

        Я про то, что вся docker сборка Agones изначально заточена под Linux / WSL. Под другое платформы CI/CD из коробки не заведётся. SDK под windows нужно собирать руками средствами cmake.
        Если что, то с большего там я автор cmake сборки, поэтому критика приветствуется.


  1. gecube
    30.09.2019 07:25

    1. Как себя игровой сервер поведет в случае, если нода кубернетеса "ушла"? Он сможет перепозлти на другой сервер или предполагается, что все — приплыли и надо игровую сессию на клиенте запускать заново? Ну, получается, что требования по надёжности нод весьма драконовские — на спот (preemptible) инстансах уже сервачки не погоняешь.
    2. Что-нибудь серьезное уже кто-либо поверх этого фреймворка сделал?
    3. Поддержка windows?


    1. Sazonov
      30.09.2019 10:30

      3) Поддержка windows
      Игровые сервера можно делать под любые платформы. На C++ там простейшая реализация. Главное, чтобы на вашей платформе можно было собрать gRPC.
      В крайнем случае можно посмотреть исходники плагина для UE и сделать по аналогии.
      А на чём крутить сам Agones думаю вам не принципиально. Linux/Mac умеет, Windows умеет (с WSL).


      1. gecube
        30.09.2019 10:58

        ну, я просто к тому, что (внезапно!) оказалось, что кубернетес умеет поддерживать ноды с windows (нативно). Control plane все равно линуксовый, но очень интересно делать такие гибридные решения.


    1. aLekSer
      30.09.2019 17:33

      2 На данный момент есть работающие на Agones игры с 20 тысяч + пользователей.
      Список компаний, использующих Agones можно посмотреть здесь Companies using Agones
      В проекте также активно используется Slack, где можно задать все интересующие вопросы.


      В комплексе с Agones еще стоит рассмотреть Open Match, который можно использовать для Match Making'а .


  1. aLekSer
    30.09.2019 17:21
    +1

    Agones — это платформа для оркестрации выделенных игровых серверов в Kubernetes.
    Стоит упомянуть про сайт проекта — agones.dev, где есть необходимая документация и описание всех Custom Resource Definitions, которые используются в платформе Agones (все-таки это не один ресурс). Сайт генерируется из md файлов с помощью Hugo.
    Так же стоит упомянуть, что билд всех бинарей происходит в docker'e, что удобно и позволяет получить унифицированную среду компиляции.
    В папке build находится описание различных make target'ов, для выполнения сборки, запуска тестов и много другого (см. build/readme.md).
    Используется Helm и gcloud. Есть Terraform конфигурации для развертывания системы.
    Также существует Terraform конфиги и документация для развертывания в MS Azure и AWS EKS (в процессе).