Originally posted on compoundtheory.com.
This is part one of a fivefour-part series on scaling game servers with Kubernetes.
For the past year and a half, I’ve been researching and building a variety of multiplayer games. Particularly those in the MMO or FPS genres, as they have some unique and very interesting requirements for communication protocols and scaling strategies. Due to my background with software containers and Kubernetes, I started to explore how they could be used to to manage and run dedicated game servers at scale. This became an area of exploration for me, and honestly I’ve been quite impressed with the results.
Why Are You Doing This Thing?
While containers and Kubernetes are cool technologies, why would we want to run game servers on this platform?
Game server scaling is hard, and often the work of proprietary software - software containers and Kubernetes should make it easier, with less coding.
Containers give us a single deployable artifact that can be used to run game servers. This removes the need to install dependencies or configure machines during deployment, as well as greatly increases confidence that software will run the same on development and testing as it will in production.
The combination of software containers and Kubernetes lets us build on top of a solid foundation for running essentially any type of software at scale - from deployment, health checking, log aggregation, scaling and more, with APIs to control these things at almost all levels.
At its core, Kubernetes is really just a cluster management solution that works for almost any type of software. Running dedicated games at scale requires us to manage game server processes across a cluster of machines - so we can take advantage of the work already done in this area, and just tailor it to fit our specific need.
Both of these projects are open source, and actively developed, so we can also take advantage of.any new features that are developed going forward
If you want to learn more about the intricacies of designing and developing communication and backends for FPS/MMO multiplayer games from the ground up I suggest starting with the articles on Gaffer on Games or, if you prefer books, The Development and Deployment of Multiplayer Games.
Disclaimer
I will put one proviso on all of this. While I am aware of more than a few companies that are containerising their game servers and running them in production, I am not aware of any that are doing so on Kubernetes. I have heard of some that are experimenting with it, but don’t have any confirmed production uses at this stage. That being said, Kubernetes itself is being used by many large enterprises, and I feel this technology combination is solid, super interesting, and could potentially save game studios a lot of time. However, I am still working out where all the edges are. That being said, I will be happily sharing the results of all my research - and would love to hear from others on their experiences.
Paddle Soccer
(Paddle Soccer in action. What a game!)
To test out my theories, I created a very simple Unity based game called Paddle Soccer, which is essentially exactly as described. It’s a two-player, online game in which each player is a paddle, and they play soccer, attempting to score goals against each other. It has a Unity client as well as a Unity dedicated server. It takes advantage of the Unity High Level Networking API to provide the game state synchronisation and UDP transport protocol between the servers and the client. If you are curious, all the code is available on GitHub for your perusal. It’s worth noting that this is a session-based game; i.e.. you play for a while, and then the game finishes and you go back to the lobby to play again, so we will be focusing on that kind of scaling as well as using that design to our advantage when deciding when to add or remove server instances. That being said, in theory these techniques would work with a MMO type game, with some adjustment.
Paddle Soccer Architecture
Paddle Soccer uses a traditional overall architecture for session-based multiplayer games:
Players connect to a matchmaker service, which pairs them together, using Redis to help facilitate this.
Once two players are joined for a game session, the matchmaker talks to the game server manager, to get it to provide a game server on our cluster of machines.
The game server manager creates a new instance of a game server that runs on one of the machines in the cluster
The game server manager also grabs the IP address and the port that the game server is running on, and passes that back the matchmaker service
The matchmaker service passes the IP and port back to the players’ clients
...and finally the players connect directly to the game server and can now start playing the game against each other
Since we don’t want to build this type of cluster management and game server orchestration ourselves, we can rely on the power and capabilities of containers and Kubernetes to handle as much of this work as possible.
Containerising the Game Server
The first step in this process is putting the game server into a software container, so that Kubernetes can deploy it. Putting the game server inside a Docker container is essentially the same as containerising any other piece of software.