Docker 群路由网格

Docker Swarm Routing Mesh

假设我在swarm中有2个节点(节点1是manager,node2是worker),使用下面的compose启动

version: "3.9"
services:
  app1:
    image: app1image
    ports:
      - 8080:8080
    deploy:
      mode: global
  app2:
    image: app2image
    ports:
      - 9080:9080
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - "node.role==manager"

我的问题是:

  1. 如果我尝试通过 node1 访问 app1,是否可以将我路由到 node2 中的 app1 容器?
  2. 由于app2仅部署到node1,如果我尝试通过端口9080上的node2访问它,我可以吗?
  3. 除了 docker 文档引用的端口(用于集群管理通信的 TCP 端口 2377 用于节点间通信的 TCP 和 UDP 端口 7946 UDP 端口 4789 用于覆盖网络流量)是否还有其他需要打开的端口?就像 app1 想要调用 app2

因此,要了解实际情况:

version: "3.9"

networks:
  default:
    driver: overlay
  ingress:
    external: true

services:
  app1:
    image: app1image
    ports:
      - 8080:5000
    deploy:
      mode: global
    networks:
      - default

  app2:
    image: app2image
    ports:
      - 9080:5000
    networks:
      - default
    deploy:
      placement:
        constraints:
          - node.role==manager

在此配置中,我的预期是该应用正在侦听 0.0.0.0:5000

因此,docker 所做的是创建两个网络:一个入口网络,用于桥接每个主机上的端口和每个容器:

node1:8080 node2:8080 将被路由和负载均衡到 app1 容器。 和 node1:9080、nod2:9080 将被路由和负载均衡到 app2 容器。

服务容器或任务也已附加到组合堆栈的隐式默认网络。它是一个覆盖 - 或软件定义 - 网络,因此每个容器在该网络上都有一个与其所在节点无关的 ip。我已经决定两个服务的实际侦听端口都是端口 :5000,因此附加到 {stack}_default 的任何服务都可以使用服务名称和实际端口地址:

app1:5000 将通过 vip 路由以负载平衡流量到 app1 的实例,app1.tasks 是一个 dnsrr 记录,它将 return 每个容器 ip。

同样 app2:5000 将路由到管理器节点上的 app2 容器。

app1 和 app2 dns 名称对于作为堆栈的一部分/附加到 {stack_default} 网络的服务是完全私有的,因此 app1:5000 名称在 swarm 外部不可用,甚至其他未明确附加的堆栈或容器。

所以:

  1. 是的。
  2. 是的。
  3. 没有但是:

如果您 ports: 发布端口,这些端口在 docker 外部并且不通过覆盖网络。如果需要节点到节点通信,您将需要添加发布到防火墙的每个端口。例如8080和9080需要开放

然而,由于overlay网络允许连接,在物理link层使用4789,流量goint到app1,overlay上的app2 ips(:5000流量)被隧道化,不需要被打开。