使用 Swarm 模式路由网格

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

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

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

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

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

您还可以绕过给定 服务。

发布服务的端口

在创建服务时使用该标志发布端口。 用于指定容器内部的端口,并用于 指定要在 routing mesh上绑定的端口。如果关闭该端口,则为每个服务任务绑定一个随机的高编号端口。你 需要检查任务以确定端口。--publishtargetpublishedpublished

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

注意

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

这是 swarm 使服务可用的端口。 如果省略它,则绑定一个随机的高编号端口。 这是容器侦听的端口。此参数 是必需的。<PUBLISHED-PORT><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}]

输出显示来自容器的 (labeled ) 和节点侦听服务请求的 (labeled )。<CONTAINER-PORT>TargetPort<PUBLISHED-PORT>PublishedPort

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

默认情况下,当您发布端口时,它是一个 TCP 端口。您可以 特别是发布 UDP 端口而不是 TCP 端口,或者同时发布 TCP 端口。什么时候 如果省略协议说明符,则同时发布 TCP 和 UDP 端口, 该端口将发布为 TCP 端口。如果您使用较长的语法(推荐), 将注册表项设置为 或 。protocoltcpudp

仅限 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 分配一个随机的高编号端口(通过省略 ),要么确保只有一个服务实例在 给定节点,通过使用全局服务而不是复制的服务,或者通过使用 使用 placement constraints。published

要绕过路由网格,必须使用 long service 和 设置为 。如果省略该键或将其设置为 ,则 使用路由网格。以下命令使用 mode 并绕过路由网格创建全局服务。--publishmodehostmodeingresshost

$ 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 文档

无布线网格

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

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

了解更多信息