使用 AWS ECS 服务和 Elastic LoadBalancer 向 public 多个端口公开

Exposing to public more than 1 port with AWS ECS service and Elastic LoadBalancer

我有公开多个端口的服务,它在 kubernetes 上运行良好,但现在我们将其移至 AWS ECS。看来我只能通过负载均衡器公开端口,而且每个 service/tasks 只能使用 1 个端口,即使 docker 定义了多个端口,我也必须选择一个端口

Add to load balancer 按钮允许添加一个端口。添加后没有添加第二个端口的按钮。

有没有比让第二个代理服务公开第二个端口更好的解决方法?

更新:我使用基于 fargate 的服务。

更新: 我能够使用 Terraform 配置目标组,但到目前为止没有在 AWS 控制台上找到这个选项。

resource "aws_ecs_service" "multiple_target_example" {
  name            = "multiple_target_example1"
  cluster         = "${aws_ecs_cluster.main.id}"
  task_definition = "${aws_ecs_task_definition.with_lb_changes.arn}"
  desired_count   = 1
  iam_role        = "${aws_iam_role.ecs_service.name}"

  load_balancer {
    target_group_arn = "${aws_lb_target_group.target2.id}"
    container_name   = "ghost"
    container_port   = "3000"
  }

  load_balancer {
    target_group_arn = "${aws_lb_target_group.target2.id}"
    container_name   = "ghost"
    container_port   = "3001"
  }

  depends_on = [
    "aws_iam_role_policy.ecs_service",
  ]
}

Version note: Multiple load_balancer configuration block support was added in Terraform AWS Provider version 2.22.0.

ecs_service_terraform

我不能说这将是一个很好的解决方法,但我正在做一个项目,我需要 运行 使用 AWS ECS 的 Ejabberd,但是当它绑定到负载均衡器服务。

我正在使用 Terraform,由于 AWS ECS 的这一限制,我们同意 运行 每个实例一个容器来解决端口问题,因为我们应该公开两个端口。

如果您不想为您的容器分配一个动态端口,并且您希望 运行 每个实例一个容器 那么该解决方案肯定会起作用。

  1. 创建目标组并指定容器的第二个端口。

  2. 转到您的 ECS 集群的 AutoScalingGroups

  3. 在ECS集群的Autoscaling组中编辑并添加新创建的目标组

因此,如果您扩展到两个容器,这意味着将有两个实例,因此新启动的实例将注册到第二个目标组,自动缩放组会处理它。 这种方法在我的情况下效果很好,但需要考虑的事情很少。

Do not bind the primary port in target, better to bind primary port in ALB service. The main advantage of this approach will be that if your container failed to respond to AWS health check the container will be restart automatically. As the target groupe health check will not recreate your container.

This approach will not work when there is dynamic port expose in Docker container.

AWS 应该更新其 ECS 代理来处理这种情况。

我在为每个实例创建多个容器时遇到过这个问题,但第二个容器没有出现,因为它使用的是任务定义中定义的相同端口。

我们所做的是,在这些容器之上创建了一个应用程序负载均衡器并删除了硬编码端口。当应用程序负载均衡器没有在其下获得预定义端口时,它所做的是,使用动态端口映射的功能。容器将出现在随机端口并驻留在一个目标组中,负载均衡器会自动将请求发送到这些端口。

可以找到更多详细信息here

您不需要任何解决方法,AWS ECS 现在支持同一 ECS 服务中的多个目标组。这将有助于您想要公开容器的多个端口的用例。

目前,如果要创建指定多个目标组的服务,则必须使用 Amazon ECS API、SDK、AWS CLI 或 AWS CloudFormation 模板创建服务。创建服务后,您可以使用 AWS 管理控制台查看服务和注册到该服务的目标组。

For example, A Jenkins container might expose port 8080 for the Jenkins web interface and port 50000 for the API.

参考:

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/register-multiple-targetgroups.html

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