はじめに
ECS Managed Instances を使っている方の中で、「設定はできたけど、内部でどう動いているかよく分からない」という経験はないでしょうか。タスクがどのインスタンスに配置されるのか、なぜ 14 日でインスタンスが入れ替わるのか、パッチング中に何が起きているのか。こうした疑問を持つことは少なくありません。
Managed Instances は「EC2 の柔軟性と Fargate の運用容易性のいいとこ取り」と言われますが、その裏側では緻密に設計されたアルゴリズムが動いています。本記事では、タスク配置の 3 フェーズアルゴリズム、30 日パッチングサイクル、ホスト置き換えのメカニズムを解説します。内部動作を理解することで、適切な設定判断ができるようになり、トラブル時の原因推測も容易になります。
すでに ECS の基本を理解しており、Managed Instances の内部動作を深く知りたい方向けの実践的なガイドとしてお役立てください。
タスク配置アルゴリズムの詳細
タスクはどこに配置されるのか
ECS のスケジューラは、サービスやタスクを起動する際に「どのインスタンスにタスクを配置するか」を決定します。 Managed Instances では、この配置決定を完全に自動化しながら、可用性とコスト効率を両立させる仕組みが組み込まれています。スケジューラは定期的にクラスター内の状態をスナップショットし、配置が必要なタスク(Pending 状態)を特定して処理を開始します。
配置決定のプロセスは単純な空きリソース探しではありません。可用性を最優先しながら、起動速度とコスト効率も同時に最適化する必要があります。この複雑な要件を満たすため、スケジューラは3つのフェーズに分けて段階的にタスクを配置します。
タスク配置の 3 つのフェーズ
フェーズ 1:既存リソースの最大活用
最初のフェーズでは、既に稼働中のインスタンスへの配置を試みます。この段階での最優先事項は速度です。新しいインスタンスを起動するには時間がかかるため、既存のリソースを活用できれば、タスクを素早く起動できます。
スケジューラは配置制約を厳密にチェックしながら、AZ 間の分散配置を優先します。例えば 3 つの AZ で運用している場合、各 AZ に均等にタスクを分散させることで、単一 AZ 障害時の影響を最小限に抑えます。この時点で配置できなかったタスクは、次のフェーズに持ち越されます。
フェーズ 2:新規リソースの調達
既存インスタンスに配置できなかったタスクに対して、新しいインスタンスを調達します。ここでも AZ 分散配置の要件は維持され、可用性が担保されます。
インスタンスタイプの選択は、タスク定義の内容に基づいて自動的に行われます。Attribute-based Selection(属性ベース選択)を指定していれば、その条件に合致するインスタンスタイプから選択されます。指定がなければ、C・M・R ファミリーの汎用インスタンスから、ワークロードに適したものが自動選択されます。
フェーズ 3:コスト最適化(ビンパック)
新しいインスタンスを調達する際、スケジューラは First Fit Decreasing 戦略を採用します。これは配置待ちのタスクの中から、最も大きなインスタンスで効率よく詰め込める組み合わせを見つける手法です。
なぜ大きなインスタンスを優先するのか。その理由は複数あります。
まず、大きなインスタンス上では複数のタスクが同じリソースを共有するため、コンテナイメージのキャッシュを効率的に活用できます。最初のタスクがイメージをプルした後、同じイメージを使う後続のタスクはキャッシュを利用でき、起動時間が大幅に短縮されます。
また、リソースの弾力性も向上します。Java アプリケーションのように起動時に CPU バーストが発生するワークロードでも、インスタンス内の余剰リソースを一時的に活用できます。
なぜこの順序なのか
3 つのフェーズが「既存リソース → 新規調達 → ビンパック」という順序になっているのには、明確な理由があります。
まず速度を優先します。既存インスタンスへの配置は数秒で完了しますが、新規インスタンスの起動には分単位の時間がかかります。スケールアウト時に素早くタスクを起動するには、既存リソースの活用が不可欠です。
次に可用性を確保します。全フェーズを通じて AZ 分散配置が維持され、単一 AZ 障害への耐性が保証されます。可用性は妥協できない要件として、常に最優先されます。
最後にコストを最適化します。大きなインスタンスへのビンパックにより、インスタンス数を抑え、リソース利用率を高めます。ただしこれは、速度と可用性を満たした上での最適化です。
タスク定義が配置に与える影響
タスク配置の判断材料となるのが、タスク定義に記述されたリソース要件です。ECS ではコンテナレベルとタスクレベルの両方で CPU とメモリを指定できますが、それぞれ意味が異なります。
メモリ予約(memory reservation)は、コンテナが最低限必要とするメモリ量です。これは必須の設定であり、スケジューラはこの値を基にインスタンスを選択します。一方、メモリ上限(memory)を設定すると、コンテナが使用できるメモリの上限が決まります。
CPU の設定は相対的な配分を意味します。1024 を指定したコンテナは、256 を指定したコンテナの 4 倍の CPU 時間を取得できます。これはハード制限ではなく、余剰 CPU があれば他のコンテナも利用できます。
Fargate ではタスクレベルでメモリと CPU を指定し、その値がそのまま割り当てられます。一方、Managed Instances では複数タスクが同じインスタンス上で動作するため、メモリ予約を基準にしながら、実際の使用量に応じて柔軟にリソースが配分されます。
運用で押さえるべきポイント
メモリ予約の適切な設定
タスク定義では、メモリ予約を適切に設定することが重要です。過大に設定すると無駄なリソースを確保してしまい、過小だと OOM(Out of Memory)のリスクがあります。本番環境での実測値を基に、適切な値を見つけることが推奨されます。
柔軟なインスタンスタイプ指定
Attribute-based Selection は、できるだけ広い範囲を指定するのが理想です。特定のインスタンスタイプに固定すると、そのタイプが調達できない場合にタスクが起動できなくなります。GPU など特殊なハードウェアが必要な場合を除き、柔軟な指定を心がけましょう。
イメージキャッシュの活用
同じイメージを使うタスクを同時にデプロイすることで、イメージキャッシュの効果を最大化できます。スケジューラは自動的に同じインスタンス上に配置しようとするため、2 つ目以降のタスクは高速に起動できます。
自動リバランスの活用
タスクの配置が偏っている場合、Continual Rebalance 機能が自動的に是正します。これはデフォルトで有効になっており、定期的に AZ 間のバランスをチェックして、必要に応じてタスクを再配置します。運用者が手動で介入する必要はありません。
ホストライフサイクルとパッチング
Managed Instancesのホスト管理
ECS Managed Instances の大きな特徴の一つが、インスタンスのパッチ適用を完全に自動化していることです。従来の ECS on EC2では、AMI の更新、パッチ適用、インスタンスの入れ替えをすべて運用者側で管理する必要がありました。これは重要な作業ですが、ビジネス価値に直結しない運用負荷でもあります。
Managed Instances はこの負担を取り除き、AWS が責任を持ってインスタンスを最新の状態に保ちます。ただし、完全に自動化されているからこそ、その仕組みを理解しておくことが重要です。パッチング中に何が起きているのか、いつインスタンスが入れ替わるのか、タスクへの影響はどうなるのか。これらを把握することで、適切な運用計画を立てられます。
30 日パッチサイクルの全体像
Managed Instances は 30 日を 1 サイクルとして、すべてのインスタンスを最新の状態に保ちます。このサイクルは 3 つの段階に分かれており、それぞれ異なるアプローチでパッチ適用を進めます。
Day 0
タスクが最初にデプロイされるとき、または新しいインスタンスが必要になったとき、AWS は常に最新の Bottlerocket AMI を使用します。このインスタンスは EC2 のヘルスチェックを通過した状態で提供されるため、既知の良好な状態であることが保証されています。
Day 14
インスタンスが起動してから 14 日が経過すると、パッチングサイクルが始まります。この段階では、EC2 メンテナンスウィンドウの設定に従って、インスタンスの置き換えが実行されます。
Day 21
21 日を過ぎると、AWS はより積極的にインスタンスを置き換え始めます。この段階では、メンテナンスウィンドウの設定に関わらず、置き換えが実行される可能性があります。
ホスト置き換えのメカニズム
インスタンスを置き換える必要が生じたとき、ECS は慎重に計画されたフローに従って処理を進めます。パッチング以外にも、EC2 のメンテナンスイベントや、運用者による手動のドレイン操作、コスト最適化のための統合など、さまざまな理由で置き換えが発生します。
Start Before Stop の原則
インスタンス置き換えで最も重要な原則が「Start Before Stop」です。これは文字通り、古いタスクを停止する前に、必ず新しいタスクを起動してヘルシーな状態にするというルールです。
この原則は ECS 全体の設計思想として貫かれており、可用性を犠牲にしてコストや速度を優先することは決してなく、常にサービスの継続性が最優先されます。
マネージドタスクとアンマネージドタスク
置き換えの過程では、マネージドタスクとアンマネージドタスクで扱いが異なります。
マネージドタスクとは、ECS サービスによって管理されているタスクです。これらは自動的に新しいインスタンス上に起動され、ヘルシーな状態になったことを確認した後、旧インスタンス上のタスクが停止されます。
一方、アンマネージドタスクは、RunTask や StartTask API で直接起動されたタスクです。これらは ECS サービスの管理下にないため、スケジューラは自動的に置き換えません。代わりに、これらのタスクは最後まで実行が保証されます。タスクのシャットダウングレースピリオドやスケールイン保護が設定されていれば、それらの設定が尊重され、タスクが安全に終了できる状態になるまで待機します。
なぜ Bottlerocket なのか
Managed Instances では Bottlerocket という AWS 独自の OS が使用されています。カスタム AMI は使用できず、Bottlerocket のみがサポートされます。
AWS が AMI の選択肢を限定している理由は、パッチ適用を自動化するためです。AMI の構成を把握していなければ、安全かつ確実にパッチを適用できません。Bottlerocket に統一することで、AWS は責任を持って最新の状態を維持し、運用者はその負担から解放されます。
運用で押さえるべきポイント
グレースフルシャットダウンの実装
タスクが停止される際、まず SIGTERM シグナルが送信されます。アプリケーションはこのシグナルを受け取ったら、新しいリクエストの受付を停止し、処理中のリクエストを完了させてから終了する必要があります。シャットダウングレースピリオドを適切に設定し、アプリケーションがクリーンアップに必要な時間を確保しましょう。
長時間実行タスクへの考慮
Managed Instances では最長でも 30 日でインスタンスが入れ替わります。数週間単位で実行されるバッチ処理など、30 日を超える可能性があるタスクには適していません。このようなワークロードには、ECS on EC2 や別の実行基盤を検討すべきです。
メンテナンスウィンドウの設定
ビジネスへの影響が少ない時間帯を慎重に選びましょう。トラフィックパターンを分析し、ピーク時を避けた設定が推奨されます。ただし、21 日を過ぎるとウィンドウ外でも置き換えが発生する可能性があることを念頭に置いてください。
まとめ
本記事では、ECS Managed Instances の内部アーキテクチャを深掘りしました。
本記事のポイント
タスク配置の 3 フェーズアプローチ
速度(既存リソース活用) → 可用性(AZスプレッド) → コスト(ビンパック)の順で最適化
30 日パッチングサイクル
Day 14 から段階的に開始、Day 21 以降は確実な完了を優先
Start Before Stop 原則
すべての置き換えで新タスクを先に起動し、可用性を最優先
内部動作を理解することで、適切なタスク定義の設定、メンテナンスウィンドウの計画、トラブル時の原因推測が可能になります。設定画面の裏側で何が起きているかを知ることが、Managed Instances を最大限活用する第一歩です。
参考リンク