Шаблон облачной информации для создания службы ECS, застрявшей в CREATE_IN_PROGRESS

Я создаю сервис AWS ECS с использованием Cloudformation.

Кажется, что все успешно завершено, я вижу, что экземпляр привязан к балансировщику нагрузки, балансировщик нагрузки объявляет экземпляр как здоровый, и, если я нахожусь в балансировщике нагрузки, я успешно попадаю в мой рабочий контейнер,

Посмотрев на панель управления ECS, я вижу, что служба стабилизировалась и все выглядит нормально. Я также вижу, что контейнер стабилен и не завершается/не создается.

Однако шаблон Cloudformation никогда не завершается, он застрял в CREATE_IN_PROGRESS примерно через 30-60 минут, когда он откатывается назад, утверждая, что служба не стабилизировалась. Глядя на CloudTrail, я могу увидеть несколько RegisterInstancesWithLoadBalancer, созданных ecs-service-scheduler, все с теми же параметрами, то есть такими же идентификаторами экземпляра и балансировкой нагрузки. Я использую стандартные роли IAM и разрешения для ECS, поэтому это не должно быть проблемой с разрешениями.

У кого-то была аналогичная проблема?

Ответ 1

Ваш AWS::ECS::Service должен зарегистрировать полный ARN для TaskDefinition (Источник: См. ответ от ChrisB @AWS на форумах AWS). Главное - установить 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"]]}
        }
    }
}

Вот отличный способ захватить последнюю версию MyTaskDefinition через aws cli и jq:

aws ecs list-task-definitions --family-prefix MyTaskDefinition | jq --raw-output .taskDefinitionArns[0][-1:]

Ответ 2

Нет необходимости регистрировать полный ARN для TaskDefinition, потому что когда логический идентификатор этого ресурса предоставляется встроенной функции Ref, Ref возвращает имя ресурса Amazon (ARN).

В следующем примере функция Ref возвращает ARN задачи MyTaskDefinition, например, arn: aws: ecs: us-west-2: 123456789012: task/1abf0f6d-a411-4033-b8eb-a4eed3ad252a.

{"Ref": "MyTaskDefinition"}

Источник http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html

Ответ 3

Я думаю, что у меня была аналогичная проблема. Попробуйте посмотреть свойство "Желаемый счетчик" в шаблоне Service. Я думаю, что CloudFormation укажет, что создание/обновление все еще продолжается, пока Служба не достигнет этого количества "DesiredCount" в вашем кластере.

Ответ 4

Я нашел другой связанный сценарий, который вызовет это, и я подумал, что поставлю его здесь, если кто-то еще столкнется с ним. Если вы определяете 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 попытался развернуть DesiredCount из 2 экземпляров, он зависел, потому что изображение не было фактически доступно в репозитории (потому что репозиторий буквально только что был создан в том же шаблоне).

Итак, на данный момент решение состоит в том, чтобы создать стек CloudFormation с DesiredCount 0 для Service, загрузить в репозиторий соответствующий Image, а затем обновить стек CloudFormation для расширения службы. Или поочередно, у вас есть отдельный шаблон, который настраивает базовую инфраструктуру, такую ​​как репозиторий, загружает сборки для этого, а затем имеет отдельный шаблон для запуска, который устанавливает сами Services.

Надеюсь, что это поможет любому, у кого есть эта проблема!

Ответ 5

Все, что мешает определению службы ECS достичь желаемого подсчета. Одним из примеров является отсутствие разрешений в политиках, связанных с ролью, используемой экземплярами. Проверьте экземпляры журналов агента ECS (/var/log/ecs/ecs-agent.log.timestamp).

Другой пример: Экземпляры не имеют достаточного количества памяти для соответствия запрошенному желаемому счету.... события показывают следующее:

"... Сервис myService не смог разместить задачу, потому что экземпляр контейнера не выполнил все его требования. Ближайший соответствующий контейнер-экземпляр 123456789 имеет недостаточную доступную память..."

Ответ 6

У меня такая же проблема. Я решил увеличить объем выделенной памяти для определения задачи.

Контейнеры, которые вы используете, не должны превышать доступную память на вашем экземпляре ECS.

Ответ 7

Чтобы добавить еще одну возможность, я столкнулся с этой проблемой один раз, когда все было в порядке с шаблоном, количество требуемых задач = число запущенных задач и т.д. Оказалось, что один из базовых экземпляров EC2 застрял около 100% состояния процессора EC2 видел это как "здоровый"). Это мешало CloudFormation проверить этот конкретный экземпляр. Я убил плохой экземпляр EC2, и ECS раскрутил действительно здоровый экземпляр.

Ответ 8

Чтобы добавить еще одну точку данных, я видел, как AWS::ECS::Service навсегда застрял в CREATE_IN_PROGRESS, если образ докера ECR не доступен а) в репозитории ECR и b) прошел проверку работоспособности.

Я несколько раз пытался загрузить AWS::ECS::Service с контейнером valid-image-hash-but-failing-health-check, затем исправить изображение и сделать различные "установить желаемое количество на ноль", "установить его обратно" и т.д., и ничто из AFAICT не отклеит.

В конечном итоге мне придется удалить стек и начать заново с изображения, которое сразу же проходит проверку работоспособности. Тогда это работает нормально.

Супер хлопья.