繁体   English   中英

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

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

我有暴露多个端口的服务,它与 kubernetes 配合良好,但现在我们将其移至 AWS ECS。 似乎我只能通过负载均衡器公开端口,即使 docker 定义了多个端口,我也仅限于每个服务/任务 1 个端口,我必须选择一个端口

在此处输入图像描述

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

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

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

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

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

例如,Jenkins 容器可能会为 Jenkins Web 界面公开端口 8080,为 API 公开端口 50000。

参考:

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/

更新:我能够使用 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",
  ]
}

版本说明:Terraform AWS Provider 版本 2.22.0 中添加了多个 load_balancer 配置块支持。

ecs_service_terraform

我不能说这将是一个很好的解决方法,但我正在从事一个项目,我需要使用 AWS ECS 运行 Ejabberd,但是在将服务端口绑定到负载均衡器时发生了同样的问题。

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

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

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

  2. 转到 ECS 集群的 AutoScalingGroups

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

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

不要在target中绑定主端口,最好在ALB服务中绑定主端口。 这种方法的主要优点是,如果您的容器未能响应 AWS 健康检查,容器将自动重新启动。 由于目标组健康检查不会重新创建您的容器。

当 Docker 容器中存在动态端口公开时,这种方法将不起作用。

AWS 应更新其 ECS 代理以处理此类情况。

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

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

可以在此处找到更多详细信息

感谢 mohit 的回答,我使用 AWS CLI 将多个目标组(多个端口)注册到一个 ECS 服务中:

ecs-sample-service.json

{
    "serviceName": "sample-service",
    "taskDefinition": "sample-task",
    "loadBalancers":[
      {  
         "targetGroupArn":"arn:aws:elasticloadbalancing:us-west-2:0000000000:targetgroup/sample-target-group/00000000000000",
         "containerName":"faktory",
         "containerPort":7419
      },
      {  
         "targetGroupArn":"arn:aws:elasticloadbalancing:us-west-2:0000000000:targetgroup/sample-target-group-web/11111111111111",
         "containerName":"faktory",
         "containerPort":7420
      }
   ],
    "desiredCount": 1
}
aws ecs create-service --cluster sample-cluster --service-name sample-service --cli-input-json file://ecs-sample-service.json --network-configuration "awsvpcConfiguration={subnets=[subnet-0000000000000],securityGroups=[sg-00000000000000],assignPublicIp=ENABLED}" --launch-type FARGATE
  1. 如果任务需要 Internet 访问来提取图像,请确保subnet-0000000000000具有 Internet 访问权限。
  2. 安全组sg-00000000000000需要给予相关端口入站访问权限。 (在本例中为 7419 和 7420)。
  3. 如果流量仅来自 ALB,则任务不需要 public IP。 然后assignPublicIp可以是false

通常,我通过创建任务定义、目标组并将它们附加到应用程序负载均衡器来使用 AWS CLI 方法本身。 但问题是,当有多个服务要完成时,这是一项耗时的任务,所以我会使用 terraform 来创建这样的服务

terraform 模块链接这是采用 Fargate 部署的多端口 ECS 服务。 目前,这仅支持 2 个端口。 当使用 sockets 的多端口时,此套接字不会发送任何响应,因此运行状况检查可能会失败。 所以要解决这个问题,我会将目标组中的端口覆盖到其他端口并修复它。

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM