AWS ASG 複数 Scaling Policy 併用時の scale-in は AND にならない(Simple Scaling の罠)
TL;DR
- Target Tracking の複数ポリシーは scale-in が AND 動作(全ポリシーが合意した時のみ縮退)
- Simple Scaling の複数ポリシーは scale-in が 独立発火(各アラームが個別に scale-in を実行)
- CPU と Passenger メトリクスを Simple Scaling で併用した結果、Passenger で scale-out した直後に CPU low が独立して scale-in し、増設インスタンスが即削除された
背景
EC2 Auto Scaling Group に CPU ベースの Simple Scaling(既存)と Passenger ActiveProcesses ベースの Simple Scaling(新規)を併用する構成を検討していた。
事前調査で AWS ドキュメントの以下の記述を見つけた:
Amazon EC2 Auto Scaling chooses the policy that provides the largest capacity for both scale out and scale in.
これを「scale-in は AND(両方のメトリクスが低い時のみ縮退)」と解釈していたが、誤りだった。
実際の動作
AWS ドキュメントの正確な意味
Dynamic scaling for Amazon EC2 Auto Scaling の記述は「複数ポリシーが同時に発火した場合の調停ルール」:
- 同時に発火した場合 → 台数を多く残す方(保守的な方)を採用
- 片方だけ発火した場合 → そのまま独立実行(もう一方のメトリクスは参照しない)
staging で再現した事象
| 時刻 (UTC) | イベント | desired | トリガー |
|---|---|---|---|
| 08:18 | scale-out | 1→2 | passenger-active-high ALARM |
| 08:24 | scale-out | 2→3 | passenger-active-high ALARM |
| 08:30 | scale-in | 3→2 | cpu-utilization-low ALARM |
| 08:36 | scale-in | 2→1 | cpu-utilization-low ALARM |
Passenger が必要と判断して増設した 2 台が、CPU low により 6 分後・12 分後に削除された。
ポリシータイプ別の scale-in 動作
| ポリシータイプ | scale-out | scale-in |
|---|---|---|
| Target Tracking(複数) | いずれかが閾値超え → 発火(OR) | 全ポリシーが合意した時のみ(AND) |
| Simple Scaling(複数) | 各アラームが独立発火(OR) | 各アラームが独立発火(OR) |
Target Tracking は AWS が内部的にアラームを管理するため AND 動作が組み込まれている。Simple Scaling は CloudWatch アラームが独立しており、相互に状態を参照しない。
対応策
案 A: scale-in を片方のメトリクスに一本化(採用)
CPU low アラームから scale-in アクションを除外し、scale-in は Passenger のみにする。
scale-out: CPU high OR Passenger high(どちらかで増設)
scale-in: Passenger low のみ(アプリ負荷がない時だけ縮退)
Passenger プロセスが低い = アプリが負荷を感じていない = 安全に縮退可能。
案 B: Lambda + DynamoDB で AND ロジックを自作
darkraiden.com の記事 で紹介されている「Sigmund」方式。DynamoDB に各メトリクスの状態を保存し、両方 low になった時だけ Lambda が scale-in API を呼ぶ。正確だが複雑。
案 C: Composite Alarm → ASG(不可)
CloudWatch Composite Alarm で AND 条件を作り ASG アクションに紐づける方式は ValidationError で不可。ASG の scaling policy は Composite Alarm をサポートしていない。
教訓
- AWS ドキュメントの「largest capacity を選ぶ」は同時発火時の調停であり、AND 条件ではない
- Simple Scaling で複数メトリクスを併用する場合、scale-in の独立発火を考慮した設計が必要
- Target Tracking なら scale-in は AND 動作するが、Simple Scaling とは混在できない制約がある