我正在构建一个CloudFormation堆栈。我有
PortMappings
为ContainerPort
的9000和9002,映射到HostPort
的80和443,AWS::ElasticLoadBalancingV2::LoadBalancer
),端口80上的HTTP为Listener
和TargetGroup
,端口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
,使用单独的负载均衡器和容器实例,但这既不简单也不经济。
答案 0 :(得分:1)
我会建议其中一个选项:
a)将任务(容器)注册到同一负载均衡器的两个不同任务定义,作为容器引导过程的一部分,而不是使用ECS服务的内置功能。</ p>
b)定义另一个ECS服务,每个服务都与它自己的目标组相关联。两个目标组都与相同的ALB链接。
答案 1 :(得分:0)
部分解决方案是在创建堆栈后通过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目标组。应该可以对实例进行装配以进行自我注册;我会调查一下。