具有两个负载均衡器的 ECS 服务用于同一端口:内部和面向 Internet

Posted

技术标签:

【中文标题】具有两个负载均衡器的 ECS 服务用于同一端口:内部和面向 Internet【英文标题】:ECS service with two Load Balancers for same port: internal and internet-facing 【发布时间】:2019-11-28 05:22:18 【问题描述】:

我在尝试对 ECS 集群应用修改时遇到问题。环境的特殊性:

集群有 2 个服务:蓝色和绿色。 目前这两个服务都关联到一个应用程序负载均衡器 暴露在互联网上。

我想要做的:添加另一个 ALB,在本例中为内部 ALB,以接收来自 VPC 中的私有子网对相同服务(相同容器、相同端口)的请求。尝试应用这些修改时,出现以下错误:

CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename [ClusterName|ServiceName] and update the stack again.

我正在使用 yml 文件描述这些新实体。值得一提的是,新的负载均衡器、其侦听器和目标组已成功创建(即使目标组未检测到 EC2 实例)。将LB添加到ECS服务时出现问题。这是正常的吗?相同端口和相同容器名称的相同 ECS 服务是否可以有 2 个 LB?是否有解决方法可以在不重命名集群的情况下执行此操作?

编辑:我尝试创建一个新的 ECS 服务并关联 2 个负载均衡器,但出现以下错误(更具体):

load balancers can have at most 1 items

所以不,ECS 服务不能与多个 ALB 关联。剩下的问题是:除了创建新的 ECS 服务供私有子网使用之外,还有其他解决方法吗?

谢谢。

【问题讨论】:

【参考方案1】:

2019 年 7 月 30 日,Amazon ECS 发布了对在 ECS 服务中使用多个负载均衡器/目标组的支持。来自他们的What's New blog post:

Amazon ECS 服务现在支持多个负载均衡器目标组

您现在可以将多个目标组附加到您的 Amazon ECS 服务 在 Amazon EC2 或 AWS Fargate 上运行。目标群体 用于将请求路由到一个或多个注册目标时 使用负载均衡器。将多个目标组附加到您的 服务允许您简化基础架构代码、降低成本和 提高 ECS 服务的可管理性。

如文档中所述,这可以实现不同的设置,包括与您在问题中提到的内部和外部负载平衡器的集成。来自docs(强调我的):

示例:内部外部分别设置负载平衡器 交通。

在以下用例中,服务使用两个单独的负载 平衡器,一个用于内部流量,另一个用于面向互联网的流量 流量,相同的容器和端口。

"loadBalancers":[
   //Internal ELB
     
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
      "containerName":"nginx",
      "containerPort":8080
   ,
   //Internet-facing ELB
     
      "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
      "containerName":"nginx",
      "containerPort":8080
   
]

AWS 容器服务公共路线图中的相关(现已关闭)github 问题可在此处找到:

https://github.com/aws/containers-roadmap/issues/12 https://github.com/aws/containers-roadmap/issues/104

【讨论】:

【参考方案2】:

正如您正确观察到的,ECS 的每个服务限制为 1 个负载均衡器。 [1] 另一个 SO 线程声明如下:[2]

弹性负载均衡器不可能同时具有公共 IP 地址和私有 IP 地址。它是其中之一,但不是两者兼而有之。

如果你想让你的 ELB 有一个私有 IP 地址,那么它就不能监听来自互联网的请求。

这意味着,您可以为私有子网中的实例使用单个公共负载均衡器,前提是它们经过 NAT 并因此可以访问互联网。但是,情况可能并非如此,您可以使用两个负载均衡器 - 每个负载均衡器都由各自的 ECS 服务提供支持。我知道这不是你想要的……

因此,在寻找解决方法时,我发现以下解决方案可能在某些情况下有效(请参阅“先决条件”):

先决条件

    您不需要对来自公共子网的内部流量进行负载平衡,而是可以直接访问任务(实际上负载平衡由 Route53 提供)。 您正在使用 FARGATE 启动类型。 您使用 awsvpc、网桥或主机网络模式。 您没有使用 Classic Load Balancer。

解决方案

为 ECS 使用服务发现。 [3] 它是 AWS Cloud Map 与 AWS ECS 的集成。

您可以像以前一样将公共负载均衡器附加到 ECS 服务。 此外,您还为服务设置了服务发现命名空间。 ECS 将任务的私有 IP 写入 DNS 命名空间。然后,您的私有子网中的实例可以查询 DNS 命名空间。

我认为这个解决方案应该有效,因为文档明确指出:

您可以为负载均衡器后面的 ECS 服务配置服务发现,但服务发现流量始终路由到任务而不是负载均衡器。 [3]

如果您想设置此场景,请注意以下几点:

服务发现只能在首次创建服务时配置。不支持首次更新现有服务以配置服务发现或更改当前配置。 [3]

参考文献

[1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_limits.html(“每个服务的负载均衡器数量”) [2]https://***.com/a/36586238/10473469 [3]https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-discovery.html

【讨论】:

谢谢你的详细回答,马丁。最后,我们只是复制了该服务,这就是 AWS 支持人员针对这种情况向我们推荐的服务,尽管它并不理想,但它也不是那么脏 我刚刚看到 AWS 向 ECS 及其 ELB 集成添加了新功能,正如 Lasse 在接受的答案中正确指出的那样。这使我的答案完全过时了。只需在此处添加此注释以避免读者混淆【参考方案3】:

虽然我迟到了,但是 7 月推出的功能可以为正在寻找它的人解决这个问题。

参考:https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecs-services-now-support-multiple-load-balancer-target-groups/

现在,您可以为每个 ECS 服务附加多个目标组。这 允许您维护可以服务流量的单个 ECS 服务 来自内部和外部负载平衡器,并支持多个 基于路径的路由规则和需要暴露更多的应用 不止一个端口。

【讨论】:

【参考方案4】:

我们最终决定提供 2 种服务:一种供内部使用,另一种供公共使用,每一种都有自己的负载均衡器(分别是内部的和面向互联网的)。 AWS 的支持人员后来批准了这个解决方案,他们说这是针对这种情况的推荐解决方法。

【讨论】:

以上是关于具有两个负载均衡器的 ECS 服务用于同一端口:内部和面向 Internet的主要内容,如果未能解决你的问题,请参考以下文章

ECS 和应用负载均衡器

AWS ECS Fargate 不带负载均衡器用于内部服务

用于微服务的私有子网 ecs 连接上负载均衡器的 AWS API 网关

云服务器 ECS 实战一文掌握负载均衡服务原理及配置方法

AWS 服务无法担任角色

如何将 Application Load Balancer 用于具有多个端口映射的 ECS 服务?