【问题标题】:Using Docker Swarm as a reverse proxy using overlay network routing mesh使用 Docker Swarm 作为反向代理,使用覆盖网络路由网格
【发布时间】:2021-10-12 07:15:35
【问题描述】:

我有一个服务堆栈,我正在部署到我的 Docker 群,它有 1 个管理节点和 1 个工作节点。它的服务被限制为仅放置在这些节点之一(在本例中为管理器)。工作节点仅用作单独的入口点。

管理节点通过docker node update --label-add minecraft=main 设置标签minecraft=main

名为minecraft-net 的群范围覆盖网络由 docker-compose 堆栈单独创建。

管理器上的 docker-compose.yml(在主机模式下,不是 swarm)包含:

...
networks:
    minecraft-net:
        name: minecraft-net
        driver: overlay
        attachable: true
        driver_opts:
            encrypted: "true"

为了访问 Minecraft 服务器,玩家应该能够连接到工作节点主机名,并且路由网格应该将流量重定向到管理器。

为了部署这个堆栈,我使用

docker stack deploy --compose-file minecraft.yml minecraft

minecraft.yml 在哪里

version: '3.7'

services:
    crafty-controller:
        image: crafty-controller  # This image is only available on the manager node
        ports:
          - "25500-25600"
          - "13121:13121"
        volumes:
          - ./minecraft/docker/minecraft_servers:/minecraft_servers
          - ./minecraft/docker/db:/crafty_db
          - /mnt/minecraft-backups:/crafty_web/backups
        networks:
            - minecraft-net
        deploy:
            placement:
                constraints:
                  - node.labels.minecraft == main

networks:
    minecraft-net:
        external: true

我过去曾为某个活动使用过类似的设置,但现在我遇到了问题。即使我能够使用管理器节点的地址直接连接到 Minecraft 服务器,工作程序节点也不会将任何流量重定向到管理器或从管理器返回。这意味着我无法通过工作节点地址连接到 Minecraft 服务器。

root@debvm:/opt/app/my.site# docker stack deploy --compose-file minecraft.yml minecraft
Updating service minecraft_crafty-controller (id: aug42i46efu9bc7wv39jflxdc)
image crafty-controller:latest could not be accessed on a registry to record
its digest. Each node will access crafty-controller:latest independently,
possibly leading to different nodes running different
versions of the image.

root@debvm:/opt/app/my.site# docker stack ls
NAME                SERVICES            ORCHESTRATOR
minecraft           1                   Swarm
root@debvm:/opt/app/my.site# docker node ps
ID                  NAME                            IMAGE                      NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
to2781e7jtjm        minecraft_crafty-controller.1   crafty-controller:latest   debvm               Running             Running about a minute ago
root@debvm:/opt/app/my.site# docker service ls
ID                  NAME                          MODE                REPLICAS            IMAGE                      PORTS
aug42i46efu9        minecraft_crafty-controller   replicated          1/1                 crafty-controller:latest   *:13121->13121/tcp, *:30000-30076->25500-25576/tcp, *:30077->25600/tcp, *:30078-30099->25578-25599/tcp, *:30100->25577/tcp
root@debvm:/opt/app/my.site# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
6tnekpdbkktl8h7puqeba06i8 *   debvm               Ready               Active              Leader              19.03.15
qiedc8wfogv25ezlasmhe52co     workernode          Ready               Active                                  19.03.15

我可以看到工作节点没有crafty-controller 图像来创建自己的服务实例。这是故意的,因为图像很大,无论如何应该只有一个实例。我想知道的是是否可以让工作节点通过入口覆盖网络将流量(请求)转发到管理节点,即使工作节点没有该堆栈所需的图像。

不知何故,我在一年前就能做到这一点,但我忘记了我是如何做到的。

目前,我无法通过工作节点的地址连接到 Minecraft 服务器(但可以使用管理节点的地址连接到它)。是否可以在我的配置中更改某些内容以允许玩家连接到工作节点并将流量重定向到管理节点?

【问题讨论】:

    标签: docker minecraft docker-swarm


    【解决方案1】:

    我在这里看到了对 Swarm 内部网络的误解。

    overlay 网络管理参与 swarm 的 Docker 守护程序之间的通信。

    您要查找的网络是ingress 网络,这是一个特殊的覆盖网络,负责服务节点之间的负载平衡。当任何 swarm 节点在发布的端口上收到请求时,它会将请求交给名为 IPVS 的模块,该模块将选择参与服务的 IP 地址之一并将请求路由到它,通过 @987654324 @网络。

    这个ingress网络应该在你启动Docker Swarm的时候就已经创建好了,你可以通过docker network inspect ingress查看。

    所以基本上,为了能够通过任何节点中的已发布端口访问服务,该服务需要位于ingress 网络中。

    默认情况下,所有发布的端口都将处于入口模式。例如来自以下 Compose:

    version: '3.7'
    
    services:
        crafty-controller:
            image: crafty-controller  # This image is only available on the manager node
            ports:
              - "25500-25600"
              - "13121:13121"
            volumes:
              - ./minecraft/docker/minecraft_servers:/minecraft_servers
              - ./minecraft/docker/db:/crafty_db
              - /mnt/minecraft-backups:/crafty_web/backups
            deploy:
                placement:
                    constraints:
                      - node.labels.minecraft == main
    

    我们将提供以下服务:

    ...
    {
       "Protocol": "tcp",
       "TargetPort": 25598,
       "PublishedPort": 30098,
       "PublishMode": "ingress"
    },
    {
       "Protocol": "tcp",
       "TargetPort": 25599,
       "PublishedPort": 30099,
       "PublishMode": "ingress"
    }
    ...
    

    集群中只能有 一个 ingress 网络,所以如果你想实际调用它minecraft-net,你必须检查已经存在的网络,删除所有现有的容器连接到ingress 网络的服务,删除现有的ingress 网络并创建一个新的overlay 网络,提供--ingress 标志。

    【讨论】:

    • 您好丹尼尔,感谢您的回答!明天我可以继续工作。我尝试将入口网络添加到堆栈,但是当我尝试部署堆栈时发生了这种情况:root@debvm:/opt/app/my.site# docker stack deploy --compose-file minecraft.yml minecraftUpdating service minecraft_crafty-controller (id: aug42i46efu9bc7wv39jflxdc) failed to update service minecraft_crafty-controller: Error response from daemon: rpc error: code = InvalidArgument desc = Service cannot be explicitly attached to the ingress network "ingress"(我会尽快跟进)
    • 你是对的,默认情况下所有端口都配置为ingress模式部署,无需将ingress定义为外部网络。试试我刚刚写给你的那个。另外,请确认您在两个容器之间打开了端口7946 UDP/TCP 和端口4789 UDP,否则入口网络将无法工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 2019-07-22
    • 2016-03-31
    相关资源
    最近更新 更多