LoginSignup
2
3

More than 5 years have passed since last update.

スポットインスタンスのTerminate時に、自動でECSクラスタからDeregisterする

Last updated at Posted at 2018-10-16

ECSとスポットインスタンスは相性がよく比較的多くの場所で推奨されていますが、そのままでは強制Terminate時にきれいにECSクラスタを抜けられないことはあまり良く知られていません。(構築・運用したことがある人はすぐに気づきますが)
今回は簡単な説明と具体的な対応を書いています。

なぜ対応が必要なのか

スポットインスタンスが強制Terminateされる時に適切な処理が行われていないと下記のような事象が発生します。なので、プロダクションで利用する際は対応はほぼ必須かと思います。

  • 該当インスタンス上のコンテナがELBから接続されている場合に、Drainingされずに停止されていしまう。
    • Drainingされなかったリクエストが503 Errorとなる。
    • 状況によっては十分な数のコンテナが存在しない時間帯が発生する。

どんな対応が必要なのか

公式ドキュメントにも記載がありますが、基本的には コンテナインスタンスの登録解除 をすることにより、下記作業が行われます。

  • 該当インスタンス上で可動しているコンテナのELBからのDraining
  • 該当インスタンス上で可動しているコンテナの、他インスタンスへのオフロード。

また、2分あれば十分かと思いますがELBのDrainingの許容時間なども合わせて見直したほうがいいかと思います。

ただ、自分で設定するのはめんどくさい、、ので今回はCloudFormationのテンプレートを用意しました。

CloudFormation テンプレート

https://github.com/mats16/ecs-spot-deregister
基本的にはこちらのテンプレートを実行してすればOKです。(リージョン毎に設定されるので、ECSをお使いのリージョンでCFnを実行してください)

基本的には構成図のとおりですが下記のようなことを行っています。

  1. CloudWatch Eventsで強制Terminationの2分前通知を検知
  2. Lambda Functionを実行
  3. Lambda内からAPIを叩き、該当インスタンスをECSクラスタからDeregisterする

ecs-spot-deregister.png

中のコードを見ていただければわかりますが、instance_idからcluster_namecontainer_instance_idを直接参照できるAPIが無いので、やや微妙な書き方になっています。

あとがき

本投稿は、個人の意見であり、所属する企業や団体は関係ありません。お約束です。
久しぶりにpython書いたのでご指摘や機能要望があれば、PullRequestやIssue頂ければと思います。
(SNS挟んだほうがいいとか、Slackに通知したいなど)

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3