Routes Minecraft client connections to backend servers based upon the requested server address
Go to file
2020-01-03 21:19:21 -06:00
.circleci ci: allow for "-\d+" tag suffix 2019-06-07 22:06:15 -05:00
cmd/mc-router Switched to go-flagsfiller to enable env var config 2020-01-03 21:19:21 -06:00
docs docs: added docker-compose example 2019-07-27 11:36:16 -05:00
mcproto Handle legacy server list ping for handshake 2019-07-13 15:40:34 -05:00
server Initial support for tracking connection metrics 2019-07-14 16:34:46 -05:00
.gitignore misc: gitignore the goreleaser dist directory 2019-04-19 20:50:08 -05:00
.goreleaser.yml ci: fix main path in goreleaser config 2019-07-14 17:02:38 -05:00
Dockerfile ci: avoid /tmp creation in Dockerfile 2018-05-26 13:17:21 -05:00
go.mod Switched to go-flagsfiller to enable env var config 2020-01-03 21:19:21 -06:00
go.sum Switched to go-flagsfiller to enable env var config 2020-01-03 21:19:21 -06:00
LICENSE.txt Initial commit 2018-05-07 22:16:01 -05:00
Makefile Switch to go modules 2019-04-15 21:16:26 -05:00
README.md docs: added docker-compose example 2019-07-27 11:36:16 -05:00

GitHub issues Docker Pulls GitHub release CircleCI Buy me a coffee

Routes Minecraft client connections to backend servers based upon the requested server address.

Usage

Flags:
  --help                     Show context-sensitive help (also try --help-long
                             and --help-man).
  --port=25565               The port bound to listen for Minecraft client
                             connections
  --api-binding=API-BINDING  The host:port bound for servicing API requests
  --mapping=MAPPING,MAPPING  Where MAPPING is externalHostname=host:port

REST API

  • GET /routes Retrieves the currently configured routes
  • POST /routes Registers a route given a JSON body structured like:
{
  "serverAddress": "CLIENT REQUESTED SERVER ADDRESS",
  "backend": "HOST:PORT"
}
  • POST /defaultRoute Registers a default route to the given backend. JSON body is structured as:
{
  "backend": "HOST:PORT"
}
  • DELETE /routes/{serverAddress} Deletes an existing route for the given serverAddress

Docker Compose Usage

The following diagram shows how the example docker-compose.yml configures two Minecraft server services named vanilla and forge, which also become the internal network aliases. Notice those services don't need their ports exposed since the internal networking allows for the inter-container access.

The router service is only one of the services that needs to exposed on the external network. The --mapping declares how the hostname users will enter into their Minecraft client will map to the internal services.

To test out this example, I added these two entries to my "hosts" file:

127.0.0.1 vanilla.example.com
127.0.0.1 forge.example.com

Kubernetes Usage

Using kubernetes service auto-discovery

When running mc-router as a kubernetes pod and you pass the --in-kube-cluster command-line argument, then it will automatically watch for any services annotated with

  • mc-router.itzg.me/externalServerName : The value of the annotation will be registered as the external hostname Minecraft clients would used to connect to the routed service. The service's clusterIP and target port are used as the routed backend.
  • mc-router.itzg.me/defaultServer : The service's clusterIP and target port are used as the default if no other externalServiceName annotations applies.

For example, start mc-router's container spec with

image: itzg/mc-router
name: mc-router
args: ["--in-kube-cluster"]

and configure the backend minecraft server's service with the annotation:

apiVersion: v1
kind: Service
metadata:
  name: mc-forge
  annotations:
    "mc-router.itzg.me/externalServerName": "external.host.name"

Example kubernetes deployment

This example deployment

  • Declares an mc-router service that exposes a node port 25565
  • Declares a service account with access to watch and list services
  • Declares --in-kube-cluster in the mc-router container arguments
  • Two "backend" Minecraft servers are declared each with an "mc-router.itzg.me/externalServerName" annotation that declares their external server name
kubectl apply -f https://raw.githubusercontent.com/itzg/mc-router/master/docs/k8s-example-auto.yaml

Notes

  • This deployment assumes two persistent volume claims: mc-stable and mc-snapshot
  • I extended the allowed node port range by adding --service-node-port-range=25000-32767 to /etc/kubernetes/manifests/kube-apiserver.yaml

Development

Building locally with Docker

docker run -it --rm \
  -v gopkg:/go/pkg \
  -v ${PWD}:/build -w /build \
  golang:1.12 \
  go build ./cmd/mc-router

Performing snapshot release with Docker

docker run -it --rm \
  -v ${PWD}:/build -w /build \
  -v /var/run/docker.sock:/var/run/docker.sock \
  goreleaser/goreleaser \
  release --snapshot --rm-dist