ECS on EC2での話です。
結論
- ECSのスケールインはマルチAZを優先にスケールインさせる
- ECSのスケールインは条件によってはEC2の削除保護を無視してスケールインされる
- インスタンスタイプ選択時は立てれるアベイラビリティゾーンは確認しよう
再現方法
簡略化させて発生させる再現手順を記載します。
- アベイラビリティゾーンに偏りがある状態でECSのEC2インスタンスを管理する
- 片側のアベイラビリティゾーンだけを対象にEC2の削除保護を設定する
- ECS(CloudformationもしくはAuto Scalingで)の最大台数を減らす
- 削除保護されたEC2がterminatedになる
手順はわかったところで、スクショを交えて手順の説明の実施と再現させます。
ECSインスタンスの状況
まずは前提となる状況を作り出します。
ECSのアベイラビリティゾーンの設定
ECSのアベイラビリティゾーンを2つとします。今回はcとd。
ECSインスタンス達
アベイラビリティゾーンを2ゾーンしか設定していなければ、奇数台数のインスタンスを立てれば偏りが出ます。
このインスタンス達の 削除保護 の状態はこんな感じに片側だけ保護するようにする。
スケールインの実施
ここはCloudformationを変更してもいいし、Auto Scalingグループの変更でもどっちでもいいですが、最大台数を落とします。
今回は3台→2台への変更とします。
すると、あら不思議!削除保護したインスタンスがterminatedになる。
実業務で発生した状況
グダグダ書きましたが、私自身が実際に起きた状況は以下です。
前提条件
- 該当のECSの アベイラビリティゾーンはaおよびc しか設定されていない
状況
- EC2インスタンスタイプを変更するために最大台数(2→4)とEC2インスタンスタイプを R5a に変更する
-
R5aは現状アベイラビリティゾーンaとdしか対応していない ため今回はaに偏って立つ
→この時点で状況を理解していたが、 気にせず次のオペレーションを実施した が最大のミス - 作成された新インスタンスの削除保護を実行
- 旧インスタンスに乗っているコンテナのdrainingを開始
- 旧インスタンスに乗っているコンテナがないことを確認後、Cloudformationで最大台数を戻す(4→2)
- 旧インスタンスの1台はdrainingにも関わらず、アベイラビリティゾーンcであるがゆえに残されて、新インスタンス1台がterminatedになる
- 晴れてterminatedとなった新インスタンスで動いていたコンテナ達は無情にも落とされて、サービスダウンとなる😭
正直ここからサービス復旧には30分もかかってないけど(長いと見るか短いと見るかは人それぞれだが、私に長い)、まぁ落ちたのは凹んだ。
最悪なのはECSのCloudformationのアベイラビリティゾーンの設定にdを足しても復旧しなかった。理由はアベイラビリティゾーンdに立ったインスンタンスでコンテナが立ち上がってもALBからのヘルスチェックが通らなかったため。
なぜならECSだけでなく、ALBのアベイラビリティゾーンもdの設定がなかったためです。
急遽ALBにもアベイラビリティゾーンdを足してコンテナを立ち上げたけど、時すでに遅し。
最後に
ECSのすべての動作を理解できてなかった検証不足と今後このような悲劇を生み出さないようにと自分への戒めとしてこの記事を書きました。