【问题标题】:How to map both ports 80 and 443 from an ELB to the same ECS container?如何将 ELB 的 80 和 443 端口映射到同一个 ECS 容器?
【发布时间】:2016-11-07 11:05:06
【问题描述】:

我正在构建一个 CloudFormation 堆栈。我有

  • ECS 容器中的 Web 应用程序,其中 PortMappings 用于 ContainerPorts 9000 和 9002,映射到 HostPorts 80 和 443,并且
  • 一个应用程序负载平衡器 (AWS::ElasticLoadBalancingV2::LoadBalancer),带有 Listeners 和 TargetGroups,用于端口 80 上的 HTTP 和端口 443 上的 HTTPS

当我定义Service 时,我只能指定一个负载均衡器元素;尽管LoadBalancers 是复数形式,但文档说只允许使用一个负载均衡器,并且指定两个负载均衡器元素不起作用。那么,如何映射两个端口呢?

这是我的 CloudFormation JSON 的服务部分,只有 HTTPS 部分,它可以工作。它可以扩展为将 HTTP 路由到同一个容器吗?如果没有,最好的解决方案是什么?

"Service": {
  "Type": "AWS::ECS::Service",
  "DependsOn": ["AutoScalingGroup", "HTTPSListener"],
  "Properties": {
    "Cluster": { "Ref": "Cluster" },
    "DesiredCount": { "Ref": "InstanceCount" },
    "LoadBalancers": [
      {
        "TargetGroupArn": { "Ref": "HTTPSTargetGroup" },
        "ContainerName": "nginx",
        "ContainerPort": "9002"
      }
    ],
    "Role": { "Ref": "ServiceRole" },
    "TaskDefinition": { "Ref": "TaskDefinition" }
  }
}

CloudFormation 解决方案是理想的,但 API 解决方案也很重要。

我可以为 HTTP 创建第二个 Service,带有单独的负载平衡器和容器实例,但这既不简单也不经济。

【问题讨论】:

  • 您是否仅将端口 80 用于重定向到 HTTPS?
  • 到目前为止,是的,所以在 CloudFormation 或 AWS API 中进行重定向的方法会很有趣。不过,最好将重定向保留在容器中,因为容器在其他上下文中使用。

标签: amazon-web-services amazon-cloudformation elastic-load-balancer amazon-ecs


【解决方案1】:

我会建议以下选项之一:

a) 在同一负载均衡器的两个不同任务定义中注册任务(容器)作为容器启动过程的一部分,而不是使用 ECS 服务的内置功能。

b) 定义另一个 ECS 服务,每个服务都与自己的目标组相连。两个目标组都与同一个 ALB 链接。

【讨论】:

  • 有没有一种不需要第二次实例化容器的方法?
  • 是的,选项 a) 不需要容器的第二次实例化。但是您已经自己回答了这个问题。 :)
  • 仅使用 CloudFormation 的解决方案,自动更新与目标组的主机注册(无需在主机上编写脚本),或者两者都比我的更好。在发布之前,我确实尝试了两种服务的解决方案,但它为每个目标组启动了不同的容器。您能否详细说明如何不这样做?
【解决方案2】:

部分解决方案是在创建堆栈后通过 API 手动向 HTTP 目标组注册实例:

autoscaling = boto3.client('autoscaling')
auto_scaling_groups = autoscaling.describe_auto_scaling_groups(AutoScalingGroupNames=[auto_scaling_group_name])
instances = auto_scaling_groups['AutoScalingGroups'][0]['Instances']

elbv2 = boto3.client('elbv2')
for instance in instances:
    elbv2.register_targets(
        TargetGroupArn=http_target_group_arn,
        Targets=[{'Id': instance['InstanceId'], 'Port': instance}]
    )

这不是一个完全可以接受的答案,因为将来自动缩放组创建的实例不会自动注册到 HTTP 目标组。应该可以装配实例来注册它们自己;我会调查的。

【讨论】:

    猜你喜欢
    • 2017-01-29
    • 2022-07-27
    • 1970-01-01
    • 2022-12-09
    • 2019-10-19
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多