我正在使用Cloudformation创建AWS ECS服务。
一切似乎都成功完成,我可以看到实例被附加到负载均衡器,负载均衡器正在声明实例是健康的,如果我点击负载均衡器,我成功地被带到了我的运行容器。
查看ECS控制面板,我可以看到该服务已经稳定,并且一切正常。我还可以看到容器是稳定的,并且没有被终止/重新创建。
然而,Cloudformation模板永远不会完成,它会在CREATE_IN_PROGRESS
停留在大约30-60分钟之后,当它回滚时声称服务没有稳定。查看CloudTrail,我可以看到由RegisterInstancesWithLoadBalancer
实例化的ecs-service-scheduler
个数,都具有相同的参数,即相同的实例ID和负载均衡器。我正在使用ECS的标准IAM角色和权限,因此它不应该是权限问题。
任何人都有类似的问题吗?
答案 0 :(得分:16)
您的AWS::ECS::Service
需要为TaskDefinition
注册完整的ARN(来源:See the answer from ChrisB@AWS on the AWS forums)。关键是要将TaskDefinition
设置为完整ARN,包括修订。如果您跳过修订版(以下示例中为:123
),则会使用最新修订版,但CloudFormation仍然会在“CREATE_IN_PROGRESS”中与午餐一起休息大约一小时,然后才会失败。这是一种方法:
"MyService": {
"Type": "AWS::ECS::Service",
"Properties": {
"Cluster": { "Ref": "ECSClusterArn" },
"DesiredCount": 1,
"LoadBalancers": [
{
"ContainerName": "myContainer",
"ContainerPort": "80",
"LoadBalancerName": "MyELBName"
}
],
"Role": { "Ref": "EcsElbServiceRoleArn" },
"TaskDefinition": {
"Fn::Join": ["", ["arn:aws:ecs:", { "Ref": "AWS::Region" },
":", { "Ref": "AWS::AccountId" },
":task-definition/my-task-definition-name:123"]]}
}
}
}
这是通过aws cli和jq获取MyTaskDefinition
的最新修订版的一种非常好的方式:
aws ecs list-task-definitions --family-prefix MyTaskDefinition | jq --raw-output .taskDefinitionArns[0][-1:]
答案 1 :(得分:7)
无需为TaskDefinition注册完整的ARN,因为当此资源的逻辑ID提供给Ref内部函数时,Ref将返回Amazon资源名称(ARN)。
在以下示例中,Ref函数返回MyTaskDefinition任务的ARN,例如arn:aws:ecs:us-west-2:123456789012:task / 1abf0f6d-a411-4033-b8eb-a4eed3ad252a。
{"参考":" MyTaskDefinition" }
来源http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html
答案 2 :(得分:6)
我想我有类似的问题。 试着看看#34; DesiredCount"服务模板中的属性。我认为CloudFormation将指示创建/更新仍在进行中,直到服务达到" DesiredCount"在您的群集中。
答案 3 :(得分:5)
我发现了另一个会引起这种情况的相关场景,并且我认为我会把它放在这里以防万一其他人遇到它。如果您使用其TaskDefinition
中实际不存在的图片定义ContainerDefinition
,然后您尝试将该TaskDefinition
作为服务运行,则会遇到相同的问题(或者至少看起来像是同一个问题的东西)。
注意:以下示例YAML块都在同一个CloudFormation模板中
举个例子,我创建了这个Repository
:
MyRepository:
Type: AWS::ECR::Repository
然后我创建了这个Cluster
:
MyCluster:
Type: AWS::ECS::Cluster
这TaskDefinition
(删节):
MyECSTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
# ...
ContainerDefinitions:
# ...
Image: !Join ["", [!Ref "AWS::AccountId", ".dkr.ecr.", !Ref "AWS::Region", ".amazonaws.com/", !Ref MyRepository, ":1"]]
# ...
通过这些定义,我开始创建一个Service
,如下所示:
MyECSServiceDefinition:
Type: AWS::ECS::Service
Properties:
Cluster: !Ref MyCluster
DesiredCount: 2
PlacementStrategies:
- Type: spread
Field: attribute:ecs.availability-zone
TaskDefinition: !Ref MyECSTaskDefinition
对我来说这一切似乎都是明智的,但事实证明这有两个问题,因为它被写入/部署导致它挂起。
DesiredCount
设置为2,这意味着它实际上会尝试启动服务并运行它,而不仅仅是定义它。如果我将DesiredCount
设置为0,这样就可以了。Image
中定义的MyECSTaskDefinition
尚不存在。我将存储库作为此模板的一部分,但我实际上没有向它推送任何内容。因此,当MyECSServiceDefinition
尝试启动2个实例的DesiredCount
时,它会挂起,因为图像实际上在存储库中不可用(因为存储库实际上只是在同一模板中创建的)。 / LI>
醇>
因此,目前,解决方案是为DesiredCount
创建Service
为0的CloudFormation堆栈,将相应的Image
上传到存储库,然后更新CloudFormation堆栈扩大服务范围。或者,可以使用单独的模板来设置核心基础结构,例如存储库,将构建上载到该基础结构,然后运行单独的模板来自行设置Services
。
希望能帮助任何人解决这个问题!
答案 4 :(得分:2)
阻止ECS服务定义到达所需计数的任何内容。一个示例是缺少附加到实例使用的角色的策略中的权限。检查实例ECS代理日志(/var/log/ecs/ecs-agent.log.timestamp)。
另一个例子: 实例没有足够的内存可用于匹配所请求的所需计数 ....事件将显示如下内容:
" ...服务myService无法放置任务,因为没有容器实例满足其所有要求。最接近的匹配容器实例123456789没有足够的可用内存......"
答案 5 :(得分:0)
我有同样的问题。我通过增加分配给任务定义的内存大小来解决。
您正在运行的容器不得超过ECS实例上的可用内存。
答案 6 :(得分:0)
为增加另一种可能性,我一次碰到了这个问题,模板一切正常,所需任务数=正在运行的任务数,等等。事实证明,一个基础EC2实例卡在100%CPU附近状态(但EC2认为它“健康”)。这阻止了CloudFormation验证该特定实例。我杀死了坏的EC2实例,然后ECS产生了一个真正健康的实例。
答案 7 :(得分:0)
要添加另一个数据点,我已经看到AWS::ECS::Service
被永久卡在CREATE_IN_PROGRESS
中,如果ECR泊坞映像不是同时存在的a)可从ECR存储库和获得b)通过健康检查。
我已经尝试过多次使用有效的图像哈希值但运行状况检查容器启动AWS::ECS::Service
,然后修复该图像并进行各种“将所需计数设置为零”的操作, “放回原处”等等,而AFAICT不会让它解开。
我最终不得不删除堆栈,并重新开始通过 通过健康检查的图像。然后就可以了。
超级flakey。