AWSのCloudWatchとAutoScallingを使用し、EC2インスタンスのCPU使用率が規定値を超過したらインスタンスを新しく立てるという検証をしていた際の失敗事例を記載します。
CloudWatchとAutoScallingの仕組み
それぞれの仕組みはこんな感じ。
CloudWatch は、AWS とオンプレミスで実行される AWS のリソース、アプリケーション、およびサービスを統括的に把握することができるように、ログ、メトリクス、およびイベントという形式でモニタリングデータと運用データを収集し、それらを自動化されたダッシュボードを使って可視化します。
ユーザーが指定するメトリック値のしきい値に基づいたアラーム、または機械学習アルゴリズムに基づいて異常なメトリック動作を監視するアラームを作成することも可能です。
つまり、AWS上で動かすものを監視して、アラーム発砲ができるサービスみたいな感じです。
AWS Auto Scaling は、安定した予測可能なパフォーマンスを可能な限り低コストで維持するためにアプリケーションをモニタリングし、容量を自動で調整します。AWS Auto Scaling を使用すると、複数のサービスにまたがる複数のリソースのためのアプリケーションスケーリングを数分で簡単に設定できます。
つまり、ユーザーが設定した範囲内でリソースを自動調整してくれるサービスみたいな感じです。
上記2つを組み合わせることで、リソースのある値が設定した閾値を超過した場合に、リソースを自動調整する仕組みを構築することができます。
発生した事象
今回の検証では、以下の2パターンの条件で実施していました。
【パターン①】
・EC2インスタンスのCPU使用率が70%を超えたら新しくインスタンスを立てる
・その際のインスタンス上限数は4つ
【パターン②】
・EC2インスタンスのCPU使用率が30%を下回ったらインスタンスを1つ削除する
・その際のインスタンス下限数は2つ
EC2インスタンスに以下のコマンドで負荷をかけました。
yes >> /dev/null &
その際、CPU使用率が70%を超え、新しくインスタンスが起動してきたことを確認しました。
ずっと負荷をかけ続けていたので、4つまで自動でインスタンスが増えることを想定していました。
しかし、実際には以下の画像の通り、5個のインスタンスが起動してしまいました。
上限の設定を間違えたかなと思い確認してみるも、きちんと4つに設定されていました。
CloudWatchとの連携がおかしいのかと思い、とりあえず負荷をかける作業を中断。
すると、パターン②の方は問題なくクリアできていることが確認できました。
原因
この事象の原因は、AutoScallingのヘルスチェック機能の時間を短く設定してしまっていたことでした。
この機能は、EC2インスタンスが正常に起動しているか確認するためのものです。
AutoScalling設定の際に、猶予時間を設定する項目があるのですが、
こちらを短く設定してしまっていたためにこの事象が起きていたと考察しています。
猶予時間とは、インスタンスやサービスが起動し終わるまで、ヘルスチェックに失敗してもOKというものです。
デフォルトでは5分となっているのですが、検証でそんなに待ちたくない!という超絶短気な思考になってしまい、結果的にこんな事態を引き起こしてしまいました。
発生した経緯を推測すると、
・インスタンスのCPU使用率が70%以上になった(この時のインスタンス数3)
・ヘルスチェックを実施し、起動しているor起動中のインスタンス数が4つ以下のため新たなインスタンスを起動(インスタンス④)
・インスタンス④起動中にヘルスチェックが実施される
・猶予時間を過ぎているため、起動完了していない状態がエラー状態となりトリガー発砲
・新たなインスタンスを起動(インスタンス⑤)
みたいな感じで上限を超えて増えていってしまったものと思われます。
ヘルスチェックの猶予時間はデフォルトのままいじらないのがよいというのが今回の学びでした。