Cloudformationを使用してAWS ECSサービスを作成しています。
すべてが正常に完了したようです。インスタンスがロードバランサーにアタッチされていることがわかります。ロードバランサーはインスタンスが正常であると宣言し、ロードバランサーにヒットすると、実行中のコンテナーに正常に移動します。
ECSコントロールパネルを見ると、サービスが安定しており、すべてが正常に見えていることがわかります。また、コンテナが安定しており、終了/再作成されていないこともわかります。
ただし、Cloudformationテンプレートは決して完了せず、サービスが安定しなかったと主張してロールバックする約30〜60分後までCREATE_IN_PROGRESS
に留まります。 CloudTrailを見ると、ecs-service-scheduler
によってインスタンス化された多くのRegisterInstancesWithLoadBalancer
があり、すべて同じパラメーター(つまり、同じインスタンスIDとロードバランサー)があります。 ECSには標準のIAMロールとアクセス許可を使用しているため、アクセス許可の問題ではありません。
誰も同様の問題がありましたか?
きみの AWS::ECS::Service
は、TaskDefinition
の完全なARNを登録する必要があります(ソース: AWSフォーラムでChrisB @ AWSの回答を参照 )。重要なのは、TaskDefinition
をリビジョンを含む完全なARNで設定することです。リビジョンをスキップした場合(:123
下の例では)、最新のリビジョンが使用されますが、CloudFormationは、失敗するまで約1時間、「CREATE_IN_PROGRESS」で昼食に出かけます。これを行う1つの方法を次に示します。
"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:]
このリソースの論理IDがRef組み込み関数に提供されると、RefはAmazonリソースネーム(ARN)を返すため、TaskDefinitionの完全なARNを登録する必要はありません。
次のサンプルでは、Ref関数はarn:aws:ecs:us-west-2:123456789012:task/1abf0f6d-a411-4033-b8eb-a4eed3ad252aなどのMyTaskDefinitionタスクのARNを返します。
{「参照」:「MyTaskDefinition」}
ソース http://docs.aws.Amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html
同様の問題があったと思います。 Serviceテンプレートの「DesiredCount」プロパティを確認してください。 CloudFormationは、サービスがクラスター内の「DesiredCount」の数に達するまで、作成/更新が進行中であることを示すと思います。
これを引き起こす別の関連するシナリオを見つけ、他の誰かがそれに遭遇した場合に備えてここに置くと考えました。 TaskDefinition
に実際には存在しない画像でContainerDefinition
を定義してから、そのTaskDefinition
をサービスとして実行しようとすると、同じハングの問題(または少なくとも同じ問題のように見えるもの)。
[〜#〜] note [〜#〜]:以下の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
これはすべて私にとって理にかなっているように見えましたが、それがハングする原因となった、書かれた/展開されたものとしての2つの問題があることがわかりました。
DesiredCount
は2に設定されます。つまり、サービスを定義するだけでなく、実際にサービスを起動して実行しようとします。 DesiredCount
を0に設定すると、これは問題なく機能します。Image
で定義されたMyECSTaskDefinition
はまだ存在しません。このテンプレートの一部としてリポジトリを作成しましたが、実際には何もプッシュしませんでした。そのため、MyECSServiceDefinition
が2つのインスタンスのDesiredCount
を起動しようとすると、イメージが実際にリポジトリで使用可能でなかったためにハングしました(リポジトリは文字通り同じテンプレートで作成されたため) 。そのため、現時点では、DesiredCount
のService
が0のCloudFormationスタックを作成し、適切なImage
をリポジトリにアップロードしてから、CloudFormationスタックを更新することです。サービスを拡大します。または、リポジトリなどのコアインフラストラクチャをセットアップする別のテンプレートを用意し、ビルドをそこにアップロードしてから、Services
自体をセットアップする別のテンプレートを実行します。
この問題を抱えている人の助けになることを願っています!
ECSサービス定義がDesired Countに到達することを妨げるもの。 1つの例は、インスタンスで使用されるロールにアタッチされたポリシーに権限がありません。インスタンスECSエージェントのログ(/var/log/ecs/ecs-agent.log.timestamp)を確認します。
別の例:インスタンスには、要求されたものと一致するのに十分なメモリがありませんDesired Count ....イベントは次のように表示されます:
"......要件をすべて満たすコンテナインスタンスがないため、サービスmyServiceはタスクを配置できませんでした。最も近い一致するコンテナインスタンス123456789に使用可能なメモリが不足しています..."
同じ問題がありました。タスク定義に割り当てるメモリサイズを増やすことで解決しました。
実行しているコンテナは、ECSインスタンスで利用可能なメモリを超えてはなりません。
別の可能性を追加するために、私はこの問題に一度遭遇しました。テンプレートですべてがうまくいっていた、目的のタスク数=実行中のタスクの数などEC2はそれを「健康」とみなしました)。 CloudFormationがその特定のインスタンスを検証するのを妨げていました。私は悪いEC2インスタンスを殺し、ECSは本当に健全なインスタンスを起動しました。