用于创建ECS服务的Cloudformation模板卡在CREATE_IN_PROGRESS中

时间:2015-09-22 21:48:39

标签: amazon-web-services amazon-cloudformation amazon-ecs

我正在使用Cloudformation创建AWS ECS服务。

一切似乎都成功完成,我可以看到实例被附加到负载均衡器,负载均衡器正在声明实例是健康的,如果我点击负载均衡器,我成功地被带到了我的运行容器。

查看ECS控制面板,我可以看到该服务已经稳定,并且一切正常。我还可以看到容器是稳定的,并且没有被终止/重新创建。

然而,Cloudformation模板永远不会完成,它会在CREATE_IN_PROGRESS停留在大约30-60分钟之后,当它回滚时声称服务没有稳定。查看CloudTrail,我可以看到由RegisterInstancesWithLoadBalancer实例化的ecs-service-scheduler个数,都具有相同的参数,即相同的实例ID和负载均衡器。我正在使用ECS的标准IAM角色和权限,因此它不应该是权限问题。

任何人都有类似的问题吗?

8 个答案:

答案 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

对我来说这一切似乎都是明智的,但事实证明这有两个问题,因为它被写入/部署导致它挂起。

  1. DesiredCount设置为2,这意味着它实际上会尝试启动服务并运行它,而不仅仅是定义它。如果我将DesiredCount设置为0,这样就可以了。
  2. 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。