mc-router

mc-router

Minecraft服务器智能路由工具 优化多服务器管理

mc-router是一款专为Minecraft服务器设计的智能路由工具。它可根据客户端请求的服务器地址,将连接自动分发到相应的后端服务器。支持Docker和Kubernetes环境,具有服务自动发现功能。通过简单配置即可实现多服务器管理,适用于各种规模的Minecraft服务器部署。mc-router简化了服务器管理流程,提高了资源利用效率,为玩家提供更流畅的游戏体验。

mc-routerMinecraftDockerKubernetes流量路由Github开源项目

GitHub issues Docker Pulls test GitHub release Discord Buy me a coffee

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

Usage

-api-binding host:port The host:port bound for servicing API requests (env API_BINDING) -auto-scale-up Increase Kubernetes StatefulSet Replicas (only) from 0 to 1 on respective backend servers when accessed (env AUTO_SCALE_UP) -connection-rate-limit int Max number of connections to allow per second (env CONNECTION_RATE_LIMIT) (default 1) -cpu-profile string Enables CPU profiling and writes to given path (env CPU_PROFILE) -debug Enable debug logs (env DEBUG) -default string host:port of a default Minecraft server to use when mapping not found (env DEFAULT) -docker-socket Path to Docker socket to use (env DOCKER_SOCKET) (default "unix:///var/run/docker.sock") -docker-refresh-interval int Refresh interval in seconds for the Docker Swarm integration (env DOCKER_REFRESH_INTERVAL) (default 15) -docker-timeout int Timeout configuration in seconds for the Docker Swarm integration (env DOCKER_TIMEOUT) -in-docker Use Docker service discovery (env IN_DOCKER) -in-docker-swarm Use Docker Swarm service discovery (env IN_DOCKER_SWARM) -in-kube-cluster Use in-cluster Kubernetes config (env IN_KUBE_CLUSTER) -kube-config string The path to a Kubernetes configuration file (env KUBE_CONFIG) -mapping value Comma-separated or repeated mappings of externalHostname=host:port (env MAPPING) -metrics-backend string Backend to use for metrics exposure/publishing: discard,expvar,influxdb (env METRICS_BACKEND) (default "discard") -metrics-backend-config-influxdb-addr string (env METRICS_BACKEND_CONFIG_INFLUXDB_ADDR) -metrics-backend-config-influxdb-database string (env METRICS_BACKEND_CONFIG_INFLUXDB_DATABASE) -metrics-backend-config-influxdb-interval duration (env METRICS_BACKEND_CONFIG_INFLUXDB_INTERVAL) (default 1m0s) -metrics-backend-config-influxdb-password string (env METRICS_BACKEND_CONFIG_INFLUXDB_PASSWORD) -metrics-backend-config-influxdb-retention-policy string (env METRICS_BACKEND_CONFIG_INFLUXDB_RETENTION_POLICY) -metrics-backend-config-influxdb-tags value any extra tags to be included with all reported metrics (env METRICS_BACKEND_CONFIG_INFLUXDB_TAGS) -metrics-backend-config-influxdb-username string (env METRICS_BACKEND_CONFIG_INFLUXDB_USERNAME) -ngrok-token string If set, an ngrok tunnel will be established. It is HIGHLY recommended to pass as an environment variable. (env NGROK_TOKEN) -port port The port bound to listen for Minecraft client connections (env PORT) (default 25565) -receive-proxy-protocol Receive PROXY protocol from backend servers, by default trusts every proxy header that it receives, combine with -trusted-proxies to specify a list of trusted proxies (env RECEIVE_PROXY_PROTOCOL) -routes-config string Name or full path to routes config file (env ROUTES_CONFIG) -simplify-srv Simplify fully qualified SRV records for mapping (env SIMPLIFY_SRV) -trusted-proxies value Comma delimited list of CIDR notation IP blocks to trust when receiving PROXY protocol (env TRUSTED_PROXIES) -use-proxy-protocol Send PROXY protocol to backend servers (env USE_PROXY_PROTOCOL) -version Output version and exit (env VERSION)

Docker Multi-Architecture Image

The multi-architecture image published at Docker Hub supports amd64, arm64, and arm32v6 (i.e. RaspberryPi).

Docker Compose Usage

The diagram below shows how this 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.

version: "3.8" services: vanilla: image: itzg/minecraft-server environment: EULA: "TRUE" forge: image: itzg/minecraft-server environment: EULA: "TRUE" TYPE: FORGE router: image: ${MC_ROUTER_IMAGE:-itzg/mc-router} depends_on: - forge - vanilla environment: MAPPING: | vanilla.example.com=vanilla:25565 forge.example.com=forge:25565 ports: - "25565:25565"

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, add these two entries to my "hosts" file:

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

Using Docker auto-discovery

When running mc-router in a Docker environment you can pass the --in-docker or --in-docker-swarm command-line argument and it will poll the Docker API periodically to find all the running containers/services for Minecraft instances. To enable discovery you have to set the mc-router.host label on the container. These are the labels scanned:

  • mc-router.host: Used to configure the hostname the Minecraft clients would use to connect to the server. The container/service endpoint will be used as the routed backend. You can use more than one hostname by splitting it with a comma.
  • mc-router.port: This value must be set to the port the Minecraft server is listening on. The default value is 25565.
  • mc-router.default: Set this to a truthy value to make this server the default backend. Please note that mc-router.host is still required to be set.
  • mc-router.network: Specify the network you are using for the router if multiple are present in the container/service. You can either use the network ID, it's full name or an alias.

Example Docker deployment

Refer to this example docker-compose.yml to see how to configure two different Minecraft servers and a mc-router instance for use with Docker service discovery.

Example Docker Swarm deployment

Refer to this example docker-compose.yml to see how to configure two different Minecraft servers and a mc-router instance for use with Docker Swarm service discovery.

Routing Configuration

The routing configuration allows routing via a config file rather than a command. You need to set -routes-config or ROUTES_CONFIG env variable. The following shows a JSON file for routes config, where default-server can also be null or omitted:

{ "default-server": "vanilla:25565", "mappings": { "vanilla.example.com": "vanilla:25565", "forge.example.com": "forge:25565" } }

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. You can use more hostnames by splitting them with comma.
  • 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"

you can use multiple host names:

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

mc-router will pick the service port named either minecraft or mc-router. If neither port names exist, it will use port value 25565.

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(s)
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
Auto Scale Up

The -auto-scale-up flag argument makes the router "wake up" any stopped backend servers, by changing replicas: 0 to replicas: 1.

This requires using kind: StatefulSet instead of kind: Service for the Minecraft backend servers.

It also requires the ClusterRole to permit get + update for statefulsets & statefulsets/scale, e.g. like this (or some equivalent more fine-grained one to only watch/list services+statefulsets, and only get+update scale):

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: services-watcher rules: - apiGroups: [""] resources: ["services"] verbs: ["watch","list"] - apiGroups: ["apps"] resources: ["statefulsets", "statefulsets/scale"] verbs: ["watch","list","get","update"]

Make sure to set StatefulSet.metadata.name and StatefulSet.spec.serviceName to the same value; otherwise, autoscaling will not trigger:

apiVersion: v1 kind: Service metadata: name: mc-forge spec: type: ClusterIP annotations: "mc-router.itzg.me/defaultServer": "true" "mc-router.itzg.me/externalServerName": "external.host.name" --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mc-forge spec: serviceName: mc-forge

REST API

  • GET /routes (with Accept: application/json)

    Retrieves the currently configured routes

  • POST /routes (with Content-Type: application/json)

    Registers a route given a JSON body structured like:

    { "serverAddress": "CLIENT REQUESTED SERVER ADDRESS", "backend": "HOST:PORT" }
  • POST /defaultRoute (with Content-Type: application/json)

    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

ngrok

mc-router has built-in support to run as an ngrok agent. To enable this support, pass an ngrok authtoken to the command-line argument or environment variable, shown above.

Ngrok Quick Start

Create/access an ngrok account and allocate an agent authtoken from the dashboard.

In a new directory, create a file called .env with the allocated token

NGROK_TOKEN=...

In the same directory, create the following compose file:

version: "3.8" services: mc: image: itzg/minecraft-server environment: EULA: true volumes: - mc-data:/data # No port mapping since mc-router connects over compose network router: image: itzg/mc-router environment: DEFAULT: mc:25565 NGROK_TOKEN: ${NGROK_TOKEN} # No port mapping needed since it routes through ngrok tunnel volumes: mc-data: {}

Start the compose project:

docker compose up -d

Grab the mc-router logs using:

docker compose logs router

From those logs, locate the ngrokUrl parameter from the "Listening" info log message, such as tcp://8.tcp.ngrok.io:99999.

In the Minecraft client, the server address will be the part after the "tcp://" prefix, such as 8.tcp.ngrok.io:99999.

Development

Building locally with Docker

docker build -t mc-router .

Build locally without Docker

After installing Go and doing a go mod download to install all required prerequisites, just like the Dockerfile does, you can:

make test # go test -v ./... go build ./cmd/mc-router/

Skaffold

For "in-cluster development" it's convenient to use https://skaffold.dev. Any changes to Go source code will trigger a go build, new container image pushed to registry with a new tag, and refresh in Kubernetes with the image tag used in the deployment transparently updated to the new tag and thus new pod created pulling new images, as configured by skaffold.yaml:

skaffold dev

When using Google Cloud (GCP), first create a Docker Artifact Registry, then add the Artifact Registry Reader Role to the Compute Engine default service account of your GKE clusterService Account (to avoid error like "container mc-router is waiting to start: ...-docker.pkg.dev/... can't be pulled"), then use e.g. gcloud auth configure-docker europe-docker.pkg.dev or equivalent one time (to create a ~/.docker/config.json), and then use e.g. --default-repo=europe-docker.pkg.dev/YOUR-PROJECT/YOUR-ARTIFACT-REGISTRY option for skaffold dev.

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

Related Projects

编辑推荐精选

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

Refly.AI

Refly.AI

最适合小白的AI自动化工作流平台

无需编码,轻松生成可复用、可变现的AI自动化工作流

酷表ChatExcel

酷表ChatExcel

大模型驱动的Excel数据处理工具

基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。

AI工具使用教程AI营销产品酷表ChatExcelAI智能客服
TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

热门AI工具生产力协作转型TraeAI IDE
AIWritePaper论文写作

AIWritePaper论文写作

AI论文写作指导平台

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

数据安全AI助手热门AI工具AI辅助写作AI论文工具论文写作智能生成大纲
博思AIPPT

博思AIPPT

AI一键生成PPT,就用博思AIPPT!

博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。

热门AI工具AI办公办公工具智能排版AI生成PPT博思AIPPT海量精品模板AI创作
潮际好麦

潮际好麦

AI赋能电商视觉革命,一站式智能商拍平台

潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。

iTerms

iTerms

企业专属的AI法律顾问

iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。

SimilarWeb流量提升

SimilarWeb流量提升

稳定高效的流量提升解决方案,助力品牌曝光

稳定高效的流量提升解决方案,助力品牌曝光

Sora2视频免费生成

Sora2视频免费生成

最新版Sora2模型免费使用,一键生成无水印视频

最新版Sora2模型免费使用,一键生成无水印视频

下拉加载更多