docker swarm模式多个服务相同的端口

bit*_*ter 17 docker docker-swarm devops

假设拓扑上有两个服务

  1. API
  2. Web界面

两者都假设在端口80上运行.

在创建服务时,如果要在群集外部访问它,则需要在docker swarm上公开并将端口从服务映射到节点(外部端口).但是,如果您将端口80映射为让我们说API服务,那么您无法映射Web Interface服务的相同端口,因为它已经映射.

怎么解决这个问题?

据我所知,这个用例不受支持.即使你想拥有一个大群集群,并且因为这种行为也无法实现所有服务和应用程序.

我错过了什么?

任何模式来解决这个问题?

dem*_*iak 6

您可以研究Docker Flow:Proxy,将其用作易于配置的反向代理。

但是,我相信,正如其他评论家所指出的那样,Docker 1.12群模式存在一个基本问题,即多个服务公开同一端口(例如80或8080)。它归结为(我认为)网状路由魔术-这是4级4层,基本上就是TCP / IP-换句话说,就是IP地址+端口。因此,当多个服务在(例如)端口8080上列出时,事情就会变得一团糟。网状路由器会愉快地将到达端口8080的流量传递给任何公开同一端口的服务。

您可以在群体模式下使用覆盖网络将事物彼此隔离,但是当您必须将服务连接到代理(覆盖网络)时就会出现问题-到那时看起来事情变得混乱了(这就是我所在的位置)现在有困难)。

我目前的解决方案是,就面向代理(覆盖)网络而言,需要暴露给唯一使用网络的服务的端口(不必将其发布到集群中!),然后实际使用诸如Docker Flow Proxy之类的东西来处理所需端口上的传入流量。

快速入门让您开始学习(大致基于

    docker network create --driver overlay proxy
    docker network create --driver overlay my-app
    # App1 exposed port 8081
    docker service create --network proxy --network my-app --name app1 myApp1DockerImage
    docker service create --name proxy \
    -p 80:80 \
    -p 443:443 \
    -p 8080:8080 \
    --network proxy \
    -e MODE=swarm \
    vfarcic/docker-flow-proxy
    #App2 exposes port 8080
    docker service create --network proxy --network my-app --name app2 myApp2DockerImage
Run Code Online (Sandbox Code Playgroud)

然后,根据其文档配置反向代理。

注意:我现在看到有新的AUTO配置可用-我还没有尝试过。

如果一切正常,最终结果:

  • 代理侦听端口80、443(以及8080的配置调用,因此请保持公用网络为空!)
  • 代理基于service domainservice path(我对存在问题service path)转发到适当的服务
  • 服务可以通过隔离的覆盖网络进行内部通信。
  • 服务不会将端口不必要地发布到集群

[编辑2016/10/20]

忽略与代理连接的同一覆盖网络上具有相同暴露端口的问题有关的所有上述内容。

我拆除了漏洞安装程序,然后再次开始-现在一切都按预期工作:我可以通过docker flow代理使用不同的域访问端口80上的多个(不同)服务。

还使用提到的自动配置-一切都像魅力一样。


ron*_*kot 5

如果需要同时公开API和Web界面,则有两个选择。使用不同的端口进行服务

http://my-site.com       # Web interface
http://my-site.com:8080  # API
Run Code Online (Sandbox Code Playgroud)

或使用侦听端口80并根据路径转发请求以更正服务的代理:

http://my-site.com      # Web interface
http://my-site.com/api  # API
Run Code Online (Sandbox Code Playgroud)


BMi*_*tch 1

[四年后重新审视这个问题,因为它似乎仍在获得投票,并且自提出问题以来发生了很多变化]

在 Swarm 模式下,或者一般的 Linux 模式下,你不能让多个服务监听同一个端口。但是,您可以在端口上运行某种第 7 层代理,该代理根据应用程序级数据执行到正确容器的路由。最常见的例子是现有的各种 http 反向代理。

特别是在 Swarm 模式下,traefik似乎是最流行的反向代理。然而,还存在其他基于 HAProxy 和 Nginx 的解决方案。

使用反向代理,您的两个容器都不会以集群模式发布端口。相反,您可以使用发布在 80 和 443 等端口上的端口来配置反向代理。然后,它将通过共享 docker 网络将请求传送到您的容器。为此,每个容器需要能够根据 http 协议中的某些内容(例如请求中的主机名、路径、cookie 等)分离要传输给它的流量。


[原答案]

如果需要公开暴露,请使用不同的端口:

docker service create -p 80:80 --name web nginx

进而

docker service create -p 8080:80 --name api myapi

在第二个示例中,公共端口 8080 映射到容器端口 80。当然,如果不需要公开端口,则可以通过容器名称和容器端口看到同一网络上的容器之间的服务。

curl http://api:80

将找到一个名为 api 的容器,并使用同一网络上容器的 DNS 发现连接到端口 80。