使用 Swarm 模式路由网格

Docker Engine Swarm 模式可以轻松发布端口,以便服务进行 它们可用于 Swarm 之外的资源。所有节点都参与 入口路由网格。路由网格使 swarm 中的每个节点能够 接受 Swarm 中运行的任何服务的已发布端口上的连接,甚至 如果节点上没有正在运行的任务。路由网格路由所有 对活动容器的可用节点上已发布端口的传入请求。

要在 swarm 中使用入口网络,您需要满足以下条件 在启用 Swarm 模式之前,Swarm 节点之间会打开端口:

  • 港口7946TCP/UDP 用于容器网络发现。
  • 港口4789容器入口网络的 UDP(可配置)。

在 Swarm 中设置网络时,应特别小心。咨询 教程 以获取概述。

您还必须在 swarm 节点和任何外部 需要访问端口的资源,例如外部负载均衡器。

您还可以绕过给定 服务。

发布服务的端口

使用--publish标志以在创建服务时发布端口。target用于指定容器内的端口,而published用于 指定要在 routing mesh上绑定的端口。如果您去掉publishedport,则每个业务任务都会绑定一个随机的高号端口。你 需要检查任务以确定端口。

$ docker service create \
  --name <SERVICE-NAME> \
  --publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <IMAGE>

注意

此语法的旧形式是冒号分隔的字符串,其中 发布的端口是 first,目标端口是 second,例如-p 8080:80.新语法是首选,因为它更易于阅读和 允许更大的灵活性。

<PUBLISHED-PORT>是 Swarm 提供服务的端口。 如果省略它,则绑定一个随机的高编号端口。 这<CONTAINER-PORT>是容器侦听的端口。此参数 是必需的。

例如,以下命令将 nginx 容器中的端口 80 发布到 群中任何节点的端口 8080:

$ docker service create \
  --name my-web \
  --publish published=8080,target=80 \
  --replicas 2 \
  nginx

当您访问任何节点上的端口 8080 时,Docker 会将您的请求路由到活动的 容器。在 swarm 节点本身上,端口 8080 实际上可能没有绑定, 但是路由网格知道如何路由流量并防止任何端口 冲突发生。

路由网格在已发布的端口上侦听分配给 节点。对于外部可路由的 IP 地址,可从 在主机之外。对于所有其他 IP 地址,只能从 在主机中。

Service ingress image

您可以使用以下命令为现有服务发布端口:

$ docker service update \
  --publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
  <SERVICE>

您可以使用docker service inspect以查看服务的已发布端口。为 实例:

$ docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web

[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8080}]

输出显示<CONTAINER-PORT>(标记为TargetPort) 和<PUBLISHED-PORT>(标记为PublishedPort),其中节点侦听对服务的请求。

发布仅用于 TCP 或仅用于 UDP 的端口

默认情况下,当您发布端口时,它是一个 TCP 端口。您可以 特别是发布 UDP 端口而不是 TCP 端口,或者同时发布 TCP 端口。什么时候 如果省略协议说明符,则同时发布 TCP 和 UDP 端口, 该端口将发布为 TCP 端口。如果您使用较长的语法(推荐), 将protocol键添加到任一tcpudp.

仅限 TCP

长语法:

$ docker service create --name dns-cache \
  --publish published=53,target=53 \
  dns-cache

简短语法:

$ docker service create --name dns-cache \
  -p 53:53 \
  dns-cache

TCP 和 UDP

长语法:

$ docker service create --name dns-cache \
  --publish published=53,target=53 \
  --publish published=53,target=53,protocol=udp \
  dns-cache

简短语法:

$ docker service create --name dns-cache \
  -p 53:53 \
  -p 53:53/udp \
  dns-cache

仅限 UDP

长语法:

$ docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp \
  dns-cache

简短语法:

$ docker service create --name dns-cache \
  -p 53:53/udp \
  dns-cache

绕过路由网格

默认情况下,发布端口的 swarm 服务使用路由网格进行发布。 当您连接到任何 swarm 节点上的已发布端口时(无论它是否正在运行 无论是否给定服务),您都会被重定向到正在运行该 服务,透明。实际上,Docker 充当了 Swarm 服务。

您可以绕过路由网格,这样当您访问 给定的节点,您始终在访问运行在 那个节点。这称为host模式。有几件事需要保留 牢记。

  • 如果您访问的节点未运行服务任务,则服务不会 监听该端口。可能没有任何东西在监听,或者 一个完全不同的应用程序正在侦听。

  • 如果您希望在每个节点上运行多个服务任务(例如,当您 有 5 个节点但运行 10 个副本),则无法指定静态目标端口。 要么允许 Docker 分配一个随机的高编号端口(通过省略published),或者确保只有一个服务实例在 给定节点,通过使用全局服务而不是复制的服务,或者通过使用 使用 placement constraints。

要绕过布线网格,必须使用长--publishservice 和 设置modehost.如果省略mode键或将其设置为ingress这 使用路由网格。以下命令使用host模式并绕过 routing mesh。

$ docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp,mode=host \
  --mode global \
  dns-cache

配置外部负载均衡器

您可以为 swarm 服务配置外部负载均衡器,方法是在 与 routing mesh 组合或根本不使用 routing mesh。

使用布线网格

您可以配置外部负载均衡器以将请求路由到 Swarm 服务。例如,您可以将 HAProxy 配置为 对发布到端口 8080 的 nginx 服务的 balance 请求。

Ingress with external load balancer image

在这种情况下,必须在负载均衡器和 虫群。Swarm 节点可以驻留在可访问 代理服务器,但该服务器不可公开访问。

您可以配置负载均衡器以平衡 即使节点上没有计划任务。例如,您 中可能具有以下 HAProxy 配置/etc/haproxy/haproxy.cfg:

global
        log /dev/log    local0
        log /dev/log    local1 notice
...snip...

# Configure HAProxy to listen on port 80
frontend http_front
   bind *:80
   stats uri /haproxy?stats
   default_backend http_back

# Configure HAProxy to route requests to swarm nodes on port 8080
backend http_back
   balance roundrobin
   server node1 192.168.99.100:8080 check
   server node2 192.168.99.101:8080 check
   server node3 192.168.99.102:8080 check

当您在端口 80 上访问 HAProxy 负载均衡器时,它会将请求转发到 节点。群路由网格将请求路由到活动任务。 如果出于任何原因 swarm 调度器将任务分派到不同的节点,则您的 无需重新配置负载均衡器。

您可以配置任何类型的负载均衡器以将请求路由到群节点。 要了解有关 HAProxy 的更多信息,请参阅 HAProxy 文档

无布线网格

要使用没有路由网格的外部负载均衡器,请将--endpoint-modednsrr而不是默认值vip.在这种情况下,没有 单个虚拟 IP。相反,Docker 会为服务设置 DNS 条目,以便 对服务名称的 DNS 查询将返回 IP 地址列表,客户端 直接连接到其中一个。

您不能使用--endpoint-mode dnsrr--publish mode=ingress. 您必须在服务前面运行自己的负载均衡器。的 DNS 查询 Docker 主机上的服务名称返回 运行服务的节点。配置负载均衡器以使用此列表 并平衡节点之间的流量。 请参阅配置服务发现

了解更多信息