Одним из ключевых преимуществ использования Kubernetes является огромная экосистема вокруг него. От Rancher до Istio, от Rook до Fission, от gVisor до KubeDB, экосистема Kubernetes богата, динамична и постоянно растет. Мы подошли к тому, что для большинства потребностей в развертывании мы можем сказать, что для этого существует проект с открытым исходным кодом на основе K8s.
Одним из последних дополнений к этой экосистеме является проект Agones, многопользовательский, выделенный хостинг на игровом сервере с открытым исходным кодом, построенный на Kubernetes, разработанный Google в сотрудничестве с Ubisoft. Проект был анонсирован в марте, и уже наделал немало шума…
В OVH Platform Team мы являемся поклонниками онлайн-игр и Kubernetes, поэтому мы сказали себе, что нам нужно протестировать Agones. И какой лучший способ проверить это, чем развернуть его в нашей службе OVH Managed Kubernetes, установить кластер игровых серверов Xonotic и сыграть в старом классе с коллегами?
Почему агон?
Agones (происходит от греческого слова agōn, конкурсы, проводимые во время публичных фестивалей или, в более широком смысле, «соревнование» или «соревнование в играх»), стремится заменить обычные проприетарные решения для развертывания, масштабирования и управления игровыми серверами.
www.merriam-webster.com/dictionary/agones
kubernetes.io/docs/concepts/api-extension/custom-resources/#custom-controllers
kubernetes.io/docs/concepts/api-extension/custom-resources/#customresourcedefinitions
Agones обогащает Kubernetes пользовательским контроллером и пользовательским определением ресурса. С их помощью вы можете стандартизировать инструменты и API Kubernetes для создания, масштабирования и управления кластерами игровых серверов.
Подождите, о каких игровых серверах вы говорите?
Итак, основное внимание Agones уделяют многопользовательским онлайн-играм, таким как FPS и MOBA, быстрым играм, требующим выделенных игровых серверов с малой задержкой, которые синхронизируют состояние игры между игроками и служат источником правды в игровых ситуациях.
Игры такого типа требуют относительно эфемерных выделенных игровых серверов, причем каждое совпадение выполняется на экземпляре сервера. Серверы должны быть с состоянием (они должны сохранять статус игры), причем состояние обычно хранится в памяти на время матча.
Задержка является ключевой проблемой, поскольку конкурентные аспекты игр в реальном времени требуют быстрого ответа от сервера. Это означает, что подключение от устройства игрока к игровому серверу должно быть максимально прямым, в идеале, в обход любого промежуточного сервера, такого как балансировщик нагрузки.
А как вы подключаете плееры к нужному серверу?
Каждый издатель игр имел свои собственные проприетарные решения, но большинство из них следуют аналогичному потоку, предлагая сервис по подбору игроков, который объединяет игроков в матчи, взаимодействует с менеджером кластера для предоставления выделенного экземпляра игрового сервера и отправки игрокам его IP-адрес и порт, чтобы позволить им напрямую подключаться к серверу и играть в игру.
Agones и его пользовательский контроллер и пользовательское определение ресурса заменяет сложную инфраструктуру управления кластером стандартизированными инструментами и API на основе Kubernetes. Службы сватов взаимодействуют с этими API-интерфейсами для создания новых модулей игровых серверов и передачи их IP-адресов и портов заинтересованным игрокам.
Вишня на торте
Использование Kubernetes для этих задач также дает приятный дополнительный бонус, например, возможность развертывать полную игровую инфраструктуру в среде разработчика (или даже в мини-кубе) или легко клонировать ее для развертывания в новом центре обработки данных или облачной области, но также предлагая целую платформу для размещения всех дополнительных услуг, необходимых для создания игры: управление учетными записями, списки лидеров, инвентарь
github.com/kubernetes/minikube
И, конечно же, простота эксплуатации платформ на базе Kubernetes, особенно когда они динамические, разнородные и распределенные, как большинство игровых онлайн-платформ.
Развертывание Agones на управляемых OVH Kubernetes
Есть несколько способов установить Agones в кластер Kubernetes. Для нашего теста мы выбрали самый простой: установка с помощью Helm.
helm.sh/
Включение создания ресурсов RBAC
Первым шагом для установки Agones является настройка учетной записи службы с достаточными разрешениями для создания некоторых специальных типов ресурсов RBAC.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin --serviceaccount=kube-system:default
Теперь у нас есть Cluster Role Binding, необходимая для установки.
kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding
Установка диаграммы Agones
Теперь давайте продолжим, добавив хранилище Agones в список хранилищ Helm.
helm repo add agones https://agones.dev/chart/stable
И затем установка стабильной диаграммы Agones:
helm install --name my-agones --namespace agones-system agones/agones
agones.dev/site/docs/installation/helm/
Установка, которую мы только что выполнили, не подходит для производства, так как в официальных инструкциях по установке рекомендуется использовать Agones и игровые серверы в отдельных выделенных пулах узлов. Но для нужд нашего теста достаточно базовой настройки.
Подтверждение Agones началось успешно
Чтобы убедиться, что Agones работает в нашем кластере Kubernetes, мы можем взглянуть на модули в пространстве имен agones-system:
kubectl get --namespace agones-system pods
Если все в порядке, вы должны увидеть модуль контроллера agones со статусом Running:
$ kubectl get --namespace agones-system pods
NAME READY STATUS RESTARTS AGE
agones-controller-5f766fc567-xf4vv 1/1 Running 0 5d15h
agones-ping-889c5954d-6kfj4 1/1 Running 0 5d15h
agones-ping-889c5954d-mtp4g 1/1 Running 0 5d15h
Вы также можете увидеть более подробную информацию, используя:
kubectl describe --namespace agones-system pods
Глядя на описание agones-контроллера, вы должны увидеть что-то вроде:
$ kubectl describe --namespace agones-system pods
Name: agones-controller-5f766fc567-xf4vv
Namespace: agones-system
[...]
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Где все Условия должны иметь статус True.
Развертывание игрового сервера
Мир Agones Hello довольно скучный, простой эхо-сервер UDP, поэтому мы решили пропустить его и перейти непосредственно к чему-то более интересному: игровому серверу Xonotic.
github.com/GoogleCloudPlatform/agones/tree/release-0.9.0/examples/simple-udp
github.com/GoogleCloudPlatform/agones/blob/release-0.9.0/examples/xonotic
www.xonotic.org/
Xonotic — это многопользовательский FPS с открытым исходным кодом, довольно неплохой, с множеством интересных игровых режимов, карт, оружия и опций настройки.
Развернуть игровой сервер Xonotic поверх Agones довольно просто:
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/agones/release-0.9.0/examples/xonotic/gameserver.yaml
Развертывание игрового сервера может занять несколько минут, поэтому нам нужно подождать, пока его состояние не станет «Готов», прежде чем использовать его. Мы можем получить статус с:
kubectl get gameserver
Мы ждем, пока извлечение не даст статус Ready на нашем игровом сервере:
$ kubectl get gameserver
NAME STATE ADDRESS PORT NODE AGE
xonotic Ready 51.83.xxx.yyy 7094 node-zzz 5d
Когда игровой сервер готов, мы также получаем адрес и порт, который мы должны использовать для подключения к нашей игре Deathmatch (в моем примере, 51.83.xxx.yyy: 7094).
Время фрагмента
Теперь, когда у нас есть сервер, давайте проверим его!
Мы загрузили клиент Xonotic для наших компьютеров (он работает на Windows, Linux и MacOS, так что оправданий нет) и запустили его:
Затем мы идем в многопользовательское меню и вводим адрес и порт нашего игрового сервера:
И мы готовы играть!
А на стороне сервера?
Со стороны сервера мы можем следить за тем, как идут дела на нашем игровом сервере, используя логи kubectl. Давайте начнем с поиска модуля, на котором запущена игра:
kubectl get pods
Мы видим, что наш игровой сервер работает в модуле под названием xonotic:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
xonotic 2/2 Running 0 5d15h
Затем мы можем использовать логи kubectl. В модуле есть два контейнера, основной ксонотический и колонтитул Agones, поэтому мы должны указать, что нам нужны журналы ксонотического контейнера:
$ kubectl logs xonotic
Error from server (BadRequest): a container name must be specified for pod xonotic, choose one of: [xonotic agones-gameserver-sidecar]
$ kubectl logs xonotic xonotic
>>> Connecting to Agones with the SDK
>>> Starting health checking
>>> Starting wrapper for Xonotic!
>>> Path to Xonotic server script: /home/xonotic/Xonotic/server_linux.sh
Game is Xonotic using base gamedir data
gamename for server filtering: Xonotic
Xonotic Linux 22:03:50 Mar 31 2017 - release
Current nice level is below the soft limit - cannot use niceness
Skeletal animation uses SSE code path
execing quake.rc
[...]
Authenticated connection to 109.190.xxx.yyy:42475 has been established: client is v6xt9/GlzxBH+xViJCiSf4E/SCn3Kx47aY3EJ+HOmZo=@Xon//Ks, I am /EpGZ8F@~Xon//Ks
LostInBrittany is connecting...
url_fclose: failure in crypto_uri_postbuf
Receiving player stats failed: -1
LostInBrittany connected
LostInBrittany connected
LostInBrittany is now spectating
[BOT]Eureka connected
[BOT]Hellfire connected
[BOT]Lion connected
[BOT]Scorcher connected
unconnected changed name to [BOT]Eureka
unconnected changed name to [BOT]Hellfire
unconnected changed name to [BOT]Lion
unconnected changed name to [BOT]Scorcher
[BOT]Scorcher picked up Strength
[BOT]Scorcher drew first blood!
[BOT]Hellfire was gunned down by [BOT]Scorcher's Shotgun
[BOT]Scorcher slapped [BOT]Lion around a bit with a large Shotgun
[BOT]Scorcher was gunned down by [BOT]Eureka's Shotgun, ending their 2 frag spree
[BOT]Scorcher slapped [BOT]Lion around a bit with a large Shotgun
[BOT]Scorcher was shot to death by [BOT]Eureka's Blaster
[BOT]Hellfire slapped [BOT]Eureka around a bit with a large Shotgun, ending their 2 frag spree
[BOT]Eureka slapped [BOT]Scorcher around a bit with a large Shotgun
[BOT]Eureka was gunned down by [BOT]Hellfire's Shotgun
[BOT]Hellfire was shot to death by [BOT]Lion's Blaster, ending their 2 frag spree
[BOT]Scorcher was cooked by [BOT]Lion
[BOT]Eureka turned into hot slag
[...]
Добавьте друзей
Следующий шаг в основном приятен: попросить коллег подключиться к серверу и провести настоящий Deathmatch, как в Quake 2 раза.
И сейчас?
У нас есть работающий игровой сервер, но мы едва раскрыли возможности Agones: развертывание флота (набор теплых GameServer, доступных для распределения), тестирование FleetAutoscaler (для автоматического увеличения и уменьшения флота в ответ на спрос), делая некоторые фиктивные услуги распределителя. В будущих публикациях в блоге мы углубимся в это и рассмотрим эти возможности.
agones.dev/site/docs/tutorials/allocator-service-go/
agones.dev/site/docs/reference/fleet/
agones.dev/site/docs/reference/fleetautoscaler/
И в более широком контексте мы собираемся продолжить наше исследовательское путешествие по Агонесу. Проект еще очень молодой, ранняя альфа, но он показывает некоторые впечатляющие перспективы.