The Essential Guide To Load-Balancing Minecraft Servers With Kong Gateway

Drag to rearrange sections
Rich Text Content


Dev Spotlight is my company. We create tech content for tech companies. Email at [email protected]



It's time to have some fun. Tell your family, friends, and coworkers that you're conducting research, or trying out new tech. But don't let your family see that you're playing Minecraft!



Here's how it works: You organize a Minecraft class for local students in STEM. You need to run your own Minecraft servers to ensure a kid-friendly multiplayer environment, restricted only to your students. Two servers won't suffice so you'll need to run them both simultaneously. Your load balancer should be able to send students to Server A or Server B depending on how busy they are.



In this article, we're going to explore port forwarding and load balancing with Kong Gateway. We're going to do this by spinning up multiple Minecraft servers, and then placing Kong Gateway in front of these upstream services to handle port forwarding and load balancing.



Before we dive in, let's briefly cover a few important technology concepts.



Key Concepts



Port forwarding is receiving network requests on a certain port of a machine and forwarding those requests to a different port. This task is typically handled by a router or firewall. You might have a webserver listening on port 3000, and a database server listening at port 5000. Your API gateway would listen out for requests from outside of your network. Requests addressed to port 80 would be forwarded by the gateway to your web server at port 3000. Meanwhile, requests addressed to port 5432 would be forwarded to your database server at port 5000.



Load Balancing



Load-balancing is the process of distributing multiple requests across multiple servers in a balanced fashion. This task is typically handled by a particular piece of hardware, or software, called a "load balancer". The outside world is unaware that there are multiple replicas of a server running. They think they are requesting information from one server. The load balancer distributes the request loads to keep any one server from becoming overwhelmed. The load balancer ensures all requests are sent to healthy nodes in the unlikely event that a replica fails completely.



Kong Gateway



Kong Gateway is a thin API gateway that sits between upstream services. It's capable of performing load balancing and port forwarding tasks. Kong Gateway can greet all requests regardless of whether they are web servers, databases, or Minecraft game server servers. Kong Gateway is capable of managing traffic control as well as authentication, request transformations (analytics), and logging.



TCP Stream Support



Our Minecraft project differs from other web servers and databases in that Minecraft requires a established connection between the Minecraft client and server. Instead of accepting stateless HTTP requests, we will be handling TCP connections with streaming data. Fortunately, Kong Gateway fully supports TCP streaming.



Our project approach



We'll walk you through this project step by step.



1. Spin up a single, local Minecraft server without any port forwarding. 2. Spin up a Minecraft server on a non-default port, configuring Kong Gateway to port forward requests to that server. 3. Spin up two Minecraft servers on different ports, configuring Kong Gateway to load balance and port forward connection requests.


As you can see, we'll start simple, and we'll slowly build on complexity.



What you'll need to get started



This mini-project does not require you to have a lot knowledge of Minecraft. Since it's easiest to spin up Minecraft servers within Docker containers, basic familiarity with Docker may be helpful.



Docker Engine will need to be installed on your local machine. If you want to check that our project results have been successful, you will need the Minecraft client installed and logged in as a paid user. Minecraft's free trial does not allow you to connect to multiplayer servers. This is what we will be using for our project.



Are you up for it? Here we go!



Step 1: Single Minecraft Server with Default Port



In this first step, we want to spin up a single Minecraft server on our local machine. We'll use the default port for the server, and then we'll connect our game client to the server. It's simple to deploy the Minecraft server as a Docker container, with the Docker image found here.



This command will be executed in a terminal window to pull down the server images and spin them up in a container.



As our container starts up, it downloads the Docker image for the Minecraft server. Once the image downloads, it starts up the server, and we see the log messages of the server startup. Here are the flags and options that we gave to docker run in this command:



-p is a port on your local machine (host port) that Docker should connect to a container port. In this example, the port 25000 on our local machine will point to port 25565 on the container. By default, Minecraft servers run on port 25565. Regardless of the port on your host, you will bind to the container's port 25655.


-e EULA=true specifies the environment variable that Docker container must use to start up the server within the container. The Minecraft server application requires that you accept the EULA upon startup. This environment variable can also be done using Docker.


- Lastly, we specify the name of the Docker image (on DockerHub), which contains the Minecraft server.


With our server running, let's see if we can connect to the server at localhost:25000. Open up the Minecraft Launcher client and click on "Play".



You should see the actual Minecraft game launch. Click on "Multiplayer" for more game options.



Next, click on "Direct Connection".



For server address, enter localhost:25000. Our local port 25000, of course, is bound to the container running our Minecraft server. Finally, click on "Join Server".



And... we're in!



If you look back at the terminal with the docker run command, you'll recall that it continues to output the log messages from the Minecraft server. It could look something like this.



The server notes that a new player (my username is familycodingfun ) has joined the game. Our single game server setup has been completed. Let's now add Kong Gateway to the mix. We will now exit the game, kill our Docker containers and send them to the server.



Step 2: Minecraft Server with Kong Gateway and Port Forwarding



Next, we'll put Kong Gateway in front of our Minecraft server and take advantage of port forwarding. If you were running a private network, you might forbid requests from outside the network to reach your Minecraft server port. You might also expose one port that Kong listens on. Kong, as the API gateway, would listen to requests on that port and then forward those requests to your Minecraft server. Doing so ensures that any requests that want to go to a Minecraft server must go through Kong first.



Although we will be working with localhost, this type of port forwarding will be done through Kong. Just like in our previous step, we want our Minecraft server to run on port 25000. Meanwhile, Kong will listen on port 20000. Kong will take TCP connection requests on port 20000 and forward them to the Minecraft server at port 25000.



Install and Setup Kong



Install Kong Gateway first. The steps for each setup will vary. After installing Kong, you will need to create the initial configuration file. You'll find a template file called kong.conf.default in your /etc/kong directory. We will copy the file and rename it kong.conf. This is the file Kong will use to configure its startup.



We'll need to make three edits to kong.conf:



The stream_listen configuration tells Kong it to listen for streaming TCP trafic. For this, we tell Kong that it should listen on port 20000. We can configure Kong using its DBless and Declarative configuration styles for this mini project. Kong will not use a database (database=off), so all of our configurations, including those for port forwarding or load balancing, will be stored in a single YAML. This is the path for declarative_config files that we've given above.



Write Declarative Configuration File



Before we start Kong, we need the minecraft.yml file to contain our port forwarding configuration. Open minecraft.yml, a file that corresponds to the path you specify above, in a project folder.



This file will declare a new Service entity called Minecraft Server-A. These values are used as the service's URL. The server uses TCP protocol and is listening on localhost port 25000. Next, we define a Route for the service, which associates our service with a URL path or an incoming connection destination that Kong will listen for. We give Kong a name to our route and tell Kong to listen to requests using TCP/TLS at the destination we specified in kong.conf: port 20000 and ip 127.0.0.1.



Start Up Minecraft Server and Kong



This step is complete. Let's start up our Minecraft server in Docker. Remember, we want our host (our local machine) to be ready on port 25000, binding that port to the standard Minecraft server port of 25565 on the container:



That command might take a little time to run as the server starts up.

Now, we'll open Kong in a separate terminal.


~/project$ sudo kong start



Once our server is up and running, we return to our game client and choose "Multiplayer" to try to establish a "Direct Connection". We know that we could connect directly to localhost:25000, since that's the actual host port bound to the container's port; rather, we want to test Kong's port forwarding. We want to connect to the supposed game server on localhost:20000, pretending that we're the casual user who is unaware that port 20000 points to a port forwarding gateway.



Click on "Join Server." As in Step 1, your connection should be successful and you will be able to access the Minecraft world. Our TCP connection request to localhost:20000 went to Kong Gateway, which then forwarded that request to port 25000, our actual Minecraft server. Port forwarding is up and running!



Step 3: Load-Balancing Two Minecraft Servers



We will spin up two Minecraft servers for the final step in our mini-project, listening on ports 25000 and 26000. Previously, when we only had one Minecraft server, Kong would naturally forward TCP requests at port 20000 to that sole Minecraft server's port. Now, with two Minecraft server ports to choose from, we'll need to use port forwarding and load balancing. Kong Gateway will take TCP connection requests that come to port 20000 and distribute connections evenly between Minecraft Server A and Minecraft Server B.



Start Up Minecraft Servers



If you haven't done so already, terminate the single Minecraft server that was running in the previous step. We'll restart everything from a clean slate, spinning each server up in its own terminal window. In the first terminal, run the Docker Container for Server A. Bind Server 25000 to the container’s port 25565.



~/project$ docker run -p 25000:25565 -e EULA=true itzg/minecraft-server



In a separate terminal, we will launch Server B. This time, the host's port 26000 is bound to the container’s port 25565.



~/project$ docker run -p 26000:25565 -e EULA=true itzg/minecraft-server



Servers A, and B, are now available at ports 25000 to 26000, respectively.



Modify Declarative Configuration File



Next, we will edit our declarative file (minecraft-kong.yml), configuring Kong to load balance. To reflect the following, edit your file.



Let's walk through what we've done here. First, we created an upstream object (arbitrarily titled Minecraft Servers), which serves as a virtual hosting server for load balancing between multiple services. That's exactly the functionality that we need. Two Target Objects were added to our upstream service. Each target has an address with host and port; in our case, our two targets point to localhost:25000 (Minecraft Server A) and localhost:26000 (Minecraft Server B). Next, we assign a weight to each target. This is what the load balancer uses for load distribution. Even though we've explicitly set the weights evenly to 100, the default for this optional configuration is 100.



Next, we declared our Service Object, which in this case is our load balancer service. Requests that meet the routes we have established will be sent to Minecraft-Servers host, which is our load balancing upstream object. Similar to our previous step, we configured a route, telling Kong Gateway to listen for TCP/TLS requests destined for 127.0.0.1:20000.



Restart Kong



Our Kong configuration has changed. We must restart Kong to allow the changes to take affect.



~/project$ sudo kong restart



Everything is now up and running. We have our two Minecraft servers (Server A and Server B) running in Docker containers in two separate terminal windows. We have Kong configured to listen for TCP on port 20000, forwarding those requests to our load balancer, distributing connections across our two servers.
Minecraft-server-list.Info



Reopen the Minecraft client. Similar to previous steps above, we will attempt direct connection to the localhost server:20000. Keep an eye on the two terminal windows of your server as you connect. As you connect to the game repeatedly, disconnect, then reconnect, you may see a connection log message from Server A at times, and another message from Server B at other times.



And just like that, we have set up our load balancer to distribute connection requests across our two Minecraft servers!



Ready to (Play) Work



In summary, we gradually increased the complexity of our mini-project.



1. We started by simply spinning up a single Minecraft server in a Docker container, using port 25000 for accepting game client connections. 2. Next, we set Kong Gateway to be able to forward port requests to our single server. Kong listened on port 20000 for game client connections, forwarding those requests to the port on our host where the Minecraft server was accessible. 3. Lastly, we set up two Minecraft servers to run concurrently. We then set Kong Gateway up to act as a load-balancer. Kong Gateway then listened on port 20000 to game client connection requests, redirecting them through its load-balancing service.


This is where you can add complexity. You can add game servers. You can add more game servers to your network. You can configure health check rules for Kong's load balancer to ensure requests are only forwarded to those servers which are presently healthy. You can choose from a few load balancing strategies, in addition to the default round-robin strategy.



So far, we've had some fun, and have learned some important concepts and tools. Kong Gateway makes load balancing, port forwarding simple and easy. These features are very powerful, even though it is so easy. Now that you have a good grasp of the basics, it's time for you to tackle the Ender Dragon.

rich_text    
Drag to rearrange sections
Rich Text Content
rich_text    

Page Comments

No Comments

Add a New Comment:

You must be logged in to make comments on this page.