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"
我的问题是:
- 如果我尝试通过 node1 访问 app1,是否可以将我路由到 node2 中的 app1 容器?
- 由于app2仅部署到node1,如果我尝试通过端口9080上的node2访问它,我可以吗?
- 除了 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 外部不可用,甚至其他未明确附加的堆栈或容器。
所以:
- 是的。
- 是的。
- 没有但是:
如果您 ports:
发布端口,这些端口在 docker 外部并且不通过覆盖网络。如果需要节点到节点通信,您将需要添加发布到防火墙的每个端口。例如8080和9080需要开放
然而,由于overlay网络允许连接,在物理link层使用4789,流量goint到app1,overlay上的app2 ips(:5000流量)被隧道化,不需要被打开。
假设我在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"
我的问题是:
- 如果我尝试通过 node1 访问 app1,是否可以将我路由到 node2 中的 app1 容器?
- 由于app2仅部署到node1,如果我尝试通过端口9080上的node2访问它,我可以吗?
- 除了 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 外部不可用,甚至其他未明确附加的堆栈或容器。
所以:
- 是的。
- 是的。
- 没有但是:
如果您 ports:
发布端口,这些端口在 docker 外部并且不通过覆盖网络。如果需要节点到节点通信,您将需要添加发布到防火墙的每个端口。例如8080和9080需要开放
然而,由于overlay网络允许连接,在物理link层使用4789,流量goint到app1,overlay上的app2 ips(:5000流量)被隧道化,不需要被打开。