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

时间:2016-07-23 03:27:54

标签: docker devops docker-swarm

假设拓扑上有两项服务

  1. API
  2. Web界面
  3. 两者都假设在端口80上运行。

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

    如何解决这个问题?

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

    我错过了什么?

    要解决这个问题的任何模式吗?

3 个答案:

答案 0 :(得分:5)

您可以查看Docker Flow:Proxy以用作易于配置的反向代理。

但我相信,正如其他评论员指出的那样,Docker 1.12群模式存在一个基本问题,即多个服务暴露同一个端口(如80或8080)。 它归结为(我认为)网状路由魔术 - 这是一个4级四件事,基本上意味着TCP / IP - 换句话说,IP地址+端口。 因此,当多个服务列在(例如)端口8080上时,事情变得混乱。网状路由器将很乐意将流向端口8080的流量传递给暴露相同端口的任何服务。

你可以使用群集模式中的覆盖网络将事物彼此隔离,但是当你必须将服务连接到代理(覆盖网络)时会出现问题 - 此时看起来事情变得混乱(这是我现在遇到困难。)

我现在的解决方案是让涉及面向代理(覆盖)网络的需要暴露给网络使用端口的服务是唯一的(它们不必发布到群集中) !),然后实际使用像Docker Flow Proxy这样的东西来处理所需端口上的传入流量。

我开始的快速示例(大致基于this

    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

然后根据它documentation配置reverseProxy。

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

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

  • 代理侦听端口80,443(以及它的配置呼叫8080,所以请关闭公共网络!)
  • 代理根据service domainservice path转发到相应的服务(我遇到了service path的问题)
  • 服务可以通过隔离的覆盖网络在内部进行通信。
  • 服务不会不必要地向swarm发布端口

[编辑2016/10/20]

忽略上面关于连接到代理的同一个覆盖网络上相同暴露端口问题的所有内容。

我撕毁了我的洞设置,并重新开始 - 现在一切正常:我可以通过docker flow proxy在端口80上使用不同的域访问多个(不同的)服务。

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

答案 1 :(得分:4)

如果您需要向公众公开API和Web界面,您有两种选择。为服务使用不同的端口

http://my-site.com       # Web interface
http://my-site.com:8080  # API

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

http://my-site.com      # Web interface
http://my-site.com/api  # API

答案 2 :(得分:3)

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

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。

相关问题