在Docker-Swarm模式下如何进行负载均衡

36

我正在进行一个项目,使用docker-swarm建立云架构。我知道使用swarm可以部署服务的副本,这意味着多个容器将运行该镜像以提供请求。

我还了解到docker有一个内部负载均衡器来管理此请求分配。

然而,我需要帮助理解以下内容:

假设我有一个容器,将服务公开为REST API或Web应用程序。如果在swarm中部署了多个容器(副本),并且我有其他容器(运行某些应用程序)与此HTTP/REST服务通信。

那么,在编写这些应用程序时,我使用哪个 IP:端口组合?是运行这些服务的任何工作节点IP吗?这样做是否会适当地分发负载,即使在运行相同服务的其他工作节点/管理节点之间也是如此?

还是应该调用管理节点,由其负责适当路由(即使管理节点没有运行此特定服务的容器)?

谢谢。

2个回答

39
当我编写这些应用程序时,我应该使用哪个IP:PORT组合?是运行这些服务的任何工作节点IP吗?
您可以使用参与swarm的任何节点,即使在该节点上不存在所讨论的服务的副本。因此,您将使用Node:HostPort组合。入站路由网格将把请求路由到活动容器。 一图胜千言

enter image description here

这样做是否能够适当地分配负载,即使是其他运行相同服务的工作人员/管理员?

默认情况下,入口控制器将进行轮询。

现在,客户端应该使用 DNS 轮询来访问 Docker Swarm 节点上的服务。经典的 DNS 缓存问题会发生。为了避免这种情况,我们可以使用外部负载均衡器,如 HAproxy。

enter image description here


2
你确定它总是进行循环调度吗?你能否链接到这个事实吗?这让我感到很奇怪的设计选择。可能会产生很多不必要的网络流量,例如如果一个容器需要另一个容器的服务,并且在同一主机上有一个副本-那么应该优先考虑该副本,以避免不必要的网络流量。 - Assaf Lavie
1
容器与容器之间的流量使用DNS。Swarm内部DNS将以轮询顺序返回与服务名称匹配的所有活动容器记录。Kubernetes通过Pod概念处理此问题。 - Farhad Farahi
@Shabirmean 当C、D、E尝试访问容器A时,它们将从DNS查询服务A,并且DNS基于它们加入的网络。在这种情况下,返回的IP将在覆盖层1中。 - Farhad Farahi
@FarhadFarahi:再次感谢。所以当 C 想要访问 A 时,它将查询其内部 DNS,该 DNS 将返回同一覆盖中类型为 A 的所有容器。假设 DNS 查询返回 IP_A1IP_A2(两者都在与 C 相同的覆盖中),那么现在谁来进行负载均衡呢?因为我认为 ingress mess 是在节点级别而不是容器级别工作的。 - Shabirmean
1
@NeilS,这不是关于Ingress的问题,而是关于DNS轮询的问题!因为客户端可能会连接到失败的Docker主机,他们必须重试另一个DNS条目,但是使用通过VRRP(keepalived)实现高可用性的HAproxy,如果主机失败,就没有延迟。 - Farhad Farahi
显示剩余12条评论

4

现有答案的重要补充信息

在 Docker Swarm 前面使用代理(HAProxy) 的优点是,Swarm 节点可以驻留在私有网络中,这个网络对代理服务器是可访问的,但是对外不可访问。这将使您的集群更加安全。

如果您正在使用 AWS VPC,您可以创建一个私有子网,并将 Swarm 节点放在其中,然后将代理服务器放在公共子网中,它可以将流量转发到 Swarm 节点。

当您访问 HAProxy 负载均衡器时,它会将请求转发到 Swarm 中的节点。Swarm 路由网格会将请求路由到一个活动任务。如果由于任何原因 Swarm 调度程序将任务分配给不同的节点,则无需重新配置负载均衡器。

要了解更多详细信息,请阅读https://docs.docker.com/engine/swarm/ingress/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接