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

ECS service with two Load Balancers for same port: internal and internet-facing

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

我想做的:添加另一个 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 服务之外,是否有解决此问题的方法?

谢谢。

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

It is not possible to for an Elastic Load Balancer to have both a public IP address and a private IP address. It is one or the other, but not both.

If you want your ELB to have a private IP address, then it cannot listen to requests from the internet.

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

因此,在寻找解决方法时,我发现了以下可能在某些情况下有效的解决方案(请参阅 'prerequisites'):

先决条件

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

解决方案

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

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

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

You can configure service discovery for an ECS service that is behind a load balancer, but service discovery traffic is always routed to the task and not the load balancer. [3]

如果要设置此场景,请注意以下事项:

Service discovery can only be configured when first creating a service. Updating existing services to configure service discovery for the first time or change the current configuration is not supported. [3]

参考资料

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

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

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

Amazon ECS services now support multiple load balancer target groups

You can now attach multiple target groups to your Amazon ECS services that are running on either Amazon EC2 or AWS Fargate. Target groups are used to route requests to one or more registered targets when using a load balancer. Attaching multiple target groups to your service allows you to simplify infrastructure code, reduce costs and increase manageability of your ECS services.

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

Example: Having separate load balancers for internal and external traffic.

In the following use case, a service uses two separate load balancers, one for internal traffic and a second for internet-facing traffic, for the same container and port.

"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 容器服务 public 路线图中的 github 相关(现已关闭)github 问题可在此处找到:

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

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

Now, you can attach multiple target groups per ECS service. This allows you to maintain a single ECS service that can serve traffic from both internal and external load balancers and support multiple path-based routing rules and applications that need to expose more than one port.