Skip to content

Commit

Permalink
Add Service Discovery option for non-Swarm Docker (#316)
Browse files Browse the repository at this point in the history
  • Loading branch information
devmattrick authored Aug 4, 2024
1 parent 8b3180d commit 5d7063f
Show file tree
Hide file tree
Showing 6 changed files with 513 additions and 180 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.20 as builder
FROM golang:1.22 AS builder

WORKDIR /build

Expand Down
61 changes: 33 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ Routes Minecraft client connections to backend servers based upon the requested
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 in-swarm Docker config (env 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
Expand Down Expand Up @@ -114,6 +118,33 @@ To test out this example, add these two entries to my "hosts" file:
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](docs/sd-docker.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](docs/swarm.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.
Expand Down Expand Up @@ -213,32 +244,6 @@ rules:
verbs: ["watch","list","get","update"]
```

## Docker Swarm Usage

### Using Docker Swarm Service auto-discovery

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

- `mc-router.host`: Used to configure the hostname the Minecraft clients would use to
connect to the server. The 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 deafult 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 service. You can either use the network ID, it's full name or an alias.

### Example Docker Swarm deployment

Refer to [this example docker-compose.yml](docs/swarm.docker-compose.yml) to see how to
configure two different Minecraft servers and a `mc-router` instance. Notice how you don't
have to expose the Minecraft instances ports, but all the containers are required to be in
the same network.

## REST API

* `GET /routes` (with `Accept: application/json`)
Expand Down Expand Up @@ -365,4 +370,4 @@ docker run -it --rm \

## Related Projects

* https://github.com/haveachin/infrared
* https://github.com/haveachin/infrared
21 changes: 16 additions & 5 deletions cmd/mc-router/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ type Config struct {
InKubeCluster bool `usage:"Use in-cluster Kubernetes config"`
KubeConfig string `usage:"The path to a Kubernetes configuration file"`
AutoScaleUp bool `usage:"Increase Kubernetes StatefulSet Replicas (only) from 0 to 1 on respective backend servers when accessed"`
InDockerSwarm bool `usage:"Use in-swarm Docker config"`
DockerTimeout int `default:"0" usage:"Timeout configuration in seconds for the Docker Swarm integration"`
DockerRefreshInterval int `default:"15" usage:"Refresh interval in seconds for the Docker Swarm integration"`
InDocker bool `usage:"Use Docker service discovery"`
InDockerSwarm bool `usage:"Use Docker Swarm service discovery"`
DockerSocket string `default:"unix:///var/run/docker.sock" usage:"Path to Docker socket to use"`
DockerTimeout int `default:"0" usage:"Timeout configuration in seconds for the Docker integrations"`
DockerRefreshInterval int `default:"15" usage:"Refresh interval in seconds for the Docker integrations"`
MetricsBackend string `default:"discard" usage:"Backend to use for metrics exposure/publishing: discard,expvar,influxdb"`
UseProxyProtocol bool `default:"false" usage:"Send PROXY protocol to backend servers"`
ReceiveProxyProtocol bool `default:"false" usage:"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"`
Expand Down Expand Up @@ -161,12 +163,21 @@ func main() {
}
}

if config.InDocker {
err = server.DockerWatcher.Start(config.DockerSocket, config.DockerTimeout, config.DockerRefreshInterval)
if err != nil {
logrus.WithError(err).Fatal("Unable to start docker integration")
} else {
defer server.DockerWatcher.Stop()
}
}

if config.InDockerSwarm {
err = server.DockerWatcher.StartInSwarm(config.DockerTimeout, config.DockerRefreshInterval)
err = server.DockerSwarmWatcher.Start(config.DockerSocket, config.DockerTimeout, config.DockerRefreshInterval)
if err != nil {
logrus.WithError(err).Fatal("Unable to start docker swarm integration")
} else {
defer server.DockerWatcher.Stop()
defer server.DockerSwarmWatcher.Stop()
}
}

Expand Down
34 changes: 34 additions & 0 deletions docs/sd-docker.docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
services:
mcfoo:
image: itzg/minecraft-server
environment:
EULA: "TRUE"
MOTD: "foo"
volumes:
- mcfoodata:/data
labels:
mc-router.host: "foo.localhost"
mc-router.default: true
mcbar:
image: itzg/minecraft-server
environment:
EULA: "TRUE"
MOTD: "bar"
volumes:
- mcbardata:/data
labels:
mc-router.host: "bar.localhost"
router:
image: itzg/mc-router:latest
command: "-debug -in-docker"
depends_on:
- mcfoo
- mcbar
ports:
- "25565:25565"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
mcfoodata:
mcbardata:
Loading

0 comments on commit 5d7063f

Please sign in to comment.