1. この記事について — なぜ今もEC2をコンピュート基盤に選ぶのか

- EC2(本シリーズ) — 素のコンピュート基盤を直接設計・運用。インスタンス選定・スケーリング・Nitroまで
- ECS / EKS — コンテナという抽象化された実行基盤。インフラ管理をクラスタに委譲したい場合
- Lambda / サーバーレス — イベント駆動の従量実行。常駐不要の短時間処理に最適
- コスト最適化 Vol2 — RI×Savings Plans×Spot×Graviton を購入オプション戦略として体系的に扱うシリーズ
- ワークロード特性からファミリー・世代・最適化種別を選定し、過剰プロビジョニングを避けられる
- Auto Scaling の予測スケーリングとウォームプールを組み合わせ、起動レイテンシを設計レベルで制御できる
- Graviton(arm64)移行の可否判断とアプリ互換性確認を設計フローとして実施できる
- Spot の中断耐性をコンピュート基盤の可用性設計として組み込める
1-1. 本記事のゴール
Amazon EC2 は AWS の最も基本的なコンピュートサービスです。
仮想マシンのスペック・OS・ネットワーク・ストレージをすべて自分で設計できる反面、
その分だけ設計の自由度と運用責任が生まれます。
「コンテナ全盛時代に EC2 を選ぶ理由はあるのか?」という問いは自然ですが、
実際には次のような要因で EC2 が選ばれ続けています。
- OS レベルのチューニングが必要なワークロード(カーネルパラメータ・NUMA トポロジ最適化)
- 商用ライセンスの都合でホスト単位の課金が求められるソフトウェア
- GPU インスタンスを専有で利用する機械学習サービス
- コンテナランタイムに収まらない大容量メモリや特殊なネットワーク要件
これらのケースでは EC2 の「インフラを直接設計できる」特性がそのまま強みになります。
本シリーズの Vol1 では、EC2 を本番のコンピュート基盤として使い続けるために必要な
「インスタンス選定・スケーリング戦略・Graviton 移行・Spot 活用・Nitro System・Image Builder」を
設計・運用の視点で体系的に扱います。
読み終えた時点で、新規のコンピュート基盤を EC2 で設計できる状態を目指します。
各セクションのスコープを以下に示します。
| セクション | 扱う内容 |
|---|---|
| §2 インスタンスタイプ選定 | ファミリー・世代・最適化サフィックス・バースト T 系・選定フロー |
| §3 Auto Scaling 戦略 | Launch Template・動的スケーリング・予測スケーリング・ウォームプール |
| §4 Graviton 移行 | arm64 アーキテクチャ採用の設計判断・互換性確認・マルチアーキビルド |
| §5 Spot 活用 | 中断耐性設計・mixed instances policy・容量最適化割り当て |
| §6 Nitro System・専有・配置 | Nitro 基盤の設計・Dedicated Hosts・Placement Group |
| §7 EC2 Image Builder | ゴールデン AMI の自動化・パッチ運用・IaC 統合 |
| §8 詰まりポイント・まとめ | アンチパターン→正解変換・総括・Vol2 予告 |
1-2. 読者像
本記事は以下の読者を対象としています。
- EC2 を本番のコンピュート基盤として設計・構築するインフラエンジニア・SRE
- Auto Scaling の動的スケーリングは使っているが、予測スケーリングやウォームプールはまだ検討中のプラットフォームエンジニア
- コンテナへの完全移行は難しく、EC2 のまま運用品質を高めたいシステム担当者
- Graviton(arm64)への移行コストと移植リスクを把握した上で判断したいアーキテクト
AWS コンソールで EC2 インスタンスを起動した経験があり、
VPC・セキュリティグループ・EBS の基本を理解していることを前提とします。
IAM・CloudWatch・Auto Scaling グループの基本操作も前提知識に含みます。
本記事では以下は扱いません。
- EC2 の基本操作(インスタンス起動・停止・キーペア設定) — 公式ドキュメントを参照してください
- RI / Savings Plans の購入判断 — コスト最適化 Vol2 で体系的に扱います
- ECS / EKS へのコンテナ移行 — 各コンテナシリーズを参照してください
なお、本記事は設計・運用の判断基準を扱うため、コードサンプルよりも
「なぜそう設計するのか」という思考フローを中心に構成しています。
Terraform / CloudFormation の具体的な実装例は各 IaC シリーズを参照してください。
各セクションは独立して読めます。すでに §2(インスタンス選定)が完了しているなら
§3(Auto Scaling)から読み始めることも可能です。
1-3. 本シリーズの位置づけと既存記事との棲み分け
AWS Compute には、EC2 以外にもコンテナ(ECS/EKS)とサーバーレス(Lambda)という選択肢があります。
3 つのサービスは互いに競合せず、ワークロードの性質によって使い分けるものです。
EC2 が適しているワークロードは、OS レベルの設定が必要なもの、
特定のライセンスソフトウェアを動かすもの、
または長時間常駐して CPU/メモリを継続的に消費するものです。
Graviton 移行や Spot 活用も、インスタンスという単位を直接操作するからこそ成り立ちます。
具体的な例を挙げると、次のようなケースが EC2 の典型的な用途です。
- オンプレミスから移行した Windows / Linux ワークロードで、OS のカーネルパラメータ調整が必要なもの
- Oracle Database など特定 OS へのバインドが強いライセンスソフトウェア
- GPU インスタンスを使う機械学習推論サービス
- 超大規模インメモリ処理で 768 GB を超えるメモリが必要なもの
コンテナ(ECS/EKS)は、インフラを抽象化して実行基盤を共有したい場合に選びます。
デプロイの俊敏性とスケーリングの柔軟性が EC2 直接管理より高くなります。
マイクロサービスアーキテクチャや CI/CD 主導のデプロイサイクルが速いサービスに向いています。
Lambdaは、リクエスト単位の短時間処理に特化した従量課金の実行環境です。
常駐不要のイベント駆動処理において最もコスト効率が高くなります。
最大実行時間 15 分・最大メモリ 10 GB という制約の内側に収まるワークロードが対象です。
コスト最適化 Vol2は、RI(Reserved Instances)・Savings Plans・Spot・Graviton を
「購入オプションによるコスト削減戦略」として体系的に扱います。
本シリーズの §4(Graviton)・§5(Spot)は設計・運用視点であり、
コスト削減の購入戦略は Vol2 へ誘導しています。
RI / Savings Plans / Spot / Graviton を「コスト削減の購入オプション」として体系的に扱うのはコスト最適化 Vol2 です。本シリーズの §4(Graviton)/§5(Spot)はコンピュート基盤の設計・運用視点で扱い、コスト削減の数値比較は Vol2 に委ねています。
2. インスタンスタイプ選定 — ファミリー・世代・最適化

2-1. ファミリーと世代の選び方
EC2 のインスタンスタイプは「ファミリー」「世代」「最適化サフィックス」「サイズ」の 4 要素で構成されます。
たとえば m8g.2xlarge は「汎用(M)」「第 8 世代(Graviton4)」「サフィックスなし」「2xlarge」です。
主要ファミリーの用途:
| ファミリー | vCPU:メモリ比 | 代表ユースケース | 最新世代例 |
|---|---|---|---|
| M(汎用) | 1:4 バランス型 | Web/API サーバー・小規模 DB | m8g, m7i, m7a |
| C(コンピュート最適化) | 1:2 CPU 優先 | バッチ・エンコード・HPC | c8g, c7i, c7a |
| R(メモリ最適化) | 1:8 メモリ優先 | インメモリ DB・Elasticsearch | r8g, r7i, r7a |
| T(バースト) | 低ベースライン+クレジット | 開発環境・軽量サービス | t4g, t3, t3a |
| G / P | GPU 搭載 | ML 推論・グラフィック処理 | g6, p4d |
| I / D | ストレージ最適化 NVMe | 高スループット DB | i4i, d3 |
世代は常に最新世代を選ぶのが基本方針です。
最新世代は前世代より同価格帯でパフォーマンスが向上しており、最新の Nitro カードと拡張ネットワーク帯域も利用できます。
2025 年時点の最新世代:
- Graviton4:
8gサフィックス(m8g / c8g / r8g) - Intel Sapphire Rapids:
7iサフィックス(m7i / c7i / r7i) - AMD EPYC Genoa:
7aサフィックス(m7a / c7a / r7a)
最適化サフィックスは特定リソースを強化した派生型です。
| サフィックス | 内容 | 代表例 |
|---|---|---|
n | 高帯域ネットワーク(Nitro カード増設) | m8gn で 600 Gbps — パケット転送・NW 仮想化 |
b | EBS 最適化帯域強化 | c8gb で 150 Gbps — ストレージ集約 I/O |
d | ローカル NVMe ストレージ搭載 | 一時データ・チェックポイント保存 |
Graviton4(第 8 世代)の性能改善は Graviton3 比で最大 30% 向上です。
ワークロード別ではデータベース最大 40%、Web アプリ最大 30%、Java アプリ最大 45% の改善が確認されています。
最大インスタンスサイズは 48xlarge、メモリは最大 768 GB まで対応します。
arm64 への移行判断と互換性確認の手順は §4 で詳しく扱います。
Graviton4 対応インスタンスファミリーの一覧:
| インスタンス | 特徴 | 主な用途 |
|---|---|---|
| m8g | 汎用 Graviton4。最大 48xlarge / 384 GB | Web/API サーバー・一般アプリ |
| c8g | コンピュート最適化 Graviton4。最大 192 vCPU | バッチ処理・高速計算 |
| r8g | メモリ最適化 Graviton4。最大 48xlarge / 768 GB | 大規模インメモリ DB |
| m8gn | m8g + Nitro カード 600 Gbps | ネットワーク仮想化・パケット転送 |
| c8gb | c8g + EBS 最適化 150 Gbps | ストレージ集約 I/O |
| c8gn | c8g + Nitro カード 600 Gbps | ネットワーク集約型 HPC |
同じファミリーで x86_64 と arm64 を比較する場合、
Graviton4 の同等インスタンスは m7i や m7a より価格効率が高いケースも多いです。
ただし、個々のワークロードによって異なるため、負荷試験での検証が推奨されます。
2-2. vCPU・メモリ最適化とバースト(T系)
vCPU とメモリ比率の選定では、アプリケーションのプロファイリング結果が起点です。
本番環境または負荷試験で 2 週間の CloudWatch メトリクスを取得し、CPU とメモリの使用率推移を比較します。
- CPU が先に張り付き、メモリが余っている → C 系(1:2)を検討
- メモリが先に枯渇し、CPU が余っている → R 系(1:8)を検討
- 両方が均等に使われている → M 系(1:4)のままで適正
初期選定はまず M 系からスタートし、観測結果に基づいてファミリーを変更する順序が安全です。
T 系(バーストインスタンス)は「CPU クレジット」によって、通常負荷時は小さなインスタンスとして動き、
スパイク時だけベースラインを超えて CPU をバーストできます。
| クレジットの状態 | 挙動 |
|---|---|
| 蓄積中(ベースライン以下) | 毎分クレジットを獲得し、次のバーストに備える |
| 消費中(ベースライン超) | 蓄積クレジットを消費し、高い CPU 性能を発揮する |
| 枯渇(standard モード) | CPU がベースライン以下に制限され、レスポンスが著しく低下する |
| 枯渇(unlimited モード) | 制限されないが、超過分が vCPU 時間あたりで追加課金される |
unlimited モードはデフォルトで有効です。
トラフィックが想定外に増加し続けた場合、クレジット超過分が累積して高額請求になる事例があります。
本番環境では以下のどちらかを選択します。
standardモードを明示指定し、クレジット枯渇時は CPU が制限されるよう設計する- CPU 使用率が常時 20% を超えるなら T 系をやめて M 系・C 系に変更する
T 系インスタンスのベースライン CPU 使用率:
各インスタンスサイズのベースライン(この使用率以下ならクレジットが蓄積される)の目安です。
| インスタンス | vCPU | ベースライン CPU 使用率(全体) |
|---|---|---|
| t4g.nano | 2 | 5%(合計 10%) |
| t4g.micro | 2 | 10%(合計 20%) |
| t4g.small | 2 | 20%(合計 40%) |
| t4g.medium | 2 | 20%(合計 40%) |
| t4g.large | 2 | 30%(合計 60%) |
| t4g.xlarge | 4 | 40%(合計 160%) |
| t4g.2xlarge | 8 | 40%(合計 320%) |
ベースライン CPU 使用率は全 vCPU に対する割合として表記されます。
t4g.nano の場合、2 vCPU で合計 10%(vCPU あたり 5%)がベースラインです。
モニタリングでは CPUCreditBalance メトリクスが 0 に近づいていないかを監視します。
T 系が適しているケース:
- 開発・ステージング環境(コスト優先)
- 大半の時間が待機中のジョブキュー・管理バッチ
- 深夜のみ負荷が高く、日中はほぼアイドルのサービス
T 系が不適なケース:
- 常時一定以上の CPU 使用率が続く本番 Web サーバー
- 予測できないスパイクが頻繁に発生するサービス
2-3. 選定フローとゴール状態
インスタンスタイプの選定は次の 4 ステップで進めます。
ステップ 1: ワークロード特性の分類
| 特性 | ファミリー候補 |
|---|---|
| CPU 集約(バッチ・エンコード・HPC) | C 系 |
| メモリ集約(インメモリ DB・大規模キャッシュ) | R 系 |
| バランス型(Web/API サーバー・一般アプリ) | M 系 |
| 突発バースト主体で常時負荷が低い | T 系(standard モード) |
ステップ 2: アーキテクチャの選択
| アーキテクチャ | 特徴 | 推奨シーン |
|---|---|---|
| Graviton(arm64) | 性能/価格比が最も高い | 新規ワークロード・互換性確認済みのサービス |
Intel x86_64(i) | ソフトウェア互換性が最広 | 移植コストを許容できない既存アプリ |
AMD x86_64(a) | Intel より若干安価 | Intel 互換でコスト削減を求める場合 |
新規ワークロードでは Graviton を第一候補とし、互換性上の問題があれば Intel/AMD にフォールバックします。
ステップ 3: 世代の確定
同じファミリー・アーキテクチャでは常に最新世代を選びます。
旧世代を選ぶ理由として許容されるのは、特定の AMI やドライバの新世代未対応が明確に確認できる場合のみです。
ステップ 4: サイズ決定とモニタリング
初期サイズは「少し余裕のある見積もり」から始め、
2 週間の CloudWatch メトリクス(CPU 使用率・ネットワーク I/O・EBS スループット)を観測して調整します。
AWS Compute Optimizer の推奨は補助的な参考情報として活用します。
過剰プロビジョニングの回避:
「とりあえず大きめ」で放置すると、コストが無駄になるだけでなく
Auto Scaling のスケールアウト判断が遅れてスパイク対応が悪化します。
モニタリングに基づく定期的なライトサイジングを運用プロセスに組み込みます。
過少プロビジョニングの回避:
初日から最小サイズにして突発スパイクによるダウンを招かないよう、
負荷試験で P99 レイテンシが SLA 内に収まることを確認してからサイズを下げる順序が安全です。
選定のゴール状態:
以下の 3 点が達成されていれば、適切な選定が完了しています。
- 通常負荷時の CPU 使用率が 20〜70% の範囲に収まっている
- メモリ使用率が 50〜80% の範囲で安定している
- Auto Scaling がスケールアウト/インを繰り返せており、未使用インスタンスが残らない状態になっている
インスタンスサイズ選定の実践的チェックリスト:
選定作業を始める前に以下を確認します。
- [ ] 現行環境での CPU/メモリのピーク・平均使用率を把握している
- [ ] アプリケーションの起動時間を把握している。30 秒以上かかる場合はウォームプールが有効
- [ ] arm64 の依存ライブラリ対応状況を確認している(Python/Node.js/Java 系は概ね対応済み)
- [ ] T 系を検討している場合、
standardモードを明示的に指定する方針が決まっている - [ ] 4 週間後にライトサイジングをレビューするスケジュールを確保している
稼働中インスタンスのタイプ変更:
稼働中の EC2 インスタンスのタイプを変更するには、一度停止する必要があります。
Auto Scaling グループで管理されている場合は、Launch Template のバージョンを更新し、
インスタンスリフレッシュ機能を使って順次入れ替えると、無停止での変更が可能です。
インスタンスリフレッシュ時は最小健全性パーセンテージ(例: 90%)を設定し、
変更中もサービスが継続稼働できる状態を維持します。
インスタンスタイプの選定が完了したら、次のステップは §3(Auto Scaling 戦略)です。
選定したインスタンスタイプを Launch Template に定義し、
動的スケーリング・予測スケーリング・ウォームプールを組み合わせることで、
コンピュート基盤のスケーリング戦略が完成します。
なお、mixed instances policy を利用する場合は、
複数のインスタンスタイプを同一 ASG に混在させるため、
本 §2 で選定したファミリーと性能特性が近い複数のタイプをリストとして定義します。
性能差が大きいタイプを混在させると、スケーリング計算が不正確になるため注意が必要です。
3. Auto Scaling 戦略 — 予測スケーリングとウォームプール

3-1. Launch Template と動的スケーリング
Launch Template は、Auto Scaling グループが起動するインスタンスの仕様を一元管理するコンポーネントです。AMI ID・インスタンスタイプ・セキュリティグループ・IAM インスタンスプロファイル・ユーザーデータ・EBS 設定をバージョン管理された定義として保持します。旧来の Launch Configuration からの最大の進化点はバージョン管理と参照の柔軟性にあります。変更のたびに新バージョンを作成し、ASG には $Latest(常に最新)または $Default(明示固定)を参照させることで、設定のロールバックを容易に行えます。
本番環境では $Default バージョンを固定し、テスト済みのバージョンのみ昇格させる運用フローを整備することを推奨します。$Latest を本番 ASG に参照させると、意図せずテスト中の設定変更が本番インスタンスに適用されるリスクがあります。
Launch Template でとくに重要な設定項目を以下に示します。
| 設定項目 | 推奨値・注意点 |
|---|---|
HttpTokens(IMDSv2) | required を必須設定。SSRF によるメタデータ漏洩を防止します |
HttpPutResponseHopLimit | 1 に設定。コンテナ内からホストメタデータへの到達を遮断します |
DeleteOnTermination(EBS) | データを持たないルートボリュームは true に設定し、コストを節約します |
| ユーザーデータ | 冪等性を確保します。再起動時の再実行を考慮し、インストール済み判定を組み込みます |
{
"MetadataOptions": {
"HttpTokens": "required",
"HttpEndpoint": "enabled",
"HttpPutResponseHopLimit": 1
}
}
HttpPutResponseHopLimit: 1 を設定すると、コンテナ内からホストのインスタンスメタデータサービスへ到達できない構成になります。コンテナワークロードと EC2 の両方を同一インスタンスで動かす場合に必ず設定します。
動的スケーリングポリシーの使い分け
Auto Scaling グループには 3 種類の動的スケーリングポリシーがあります。
ターゲット追跡スケーリングは最もシンプルで推奨される方式です。目標値(例: CPU 使用率 60 %)を設定すると、ASG が CloudWatch アラームを自動生成・管理し、目標値を維持するようにインスタンス数を自動調整します。主な定義済みメトリクスは以下のとおりです。
| メトリクス | ユースケース |
|---|---|
ASGAverageCPUUtilization | CPU バウンドな汎用ワークロード・バッチ処理 |
ALBRequestCountPerTarget | Web / API サーバーのリクエスト処理能力ベース |
ASGAverageNetworkIn / Out | ストリーミング・ログ転送など帯域バウンド |
カスタムメトリクス(customized) | SQS キュー深度・DB コネクション数など |
ターゲット追跡ではスケールインのクールダウンを設定できます。スケールアウト後に急激なスケールインが発生しないよう、scaleInCooldown(デフォルト 300 秒)をワークロードの特性に合わせて調整します。
ステップスケーリングは複数の閾値帯域に応じて起動台数を段階的に制御したい場合に適しています。例えば、CPU 使用率 70–80 % でインスタンスを 2 台追加し、80 % 超で 5 台追加するといった設定が可能です。estimatedInstanceWarmup(ウォームアップ時間)を適切に設定することで、スケールアウト直後のフラッピングを防止できます。
簡易スケーリングは 1 つの CloudWatch アラームに対して 1 つのアクションのみを定義する旧来の方式です。CloudWatch アラームのクールダウン時間に依存するため、現在はターゲット追跡またはステップスケーリングへの移行を推奨します。
3-2. 予測スケーリング・ウォームプール・ライフサイクルフック
予測スケーリング(Predictive Scaling) は、Auto Scaling グループの過去 14 日間のメトリクスデータを機械学習モデルで分析し、最大 48 時間先のスケジュールを自動生成する機能です。朝のトラフィック急増・毎日定刻のバッチ実行・週次ピークなど、周期的な負荷パターンを持つワークロードで特に効果的です。
2025 年の更新でサポートリージョンが拡大し、mixed instances policy との組み合わせが正式にサポートされました。ただし、mixed instances policy 使用時は均質性の前提に注意が必要です。予測モデルはインスタンス群を均質なキャパシティ単位として計算するため、性能差の大きいインスタンスタイプを混在させると、実際のキャパシティと予測値に乖離が生まれます。この場合は ForecastAndScale(予測 + 動的スケーリング併用)モードでターゲット追跡ポリシーと組み合わせて補完します。
予測スケーリングの Terraform 設定例を以下に示します。
resource "aws_autoscaling_policy" "predictive" {
name = "predictive-scaling-policy"
autoscaling_group_name = aws_autoscaling_group.app.name
policy_type= "PredictiveScaling"
predictive_scaling_configuration {
metric_specification {
target_value = 60
predefined_scaling_metric_specification {
predefined_metric_type = "ASGAverageCPUUtilization"
}
predefined_load_metric_specification {
predefined_metric_type = "ASGTotalCPUUtilization"
}
}
mode = "ForecastAndScale"
scheduling_buffer_time = 300
max_capacity_breach_behavior = "IncreaseMaxCapacity"
max_capacity_buffer = 10
}
}
scheduling_buffer_time: 300 はスケールアウト完了の 5 分前に起動を開始するバッファ時間です。インスタンスの起動・初期化に時間がかかるワークロードでは大きめに設定します。max_capacity_buffer: 10 は予測キャパシティの 10 % を上乗せして最大キャパシティを自動設定する設定です。
ウォームプール(Warm Pool) は、初期化済みのインスタンスをプールとして保持し、スケールアウト時の起動遅延を削減する機能です。
通常の ASG では、インスタンスが InService になるまでに「AMI 起動 → OS ブート → UserData 実行 → アプリ初期化」という Cold Start フローが発生し、数分の遅延が生じます。ウォームプールはこれらの工程を事前に完了させたインスタンスを停止状態(Stopped)または実行状態(Running)で待機させておきます。スケールアウト時は即座に InService へ遷移させます。
| 状態 | 課金 | 起動遅延削減効果 | ユースケース |
|---|---|---|---|
| Stopped | EBS のみ(インスタンス料金なし) | OS ブートまでの時間を削減 | コスト重視。アプリ初期化が速い場合 |
| Running | フル課金 | UserData・アプリ初期化を含む全工程を削減 | 起動遅延をゼロにしたい最高速要件 |
2025 年 11 月の更新で mixed instances policy との正式対応が追加され、複数インスタンスタイプを混在させた構成でもウォームプールを利用できるようになりました。
Terraform での設定例を以下に示します。
resource "aws_autoscaling_group" "app" {
name = "app-asg"
min_size= 2
max_size= 20
desired_capacity = 4
# ... 他の設定省略 ...
warm_pool {
pool_state= "Stopped"
min_size = 2
max_group_prepared_capacity = 6
instance_reuse_policy {
reuse_on_scale_in = true
}
}
}
reuse_on_scale_in: true を設定すると、スケールイン時に終了するインスタンスをウォームプールへ戻してプール補充に再利用します。max_group_prepared_capacity はウォームプールに保持するインスタンス数の上限で、ASG の desired_capacity と合算して設定します。
ライフサイクルフック(Lifecycle Hooks) は、インスタンスの起動・終了フェーズに独自処理を挟む機能です。ASG は SNS / SQS / EventBridge を介してフックを発火し、インスタンスは指定の状態(Pending:Wait / Terminating:Wait)で一時停止します。外部プロセス(Lambda / EC2 上のスクリプト)が処理を完了させた後、complete-lifecycle-action で次フェーズへ遷移させます。
起動フック(Launching) の主なユースケースは以下のとおりです。
- 監視エージェント(CloudWatch Agent / Datadog Agent 等)のインストール完了確認
- 自社認証局証明書の配布と TLS 設定
- サービスディスカバリへの登録
- ウォームアップ待機(アプリが最初のリクエストを正常に処理できる状態になるまで待機)
終了フック(Terminating) の主なユースケースは以下のとおりです。
- ALB ターゲットグループからのコネクションドレイン(処理中セッションの完了)
- 実行中バッチジョブの退避・チェックポイント保存
- ログのフラッシュと S3 への転送
- サービスディスカバリからの登録解除
ライフサイクルフックのタイムアウトは最大 7,200 秒(2 時間)まで設定できます。処理が完了したら以下のコマンドで ASG に通知します。
aws autoscaling complete-lifecycle-action \
--lifecycle-hook-name "app-launching-hook" \
--auto-scaling-group-name "my-asg" \
--lifecycle-action-result CONTINUE \
--instance-id i-0123456789abcdef0
タイムアウトまでに完了通知が届かない場合、DefaultResult に設定した値(CONTINUE または ABANDON)が適用されます。起動フックでは ABANDON(起動をキャンセル)を設定し、初期化に失敗したインスタンスが InService に入らないよう設計することを推奨します。
ライフサイクルフックとウォームプールを組み合わせる場合、ウォームプールへの遷移時にも起動フックが発火します。InstanceReusePolicy で再利用インスタンスのフック発火を制御できるため、再利用時に不要な初期化処理をスキップする設計が可能です。
4. Graviton 移行 — arm64 をコンピュート基盤に採用する

コスト削減の費用対効果についてはコスト最適化 Vol2 を参照ください。本章は arm64 アーキテクチャのコンピュート基盤への採用・移行設計・運用に集中します。価格性能比の購入戦略はコスト最適化 Vol2 で扱います。
4-1. arm64 採用の設計判断とアプリ互換性
Graviton4(第 4 世代 Arm ベースプロセッサ)は C8g / M8g / R8g / X8g インスタンスファミリーに対応し、Graviton3 比で最大 30 % の性能向上を実現します。ワークロード別の向上は、データベース +40 %・Web アプリ +30 %・Java アプリ +45 % が確認されています。最大インスタンスサイズは 48xlarge で、384–768 GB のメモリを搭載できます。
arm64 採用の設計判断フロー
arm64 インスタンスへの移行を判断する際は、以下の順序で互換性を確認します。
- OS / AMI の確認: Amazon Linux 2023・Ubuntu 24.04・RHEL 9 など主要ディストリビューションは arm64 版 AMI を公式提供しています。
- 主要言語・ランタイムの確認: 後述の互換性一覧を参照します。
- 依存ライブラリ・C 拡張の確認: x86 専用バイナリやベンダー提供のクローズドソースライブラリを洗い出します。
- SIMD 命令セットの確認: SSE / AVX を使用している場合、ARM NEON / SVE 対応版の有無を確認します。
- パイロット評価: Launch Template のインスタンスタイプを arm64 に変えて試験起動し、動作を確認します。
言語・ランタイム別互換性
| 言語 / ランタイム | arm64 サポート状況 | 注意点 |
|---|---|---|
| Python(CPython) | 3.6 以降で arm64 公式ビルドあり | NumPy / scikit-learn 等は arm64 向けホイールが公式配布済 |
| Node.js | v16 以降で arm64 ネイティブバイナリ提供 | ネイティブアドオン(.node ファイル)は個別確認が必要 |
| JVM(OpenJDK) | OpenJDK 11+ / AWS Corretto で arm64 版提供 | JIT コンパイラが Graviton での最適化を活かせます |
| Go | 標準でクロスコンパイル対応 | GOARCH=arm64 GOOS=linux go build でバイナリ生成 |
| Rust | aarch64-unknown-linux-gnu ターゲットで対応 | クロスコンパイル時は cross ツールが便利 |
| C / C++ | GCC 10+ / Clang 12+ で arm64 対応 | -march=armv8.2-a で Graviton 最適化を有効化します |
移行の第一歩:AMI スワップ法
既存ワークロードを最小手順で arm64 動作確認する「AMI スワップ法」が有効です。Launch Template のインスタンスタイプを m7i.large(x86)から m8g.large(Graviton4 / arm64)に変更し、arm64 版 AMI を指定して試験起動します。AMI の切り替えは AWS Management Console / Terraform どちらからでも数分で実施できます。
試験起動後は以下の点を確認します。
- アプリケーションプロセスが正常に起動するか
- 単体テスト・統合テストがすべてパスするか
- エラーログに依存ライブラリ関連のエラーが出ていないか
4-2. マルチアーキ対応と性能ベンチマーク
コンテナ化されたアプリケーションを arm64 で運用するには、マルチアーキテクチャイメージの構築が必要です。Docker BuildKit の buildx を利用すると、単一のイメージタグで linux/amd64(x86)と linux/arm64 の両アーキテクチャをサポートするマニフェストリストを生成できます。
# QEMU エミュレータのセットアップ(初回のみ)
docker run --privileged --rm tonistiigi/binfmt --install all
# マルチアーキビルダーの作成
docker buildx create --name multiarch --driver docker-container --use
# linux/amd64 + linux/arm64 の同時ビルド & レジストリへ push
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/app:latest \
--push .
QEMU エミュレーションによるクロスビルドは互換性確認に適していますが、ネイティブビルドと比較してコンパイル速度が大幅に低下します(x86 上での arm64 クロスビルドは 5–10 倍遅くなることがあります)。本番 CI/CD パイプラインでは ネイティブ arm64 ランナーの使用を推奨します。
CI/CD での arm64 ネイティブビルド
| CI/CD 環境 | arm64 ネイティブビルドの方法 |
|---|---|
| AWS CodeBuild | アーキテクチャに ARM を指定(Graviton ランナー)。コスト効率も高いです |
| GitHub Actions | ubuntu-24.04-arm ランナー(2024 年 GA)で arm64 ネイティブビルドを実行できます |
| GitLab CI | arm64 自己ホストランナーを EC2 Graviton インスタンスで構成します |
| CircleCI | arm.medium / arm.large リソースクラスを指定します |
性能ベンチマークの取り方
Graviton 移行の可否を客観的に判断するため、x86 と arm64 で同一ワークロードを定量比較します。
Step 1: マイクロベンチマーク
sysbench / stress-ng / phoronix-test-suite を使い、CPU 演算(数値計算・文字列処理・暗号化 AES / RSA)を単体計測します。Graviton の性能優位性が出やすいワークロードを事前に特定できます。
Step 2: アプリケーションベンチマーク
wrk2 / Locust / Artillery で本番想定のトラフィックを生成し、RPS(秒あたりリクエスト数)・P50 / P99 レイテンシ・エラーレートを x86 と arm64 で比較します。
Step 3: 本番段階的ロールアウト
ベンチマーク結果が良好であれば、ASG の mixed instances policy を使って Graviton 比率を段階的に拡大します。
resource "aws_autoscaling_group" "app" {
name = "app-asg"
min_size= 2
max_size= 20
desired_capacity = 4
vpc_zone_identifier = var.private_subnet_ids
mixed_instances_policy {
instances_distribution {
on_demand_base_capacity= 2
on_demand_percentage_above_base_capacity = 30
spot_allocation_strategy = "capacity-optimized"
}
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.app_arm64.id
}
override { instance_type = "m8g.large" }
override { instance_type = "m8g.xlarge" }
override { instance_type = "c8g.large" }
override { instance_type = "m7g.large" }
}
}
}
On-Demand 台数をベースラインとして確保しながら Graviton Spot の比率を徐々に高めることで、段階的なリスク管理が可能です。
5. Spot 活用 — 中断耐性のあるコンピュート設計
Spot インスタンスのコスト削減 ROI(RI / Spot 選択・割引率・購入戦略の比較)はコスト最適化 Vol2 で詳しく扱います。本章は Spot を安全に使いこなすための中断耐性設計に集中します。

Spot インスタンスはオンデマンド価格と比較して大幅に安く利用できます。その代償として、EC2 が容量を必要とした場合に 2 分前の通知を経て中断される可能性があります。本章では、この中断を前提とした設計パターンにより、可用性とコストを両立する方法を解説します。
5-1. Spot 中断の仕組みと 2 分前通知
AWS は Spot インスタンスを中断する 2 分前に中断通知(Interruption Notice)を発行します。通知の受け取り方は 2 つあります。
EC2 インスタンスメタデータ経由のポーリング
インスタンス内から定期的にメタデータを参照する方法です。
# 中断通知の確認(インスタンス内から実行)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
NOTICE=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
"http://169.254.169.254/latest/meta-data/spot/interruption-action")
echo "Interruption notice: $NOTICE"
通知を検知したら、新規リクエストの受け付けを停止し、既存の処理を完了させてからシャットダウンします。10〜15 秒ごとにポーリングすることで、2 分以内に確実に検知できます。
EventBridge 経由の自動処理
EC2 Spot Instance Interruption Warning イベントを EventBridge で受信する方法です。Lambda または SNS と組み合わせて自動化できます。以下は Lambda で ALB ターゲットグループから対象インスタンスを登録解除する例です。
import boto3
TARGET_GROUP_ARN = "arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/app-tg/xxxx"
def handler(event, context):
instance_id = event["detail"]["instance-id"]
elbv2 = boto3.client("elbv2")
targets = elbv2.describe_target_health(TargetGroupArn=TARGET_GROUP_ARN)
for t in targets["TargetHealthDescriptions"]:
if t["Target"]["Id"] == instance_id:
elbv2.deregister_targets(
TargetGroupArn=TARGET_GROUP_ARN,
Targets=[{"Id": instance_id}]
)
return {"statusCode": 200}
登録解除後、接続ドレイン期間(deregistration_delay)が終了してからインスタンスが中断されるよう、ドレイン時間は 90 秒以内に設定します。
5-2. Graceful Shutdown の実装
Spot インスタンスが中断通知を受け取ってから 2 分以内に処理を完了するには、アプリケーションの graceful shutdown が不可欠です。
systemd を使ったサービスでは、TimeoutStopSec を 90 秒以内に設定し、SIGTERM を受信した際にコネクションのドレインと処理中タスクの完了を待ってからプロセスを終了するよう実装します。
# /etc/systemd/system/myapp.service の抜粋
[Service]
ExecStop=/usr/local/bin/myapp --graceful-shutdown
TimeoutStopSec=90
KillSignal=SIGTERM
コンテナワークロードでは、ECS タスク定義の stopTimeout を 90 秒以内に設定します。Kubernetes では terminationGracePeriodSeconds を同様に調整します。Spot 中断をテストするには AWS Fault Injection Service(FIS) の Spot 中断実験テンプレートを活用できます。本番環境で FIS を使って中断シナリオを再現し、graceful shutdown が正しく動作することを確認することを推奨します。
5-3. ASG と mixed instances policy による高可用設計
capacity-optimized 戦略と複数インスタンスタイプ
Spot の中断率を最小化するには、複数のインスタンスタイプから容量が最も潤沢なプールを選ぶ capacity-optimized 割り当て戦略が効果的です。3〜5 種類のインスタンスタイプを指定することで、特定のプールが枯渇した場合でも代替インスタンスタイプで起動できます。
mixed_instances_policy {
instances_distribution {
on_demand_base_capacity= 2
on_demand_percentage_above_base_capacity = 20
spot_allocation_strategy = "capacity-optimized"
}
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.app.id
}
override { instance_type = "m8g.large" }
override { instance_type = "m7g.large" }
override { instance_type = "c8g.large" }
override { instance_type = "m8g.xlarge" }
override { instance_type = "c8g.xlarge" }
}
}
Capacity Rebalancing
ASG の Capacity Rebalancing を有効にすると、AWS が中断リスクの高い Spot インスタンスを検知した段階で(中断前に)新しい Spot インスタンスを起動し、切り替えを試みます。AWS:EC2 Rebalance Recommendation イベントを利用する仕組みで、2 分前通知よりも早い段階で対応を開始できます。
resource "aws_autoscaling_group" "app" {
capacity_rebalance = true
instance_maintenance_policy {
min_healthy_percentage = 90
max_healthy_percentage = 110
}
}
On-Demand フォールバック設計
on_demand_base_capacity で一定台数をオンデマンドとして確保し、それ以上の台数を Spot で補う設計が標準です。on_demand_percentage_above_base_capacity を段階的に下げることで、Spot 比率を徐々に高めたリスク管理型の展開も可能です。
| 設定値 | 動作 |
|---|---|
on_demand_base_capacity: 2 | 最低 2 台はオンデマンドで確保 |
on_demand_percentage_above_base_capacity: 20 | 基底台数を超えた分の 20 % はオンデマンド、80 % は Spot |
spot_allocation_strategy: "capacity-optimized" | 容量が最も豊富なプールから Spot を選択 |
Spot ベースのキャパシティを効果的に活用するには、ステートレスなアプリケーション設計が前提です。セッション状態は ElastiCache や DynamoDB などの外部ストアに持ち出し、インスタンス交代による影響を最小化します。
6. Nitro System・専有・配置 — 基盤レイヤの設計

EC2 インスタンスの基盤を構成する Nitro System は、専用ハードウェアとハイパーバイザの分離により、インスタンスの性能と信頼性を高めます。本章では、Nitro System の特性・専有インスタンスの使い分け・Placement Group による配置最適化を解説します。
6-1. Nitro System の概要
Nitro System は AWS が独自開発した軽量ハイパーバイザとオフロードカードの組み合わせです。ネットワーク処理・ストレージ I/O・監視機能を専用の Nitro カードにオフロードすることで、ホスト CPU リソースをほぼ全量インスタンスへ割り当てられます。
Nitro ベースのインスタンスには次の特性があります。
- ベアメタルに近い性能: 従来ハイパーバイザのオーバーヘッドを排除し、仮想化インスタンスでもベアメタルと遜色のないパフォーマンスを実現します
- EBS 最適化デフォルト有効: Nitro ベースでは EBS 専用帯域が標準で有効になり、インスタンスタイプ別の最大 EBS スループットを発揮できます
- ENA(Elastic Network Adapter)対応: SR-IOV ベースのネットワークインターフェースにより、インスタンスタイプに応じた高帯域・低レイテンシのネットワーク性能を実現します
- Nitro Enclaves 対応: 一部の Nitro インスタンスは、CPU とメモリを完全に分離した信頼実行環境(Enclave)を作成できます
m5/c5 世代以降、ほぼすべての最新インスタンスファミリーが Nitro System を採用しています。インスタンスを選定する際は AWS 公式ドキュメントで Nitro 対応を確認してください。
6-2. Dedicated Hosts と Dedicated Instances
専有インスタンスには Dedicated Instances と Dedicated Hosts の 2 種類があります。両者の違いを理解して適切に使い分けることが重要です。
| 比較軸 | Dedicated Instances | Dedicated Hosts |
|---|---|---|
| 物理ホストの扱い | 同一アカウント内インスタンスのみ配置 | 指定した物理ホストを完全専有 |
| ホスト ID の固定 | 不可(再起動で変わることがある) | 可(同じホスト ID に再配置) |
| BYOL(ライセンス持込) | 対応困難(ソケット数が不明確) | 対応(ソケット数・コア数を明示的に把握可能) |
| 課金単位 | インスタンス単位 | ホスト単位(時間課金) |
| 用途 | コンプライアンス要件(テナント物理分離) | Oracle / Windows Server の BYOL |
Oracle Database のような「ソケット単位」ライセンスを持ち込む場合、Dedicated Hosts を使って物理ソケット数を明確にし、ライセンス数を最小化できます。ライセンス監査の際はホスト ID を証跡として記録しておくと便利です。Dedicated Hosts は aws_ec2_host リソースで Terraform 管理できます。
コンプライアンス要件で物理テナント分離が必要なケースでは Dedicated Instances で対応できます。ホスト単位の制御が不要な場合は Dedicated Instances の方がシンプルです。
6-3. Placement Group の設計
Placement Group は EC2 インスタンスの物理配置を制御する機能です。用途に応じて 3 種類を使い分けます。
Cluster Placement Group
同一アベイラビリティーゾーン内の隣接ラックにインスタンスを集約します。インスタンス間の通信レイテンシが最も低く、HPC や分散処理フレームワーク(Spark / MPI)のような低レイテンシ通信が必要なワークロードに適しています。単一ラック集約のため、ハードウェア障害時に全インスタンスが影響を受けるリスクがある点に注意が必要です。
Spread Placement Group
インスタンスを異なる物理ラックに分散配置します。ラック障害の影響を局所化できるため、本番の重要インスタンス(プライマリ DB・主要コンポーネント)の可用性向上に使います。1 グループあたり AZ 当たり最大 7 インスタンスという制約があります。
Partition Placement Group
複数の論理パーティションに分割し、各パーティションが専用の物理ラック群を使います。Spread と異なり、1 グループに数十〜数百台のインスタンスを配置できます。Hadoop / Cassandra / Kafka などの分散システムで、ノードをパーティション単位で配置するアーキテクチャに最適です。
resource "aws_placement_group" "kafka_cluster" {
name= "kafka-partition-pg"
strategy = "partition"
partition_count = 3
}
resource "aws_autoscaling_group" "kafka" {
name = "kafka-asg"
placement_group = aws_placement_group.kafka_cluster.name
vpc_zone_identifier = var.private_subnet_ids
min_size= 3
max_size= 9
desired_capacity = 6
}
| Placement Group | ユースケース | 制約 |
|---|---|---|
| Cluster | HPC・低レイテンシ通信 | 同一 AZ 内のみ・同一インスタンスファミリー推奨 |
| Spread | 重要インスタンスの分散配置 | AZ あたり最大 7 インスタンス |
| Partition | 大規模分散システム | 最大 7 パーティション / グループ |
EBS 最適化は Nitro 世代では標準で有効になりますが、インスタンスタイプごとに最大スループットが異なります。ストレージ集約型ワークロードでは、インスタンスタイプのドキュメントで EBS 最大帯域を確認してから選定してください。
7. EC2 Image Builder — ゴールデンAMIの自動化
7-1. イメージパイプラインとゴールデンAMI
EC2 Image Builder は、AMI の作成・検証・配布を自動化するマネージドサービスです。手動でインスタンスを起動してソフトウェアをインストールし AMI を作成する運用は、作業ミスや属人化を生みやすく、セキュリティパッチの適用漏れリスクも高まります。Image Builder を使うと、このビルドフローをコードで宣言してスケジュール実行できます。
主要コンポーネントの構成
Image Builder のパイプラインは 4 つの要素で構成されます。
| 要素 | 役割 |
|---|---|
| コンポーネント | ソフトウェアインストール・設定変更・テストスクリプトを YAML で定義 |
| レシピ | ベースイメージ + 複数コンポーネントの組み合わせを定義 |
| インフラストラクチャ設定 | ビルド用インスタンスタイプ・VPC・IAM ロールを定義 |
| イメージパイプライン | レシピ・インフラ設定・テスト設定を組み合わせ、スケジュールを設定 |
コンポーネントは build フェーズと test フェーズの 2 段階で記述します。build フェーズでパッケージをインストールし、test フェーズで期待する状態を検証します。テストが失敗した場合は AMI が作成されず、パイプライン全体が失敗として記録されます。
# コンポーネント例: Amazon CloudWatch Agent のインストール
name: CloudWatchAgentInstall
schemaVersion: 1.0
phases:
- name: build
steps:
- name: InstallCWAgent
action: ExecuteBash
inputs:
commands:
- |
yum install -y amazon-cloudwatch-agent
systemctl enable amazon-cloudwatch-agent
- name: test
steps:
- name: VerifyCWAgent
action: ExecuteBash
inputs:
commands:
- systemctl is-enabled amazon-cloudwatch-agent || exit 1
マルチリージョン配布の設計
ゴールデン AMI の配布設定では、対象リージョンと AMI の共有設定を記述します。東京リージョンで作成した AMI を大阪リージョンや他のリージョンへ自動コピーし、各リージョンの Auto Scaling グループが最新のゴールデン AMI を利用できる状態を維持します。配布設定には、AMI の暗号化有無やクロスアカウント共有の設定も含まれます。
バージョン管理の観点では、Image Builder は AMI ごとにバージョン番号を付与します。1.0.0、1.0.1 のように管理し、問題発生時は前バージョンへの切り戻しが容易です。AMI ID をハードコードせず、SSM パラメーターに最新 AMI ID を自動登録する設計が推奨されます。Launch Template の AMI 指定をこの SSM パラメーター参照にすることで、パイプライン完了後に Auto Scaling グループへ自動反映されます。
7-2. パッチ運用と IaC 統合
SSM Patch Manager との連携
Image Builder のパイプラインに UpdateOS アクションを組み込むと、ビルド時に OS パッチを自動適用した状態で AMI を作成できます。ただし、稼働中インスタンスへのスポットパッチ適用のみを目的とする場合は、SSM Patch Manager との使い分けが重要です。
| 用途 | 推奨アプローチ |
|---|---|
| 新規 AMI へのパッチ適用 | Image Builder + UpdateOS コンポーネント |
| 稼働中インスタンスへの緊急パッチ | SSM Patch Manager (Run Command / Maintenance Window) |
| ゴールデン AMI の定期更新 | Image Builder パイプラインをスケジュール実行(週次等) |
ゼロデイ脆弱性対応では、Image Builder で新しいゴールデン AMI を作成し、Auto Scaling グループの Launch Template を更新してインスタンスをローリング置換します。UpdateOS コンポーネントで reboot: true を指定すると、カーネルパッチが確実に適用された状態で AMI が作成されます。
Terraform 統合
# Image Builder パイプラインの Terraform 定義
resource "aws_imagebuilder_image_pipeline" "golden_ami" {
name = "golden-ami-pipeline"
image_recipe_arn = aws_imagebuilder_image_recipe.main.arn
infrastructure_configuration_arn = aws_imagebuilder_infrastructure_configuration.main.arn
schedule {
schedule_expression = "cron(0 2 ? * SUN *)"
pipeline_execution_start_condition = "EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE"
}
}
resource "aws_launch_template" "app" {
name_prefix= "app-"
image_id= data.aws_ssm_parameter.golden_ami.value
instance_type = "m8g.large"
}
data "aws_ssm_parameter" "golden_ami" {
name = "/aws/imagebuilder/image/golden-ami-pipeline/x.x.x/1"
}
pipeline_execution_start_condition を EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE にすると、スケジュール時刻になっても依存コンポーネントに更新がない場合はパイプラインを実行しません。不必要なビルドを防いでコストを抑制できます。
本番運用パターン: ゼロダウンタイム AMI 更新
- Image Builder パイプラインが成功し、新しいゴールデン AMI が作成されます
- パイプラインの SNS 通知を受け取った Lambda が Launch Template のデフォルトバージョンを更新します
- Auto Scaling グループのインスタンスリフレッシュを開始します (
MinHealthyPercentage: 90) - 旧世代インスタンスが順次置換され、新しいゴールデン AMI を使ったインスタンスに切り替わります
- CloudWatch アラームが異常を検知した場合はリフレッシュを一時停止して調査します
インスタンスリフレッシュには CheckpointPercentages を設定することで、全体の一定割合が新世代に移行した時点で一時停止し、動作確認できます。問題がなければ再開して、全インスタンスの更新を完了させます。
8. 詰まりポイント・アンチパターン・まとめ
8-1. 詰まりポイント(7 選以上)
現場でよく遭遇する運用上の問題と、根本原因・解決策を紹介します。
詰まり① Spot インスタンスが取れず Auto Scaling が失敗する
症状: ASG のスケールアウト時に「キャパシティ不足」エラーが発生し、インスタンスが起動しません。
原因: 単一インスタンスタイプまたは特定のアベイラビリティーゾーンのみを指定しているため、Spot プールが枯渇した際に代替手段がありません。
解決策: mixed instances policy で複数のインスタンスタイプ(例: m8g.large + c8g.large + m7g.large)を指定し、capacity-optimized 割り当て戦略を使います。3〜5 種類のインスタンスタイプを指定すると中断率・不足率が大幅に低下します。また、複数の AZ を ASG の対象にすることで、特定 AZ の Spot プール枯渇にも対応できます。
mixed_instances_policy {
instances_distribution {
on_demand_base_capacity= 1
on_demand_percentage_above_base_capacity = 0
spot_allocation_strategy = "capacity-optimized"
}
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.app.id
}
override { instance_type = "m8g.large" }
override { instance_type = "c8g.large" }
override { instance_type = "m7g.large" }
}
}
詰まり② ウォームプール有効化後もスケールアウトが遅い
症状: ウォームプールを設定したのに、スケールアウト時のインスタンス起動が依然として数分かかります。
原因: ウォームプール内インスタンスの初期化(アプリの起動・設定反映)がまだ完了していない状態でトラフィックを受け取っています。または、ウォームプールのサイズが不足しておりプールが空になっています。
解決策: ライフサイクルフックを使い、インスタンスが Warmed:Pending 状態にある間、初期化処理を完了させます。completeLifecycleAction を呼び出すまでインスタンスはウォームプールに留まるため、確実に初期化が終わった状態でプールに追加されます。ウォームプールのサイズは過去のスケールアウト量を参考に MaxGroupPreparedCapacity を設定します。
詰まり③ Graviton 移行後に AMI が起動しない・動作が不安定
症状: x86 向けの AMI をそのまま arm64 インスタンスで使おうとしてエラーになります。または、コンパイル済みバイナリが arm64 で動きません。
原因: x86_64 の AMI と arm64 の AMI は互換性がなく、アーキテクチャを跨いで同じ AMI を使うことはできません。また、ネイティブコンパイルした x86 バイナリも arm64 では実行できません。
解決策: Image Builder でベースイメージを Amazon Linux 2023 arm64 に変更し、arm64 向けのゴールデン AMI を別途作成します。アプリケーションが自前コンパイルのバイナリを含む場合は、CI で arm64 向けのビルドを追加します。コンテナを使っている場合は、--platform linux/arm64 でマルチアーキビルドを行い、linux/amd64,linux/arm64 のマニフェストリストを push します。
詰まり④ Auto Scaling の予測スケーリングが実際の需要に追いつかない
症状: 予測スケーリングを有効にしているが、週明け朝や月末バッチの時間帯にスケールアウトが間に合わずアクセス遅延を招きます。
原因: 予測スケーリングは 14 日分の過去データを学習するため、不定期なイベント(月次バッチ、大型セールなど)は予測できません。また、過去データが 14 日未満の場合は予測精度が低くなります。
解決策: 予測スケーリングと予定されたスケーリング(Scheduled Scaling)を組み合わせます。月末バッチや既知のイベントは Scheduled Scaling で事前にスケールアウトし、日常的な増減パターンは予測スケーリングに任せます。予測スケーリングは ForecastOnly モードでまず精度を確認してから ForecastAndScale に切り替えると安全です。
詰まり⑤ Spot 中断でバッチジョブが途中から再実行できない
症状: Spot インスタンスが中断されるとバッチジョブが最初からやり直しになり、処理時間が 2〜3 倍かかります。
原因: ジョブに進捗保存(チェックポイント)の仕組みがなく、再開時に処理済みのデータも再計算しています。
解決策: チェックポイントを S3 や DynamoDB へ保存し、ジョブ起動時はチェックポイントから再開するロジックを実装します。Spot 中断通知(2 分前に EventBridge で受信可能)を受け取り、中断直前のチェックポイントを保存するシャットダウンフックを設けます。バッチ処理の冪等設計(同じ入力で常に同じ結果になる)も合わせて実施します。
詰まり⑥ Nitro インスタンスで ENA ドライバが有効になっておらずネットワーク帯域が出ない
症状: Nitro 対応インスタンスタイプに移行したのに、期待したネットワーク帯域が出ません。または、インスタンスが起動しません。
原因: 古い AMI(例: Amazon Linux 1 や CentOS 7 系の古いカーネル)には ENA(Elastic Network Adapter)ドライバが同梱されていない場合があります。Nitro インスタンスは ENA を前提としており、ENA ドライバなしでは動作しません。
解決策: Image Builder のゴールデン AMI ビルドで ENA ドライバのインストールと ena_support 属性の有効化を確認するコンポーネントを追加します。Amazon Linux 2023 や最新の Ubuntu/RHEL 公式 AMI を使う場合は最初から ENA が有効です。既存 AMI の確認は aws ec2 describe-images --image-ids <ami-id> --query 'Images[].EnaSupport' で行えます。
詰まり⑦ Image Builder パイプラインが失敗したが原因がわからない
症状: パイプラインが FAILED で終わるが、コンソールに詳細なエラーが表示されません。
原因: Image Builder はビルド用の EC2 インスタンスを一時起動してビルドを実行するため、ログはそのインスタンスの CloudWatch Logs に出力されます。コンソールの概要だけではエラーの詳細が見えません。
解決策: パイプラインのインフラストラクチャ設定で CloudWatch Logs へのログ出力を有効にします。ロググループ /aws/imagebuilder/<pipeline-name> にビルドの詳細ログが出力されます。また、aws imagebuilder get-image コマンドでイメージの状態と statusReason を確認することで、フェーズ(build/test)とステップレベルのエラーを特定できます。
# パイプラインの失敗イメージ一覧確認
aws imagebuilder list-images \
--filters name=name,values=golden-ami-pipeline \
--query 'imageVersionList[].{version:version,arn:arn}'
詰まり⑧ T 系インスタンスの CPU クレジット枯渇で性能が低下する
症状: 通常時は快適に動いているのに、業務時間帯に CPU 使用率は高くないのに応答が遅くなります。
原因: T 系インスタンスはベースラインを超えた CPU 使用時に CPU クレジットを消費します。クレジットが枯渇するとベースライン(例: t3.medium なら 40%)以上の CPU が使えなくなります。CPUCreditBalance メトリクスを監視していないと気づきにくいです。
解決策: CloudWatch アラームで CPUCreditBalance が一定値を下回ったらアラートを発報します。T 系インスタンスを使う場合は unlimited モードを有効化するか(追加料金あり)、恒常的に高負荷なワークロードには最初から M 系(汎用・バーストなし)への切り替えを検討します。
詰まり⑨ cluster Placement Group でインスタンス追加時にキャパシティ不足が起きる
症状: cluster 型 Placement Group に後からインスタンスを追加しようとすると InsufficientCapacity エラーが発生します。
原因: cluster 型 Placement Group は単一ラック内に集約されるため、物理的なキャパシティ制約があります。後から大量に追加しようとすると空き不足が起きやすいです。
解決策: 初回に必要な最大台数を一括起動し、一度全台停止してから再起動すると同一ラックに再配置されやすくなります。インスタンスのサイズ変更や追加が多い場合は partition 型を検討します。HPC 向けの密結合通信が不要なら spread 型や配置なしのほうが柔軟です。
8-2. アンチパターン → 正解変換(5 選以上)
現場でよく見かける誤った設計と、推奨する正しいアプローチを示します。
アンチパターン① 旧世代インスタンスを固定で使い続ける
| 内容 | |
|---|---|
| アンチパターン | コスト最適化や移行リスクを嫌い、インスタンスタイプを何年も変えない |
| 問題 | 性能・コスト面で著しく不利。m5.xlarge と m8g.xlarge では同価格帯で Graviton4 が大幅に高性能 |
| 正解 | 四半期ごとに最新世代の性能ベンチマークを実施し、定期的にインスタンスファミリーを更新する |
| 実践 | Launch Template のバージョン管理と Image Builder を組み合わせ、ゴールデン AMI 更新のついでにインスタンスタイプも最新世代へ移行する |
アンチパターン② 可変負荷なのに全インスタンスを On-Demand で固定運用する
| 内容 | |
|---|---|
| アンチパターン | Spot 中断を恐れて On-Demand のみで ASG を構成する |
| 問題 | ベースライン以上の負荷に On-Demand で対応するとコストが最大 70〜90% 高くなる |
| 正解 | On-Demand をベースライン(例: 2 台)に固定し、スケールアウト分を Spot で補完する on_demand_base_capacity 設計 |
| 実践 | mixed_instances_policy で on_demand_base_capacity = 2、on_demand_percentage_above_base_capacity = 0 とし、スパイク分は Spot が担う |
アンチパターン③ AMI を手動で作成・管理する
| 内容 | |
|---|---|
| アンチパターン | 担当者が手動でインスタンスを起動し、ソフトウェアをインストールして AMI を作成する |
| 問題 | 作業ミスによる設定漏れ、セキュリティパッチ適用忘れ、作業記録の欠如、属人化 |
| 正解 | EC2 Image Builder でパイプラインをコード化し、スケジュール実行で常に最新のゴールデン AMI を維持する |
| 実践 | Terraform で Image Builder パイプラインを管理し、AMI ID は SSM パラメーターストアで Launch Template に連携する |
アンチパターン④ Graviton 移行でテストをスキップして本番に投入する
| 内容 | |
|---|---|
| アンチパターン | x86 で動いていたから arm64 も大丈夫だろうと考え、ステージング環境のみで動作確認して本番へ投入する |
| 問題 | x86 固有のコードパス、ネイティブ拡張ライブラリ、バイナリ互換に依存した処理が arm64 で失敗するケースがある |
| 正解 | CI パイプラインに arm64 向けのビルド・テストジョブを追加し、x86 と arm64 を同時に検証した上で移行する |
| 実践 | GitHub Actions / CodeBuild で arm64 向けジョブを並走させ、テストが両アーキで通ることを確認してから本番切り替えをする |
アンチパターン⑤ 単一 AZ 配置で Spot + ASG を運用する
| 内容 | |
|---|---|
| アンチパターン | コスト比較やネットワーク設定の簡素化を理由に ASG の対象 AZ を 1 つだけに限定する |
| 問題 | AZ 内の Spot プールが枯渇したり、AZ 障害が発生したりすると ASG のスケールアウトが完全に止まる |
| 正解 | 最低 2 AZ(本番推奨は 3 AZ)を ASG の対象にし、Spot は複数のインスタンスタイプと複数の AZ で分散確保する |
| 実践 | availability_zones に複数 AZ を設定し、capacity-optimized-prioritized を使うことで実際に取れる可能性が高いプールを優先させる |
アンチパターン⑥ Launch Template を直接更新しブルーグリーン切り替えをしない
| 内容 | |
|---|---|
| アンチパターン | Launch Template のデフォルトバージョンを更新した後、既存インスタンスが置き換わるのを自然消滅(スケールイン)に任せる |
| 問題 | 旧世代と新世代が長期間混在し、動作不整合やロールバック困難な状態が続く |
| 正解 | インスタンスリフレッシュ(StartInstanceRefresh)を使って計画的に段階置換し、問題発生時はリフレッシュをキャンセルして旧バージョンに戻す |
| 実践 | MinHealthyPercentage: 80〜90、CheckpointPercentages: [20, 50, 100] で段階的に確認しながら更新する |
8-3. まとめと Vol2 予告
本記事では、Amazon EC2 を本番のコンピュート基盤として設計・運用するための主要テーマを解説しました。
Vol1 で学んだこと
インスタンスタイプ選定: ワークロード特性(汎用/コンピュート最適化/メモリ最適化/バースト)に合わせたファミリーと世代の選び方。Graviton4(
m8g/c8g/r8g)を含む最新世代が性能・コスト面で有利なことを確認しました。Auto Scaling 戦略: Launch Template、動的スケーリング(ターゲット追跡)、予測スケーリング(パターン学習による事前スケールアウト)、ウォームプール(初期化済みインスタンスの待機プール)の設計方針を押さえました。ライフサイクルフックで初期化タイミングを制御することが、応答性能安定の鍵です。
Graviton 移行: arm64 アーキテクチャを本番コンピュート基盤に採用するための互換性確認・マルチアーキビルド・性能ベンチマークの進め方を解説しました。コスト削減 ROI の体系的な分析は Vol2 で扱います。
Spot 活用: 中断耐性のあるコンピュート基盤設計として、mixed instances policy・capacity-optimized 割り当て・Capacity Rebalancing・チェックポイントによる再実行耐性を解説しました。
Nitro System と配置: Nitro System の専用ハードウェアによる性能・セキュリティ特性、Dedicated Hosts のライセンス活用、Placement Group の用途別選択(cluster/spread/partition)を整理しました。
EC2 Image Builder: ゴールデン AMI のパイプライン自動化、コンポーネントによるテスト組み込み、SSM Patch Manager との連携、Terraform 統合、インスタンスリフレッシュとの組み合わせによるゼロダウンタイム AMI 更新の本番運用パターンを解説しました。
これらを組み合わせることで、需要変動に追従しながらも安定したコンピュート基盤を構築できます。
Vol2 予告: コスト最適化とコンピュート購入戦略
Vol2 では、EC2 のコスト最適化に焦点を当てます。Reserved Instances と Savings Plans の設計(コミットメント期間・支払いオプションの選択)、Spot Fleet の本番運用、Graviton をコスト削減の購入オプションとして選択する ROI 分析、Right Sizing による継続的最適化の方法論を体系的に解説する予定です。
EC2 コンピュート基盤の設計・運用では、インスタンス選定・スケーリング・ゴールデン AMI 管理が三本柱です。次は購入オプションとコスト最適化を Vol2 で体系化しましょう。
クロスリンク
コスト最適化 Vol2:RI×Spot×Graviton×Right Sizing を読む
Container本番運用 Vol1:ECS × Fargate × ECR (コンテナ実行基盤との対比) →
Container本番運用 Vol3:EKS縦深化 (EKS NodeのEC2基盤設計) →
Serverless本番運用 Vol1:Lambda × API Gateway × Step Functions (サーバーレスとの使い分け) →
Step Functions:Distributed Map で大規模並列処理を設計する
AWS Systems Manager:Patch Manager・Session Manager・パラメーターストア運用