首页 > 解决方案 > Docker Swarm 访问容器到已发布端口上的容器?

问题描述

我已经看到至少 10 个这样的问题,但找不到答案。

我正在从 Rancher 搬到 Docker Swarm。

我使用 docker-compose 来部署堆栈。

我正在使用linux主机。

➜  swarm git:(master) ✗ docker --version
Docker version 20.10.9, build c2ea9bc
➜  swarm git:(master) ✗ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

我遇到的问题是我有一个smtp侦听端口的容器(服务) 2525。在来自其他服务的 swarm 中,我需要将此服务引用为smtp:25not 2525。当然,我只是做了一个端口映射。但其他服务无法访问25仅 on端口上的服务2525

请注意,为了进行测试,我正在尝试映射2526->2525以排除任何特权问题。

我的 docker-compose 条目如下所示:

smtp:
    image: <my repository>
    user: node
    environment:
      - NODE_ENV=production
    privileged: true
    ports:
      - published: 2526
        target: 2525
        protocol: tcp
        mode: ingress # I don't need this on the host, just on the swarm vip.
    deploy:
      replicas: 2
      placement:
        constraints:
          - node.labels.scheme == task
      restart_policy:
        condition: on-failure
        delay: 5s # how long to wait between retarts
        window: 20s # How long to determine if startup has succeeded
    healthcheck:
      test: netstat -l | grep 2525
      interval: 10s
      timeout: 10s
      retries: 10
      start_period: 20s

从busybox容器中,我可以成功telnet smtp 2525telnet smtp 2526给了我connection refused. 此外,我也无法从 smtp 容器内部远程登录到 smtp:2526。

Docker 检查服务显示

 "Endpoint": {
            "Spec": {
                "Mode": "vip",
                "Ports": [
                    {
                        "Protocol": "tcp",
                        "TargetPort": 2525,
                        "PublishedPort": 2526,
                        "PublishMode": "ingress"
                    }
                ]
            },
            "Ports": [
                {
                    "Protocol": "tcp",
                    "TargetPort": 2525,
                    "PublishedPort": 2526,
                    "PublishMode": "ingress"
                }
            ],
            "VirtualIPs": [
                {
                    "NetworkID": "wv8fe0yih5ql9ye09chcl6y1b",
                    "Addr": "10.0.0.41/24"
                },
                {
                    "NetworkID": "5a9tjqidsvphi9lphldit62tm",
                    "Addr": "10.0.2.145/24"
                }
            ]
        }

Netstat 透露

~/app $ netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:2525            0.0.0.0:*               LISTEN      13/node             
tcp        0      0 127.0.0.11:42381        0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:783           0.0.0.0:*               LISTEN      -        

有任何想法吗?我不允许这样做吗?

编辑:

我必须让容器在端口 25 上侦听才能使其工作。

标签: dockerdocker-composedocker-swarm

解决方案


首先,在 docker swarm 上,您使用docker stack deploynotdocker compose来部署服务。

Docker swarm 管理与覆盖网络的服务连接:当您部署堆栈 ( docker stack deploy) 时,会隐式创建覆盖网络并将服务附加到它。连接到覆盖网络的所有服务都可以使用 docker 的网状网络 dns 发现相互发现。

因此,实际上,您可以部署您的 smtp 服务,并将堆栈文件修改为如下所示:

version: "3.9"

networks:
  public:
    attachable: true
    driver: overlay
    name: smtp

services:
  smtp:
    image: ...
    command: .... --listen :25
    networks:
      - public
    ports:
      - 2525:25
    healthcheck:
      test: netstat -l | grep 25
    ...

进一步的警告:当服务使用 docker 桥接或覆盖网络相互连接时,没有端口重新映射。“ports”指令仅适用于入口,即从 swarm 外部到达 docker 节点的数据包,这些数据包需要路由到服务。因此,要让服务到服务的流量通过 :25 进行通信,则需要将 smtp 容器配置为在 :25 上进行侦听。

完成后,您可以通过指定目标网络从容器和服务连接到 smtp。

考虑到这一点,并假设可以将 smtp 服务配置为监听 :25,我将服务显式附加到撰写文件中名为“public”的网络。这个网络是用全局名称“smtp”创建的,它被标记为可附加的,因此可以将 ad-hoc 容器附加到它。它明确声明为“覆盖”,因为 docker compose 将部署此 compose 并尝试将其创建为bridge网络。

然后,为了验证这是否有效,可以使用 netshoot 容器。只需将其附加到现在可用的网络并验证 dns 是否解析了该网络上的“smtp”名称,并且端口 25 是可访问的。

docker run --network smtp --rm -it nicolaka/netshoot
$ telnet smtp 25 
...

其他需要使用 smtp 的服务将被附加到 smtp 公共网络:

version: "3.9"

networks:
  smtp:
    external: true

services:
  some-other-service:
    image: ...
    command: .... 
    environment:
      SMTP_URL: smtp://smtp:25
    networks:
    - default
    - smtp

在这里,我明确将此服务附加到隐式默认堆栈网络,以防除了 smtp 网络之外还有其他服务与之通信。


推荐阅读