🐕

【ECS入門】タスク配置戦略を理解する

に公開

はじめに

ECS(Amazon Elastic Container Service)を使っていると、「タスクをどのホストに置くか」「スケールインするときにどのタスクを落とすか」という疑問が出てきます。
特に EC2 起動タイプ の場合は、クラスタ内に複数のコンテナインスタンス(EC2)が存在するため、ECS がどのように配置先を決めているのか を理解しておくことが重要です。

今回は、ECS の タスク配置戦略(Placement Strategy) と 配置制約(Constraint) について整理してみます。

ECS がタスクを配置する流れ

ECS が新しいタスクを配置する際には、次の順番でインスタンスを絞り込みます。

①リソース要件チェック
タスク定義で指定された CPU、メモリ、GPU、ポート要件を満たすインスタンスを抽出。

②配置制約チェック
「この属性を持つインスタンスに置きたい」といった条件を満たすインスタンスを絞り込み。
例: attribute:ecs.instance-type == m5.large

③配置戦略の適用
ルール(binpack / spread / random)に従って配置先を決定。

④配置確定
選ばれたインスタンスにタスクを実行。

スケールイン時(タスクを減らすとき)も同様に、このルールに基づいて どのタスクを終了するか が決まります。

タスク配置戦略の種類

ECS では 3 種類の配置戦略を指定できます。

type 動作イメージ 有効なフィールド
binpack CPU またはメモリを詰め込むように配置。リソース効率化に有効。
スケールイン時は「リソースが一番余るようになるタスク」から終了。
cpu / memory
spread 指定した属性に基づいて均等に分散。
例: AZ ごと、インスタンスごとに分散。
スケールイン時はバランスを維持しつつ終了。
attribute:ecs.availability-zone / instanceId など
random ランダムに配置。単純に散らしたい場合に使う。 なし

デフォルトの戦略

サービスで実行するタスク
→ デフォルトで spread 戦略(attribute:ecs.availability-zone)
→ AZ ごとに均等配置されるので可用性を確保しやすい

スタンドアロンタスク(RunTask で手動実行)
→ デフォルト戦略はなし(ECS が適当に配置)

戦略と制約の組み合わせ

配置戦略と制約は併用可能です。たとえば、次のような組み合わせが考えられます。

  • AZ 間で分散(spread, AZ)
  • その中でメモリ効率良く配置(binpack, memory)

この場合、まず AZ 単位で均等にタスクが配置され、その AZ の中では binpack に基づいて CPU/メモリが効率的に使われます。

戦略は複数指定でき、配列の順番通りに処理されるのがポイントです。

設定例

実際には CreateService や RunTask のパラメータで指定します。

"placementStrategy": [
  {
    "type": "spread",
    "field": "attribute:ecs.availability-zone"
  },
  {
    "type": "binpack",
    "field": "memory"
  }
]

この例では「まず AZ に分散し、その中でメモリ効率良く配置」という戦略になります。

まとめ

  • ECS の EC2 起動タイプでは、どのホストにタスクを置くか/どのタスクを消すか を ECS が判断する
  • 判断のルールを変えるのが タスク配置戦略(binpack / spread / random)
  • 配置制約 を組み合わせることで、配置先をさらに制御できる
  • サービスのデフォルトは AZ spread、スタンドアロンはデフォなし

個人的には、Web アプリのように可用性が大事なケースでは spread(AZ) を基本にして、リソース効率を求めるバッチ系には binpack を組み合わせるのがおすすめです。

参考

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-placement-strategies.html

Discussion