The Essential Guide To LoadBalancing Minecraft Servers With Kong Gateway

From Fake News
Jump to: navigation, search

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



It's time for some fun. It's okay to tell your family or colleagues that research is being done, that you're experimenting with new tech-because that's what we'll do-but don't let anyone see you playing Minecraft!



Let's say you're organizing a Minecraft class for local STEM students. 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 will explore port forwarding with Kong Gateway and load balancing. Minecraft Servers 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 refers to receiving network requests on a specific port of a computer and forwarding them to another port. This task is typically handled by a router or firewall. For example, a web server could listen on port 3000 and a server listening on 5000. Your API gateway would listen for outside requests. The gateway would forward requests to port 80 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 refers to the process of distributing multiple requests on a server in a balanced way across many replicas of that server. This is usually done by a piece of hardware or software known as a load balancer. The outside world doesn't know that there are multiple copies of a server. They believe they are making requests to only one server. The load balancer distributes the request loads to keep any one server from becoming overwhelmed. The load balancer ensures requests only reach healthy nodes in case of a total failure of the replica.



Kong Gateway



Kong Gateway is a thin API gateway layer that sits in front of upstream services, capable of performing these port forwarding and load balancing tasks. Kong Gateway can greet all requests regardless of whether they are web servers, databases, or Minecraft game server servers. Kong Gateway can also manage traffic control, authentication, request transformations and analytics.



TCP Stream Support



Minecraft, unlike other web servers and databases, requires a connection between the Minecraft client (the user) and the server. Instead of expecting stateless HTTP requests we will need to handle TCP connections using 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 will start simple and slowly increase complexity.



Here are the essentials to get you started



You don't actually need a lot of familiarity with Minecraft to progress through this mini-project. Since it's easiest to spin up Minecraft servers within Docker containers, basic familiarity with Docker may be helpful.



Docker Engine needs to be installed on the 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 test doesn't allow you connect to multiplayer servers. We'll be using this feature 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 is downloaded, it starts the server. We can see the log messages for the server startup. Here are the flags and options that we gave to docker run in this command:



-p specifies the port on the host (your machine) that Docker should bind with a port in the container. In this case, our local machine's port 25000 will point to the container's port 25565. By default, Minecraft servers run on port 25565. Typically, you will always bind to the container's port 25565, regardless of the port on the host that you choose to use. -e EULA=true is an environment variable that Docker container needs when starting up the server. The Minecraft server application requires that you accept the EULA upon startup. This environment variable can be provided by Docker. - Lastly, we specify the name of the Docker image (on DockerHub), which contains the Minecraft server. Now that our server is up, let's connect to localhost:25000. Open up the Minecraft Launcher client and click on "Play".



You should see the actual Minecraft game launch. For game options, click on "Multiplayer".



Next, click "Direct Connection".



For server address, enter localhost:25000. Our local port 25000, of course, is bound to the container running our Minecraft server. Finally, we click "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 reports that a new player has joined the game (my username is familycodingfun). The single game server setup is complete. Let's add Kong Gateway as well as port forwarding. We'll close the game now and kill the Docker container that we have with 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 to Kong that Kong listens to. 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.



We'll be working in localhost but we'll setup port forwarding 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 set up Kong



Install Kong Gateway first. The installation process will vary depending upon your particular setup. After installing Kong, it's time to set up the first configuration file. In your /etc/kong folder, you'll see a template file called kong.conf.default . We will copy the file and rename it kong.conf. This is the file Kong will use to configure its startup.



We will need to make these three edits in kong.conf



The stream_listen configuration tells Kong to listen for streaming TCP traffic. We're telling Kong to listen on port 20000 for this. For the needs of this mini project, we can configure Kong using its DB-less and Declarative configuration style. Kong will not need a database (database=off), as all configurations for port forwarding, load balancing, and load balancing can be stored in one YAML file. This is the path to declarative_config that we have set above.



Write Declarative Configuration File



Before we start up Kong, we need to write that minecraft-kong.yml file with our port forwarding configuration. Open minecraft-kong.yml in a folder that matches the path you have specified.



This file will declare a new Service entity called Minecraft Server-A. These values will be used as the service's web address. The server uses TCP protocol. It is listening on localhost port 250000. Next, we define a route for the service. This associates our server with a URL path, or an incoming connection destination, that Kong will listen to. We give Kong a route name, telling Kong that it will listen for requests using TCP/TLS to the destination specified in our kong.conf.



Start Up Minecraft Server and Kong



We have all the configuration needed for this step. 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:



As the server starts up, it might take some time for this command to run.

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 localhost:25000 is the host port bound to the container port. However, we want Kong to test Kong's 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." Like Step 1, your connection should be successful, and you'll have entered 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 will start everything from scratch, spinning up each server in its respective terminal window. In your first terminal window, run the Docker container for Server A, binding the host's port 25000 to the container's port 25565:



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



Then, in a separate terminal window, we will start up Server B, this time binding the host's port 26000 to the container's port 25565:



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



Now, Servers A & B are available at ports 25000 and 26000, respectively.



Edit Declarative Configuration File



Next, we want to edit our declarative configuration file (minecraft-kong.yml ), configuring Kong for load balancing. Make sure your file reflects the following:



Let's see what we've done. First, we created an upstream object (arbitrarily titled Minecraft Servers), which serves as a virtual hosting server for load balancing between multiple services. This is exactly the functionality we require. We added two Target Objects 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 have specified that the weights should be evenly distributed to 100, the default is 100 for this optional configuration.



Next, we created our Service Object. It is our load balancer. Requests that satisfy the routes we establish will be forwarded to the Minecraft-Servers host, our load balancing upstream object. Similar to the last step, we created a route to tell Kong Gateway to listen out for TCP/TLS queries destined for 127.0.0.1.20000.



Restart Kong



Since our Kong configuration has changed, we need to restart Kong for the changes to take effect:



~/project$ sudo kong restart



Everything is now fully operational. 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.



Open the Minecraft game client once again. Similar to the previous steps we will connect to the multiplayer server localhost:20000 directly. Keep an eye on the two terminal windows of your server as you connect. As you connect to the server, disconnect and reconnect repeatedly, you will sometimes see a connection message for Server A and a message for Client B.



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



Ready to (Play!) Work



To recap, we slowly progressed in complexity for 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 listened to port 20000 and routed game client connections through its load balancing service. This allowed us to distribute the connections between our two servers. There are many ways to add complexity from here. You can add additional game servers. If you have servers that can handle more connections than others, you can adjust the load balancer so that the load is distributed unevenly. To ensure that requests are only sent to the servers that are currently healthy, you can set up health check rules for Kong’s load balancer. You can also choose from a number of load balancing algorithms, other than the default "round-robin".



So far, we have had a lot of fun and learned some important tools and concepts. It's easy to set Kong Gateway up for load balancing or port forwarding. These features are still extremely powerful, even though they are simple to set up. Now that you are familiar with the basics, it is time to get to work on the Ender Dragon.