はじめに

AutoScaling(面倒なので以下AS)を使って気づいたことをまとめました。上手に作るととても便利な機能です。「イベントあるからインスタンス増やして!」といわれてても、数字を増やすだけでインスタンスが勝手に増えてくれます。また、リソースが足りなくなった場合もASが自動にインスタンスを追加することも出来ます。
ただし、いろいろ気をつけるべき点もありました。今回はその点についてまとめてみました。書いてみたら長くなってしまったので、手順等はありません。使ったことがない方が雰囲気を感じてもらうか、一度つかってみた方が「なるほど」もしくは「あるある」とおもってもらえればとおもいます。間違っていることを書いていれば教えてもらえると嬉しいです。

インスタンスは起動停止ではなく作成削除

使ったことがある人にはあたり前なのですが、ASはインスタンスを起動/停止するのではなくて、作成、削除します。必要となったらASがインスタンスを作成し、必要がなくなったら、インスタンスはASによって消されてしまいます。ポイントとなるのは、初期化と終了時処理です。

インスタンス初期化

インスタンス起動してサービスができるようになるためには、サービスの起動だけではなくてコンテンツの設定や、監視設定等が必要です。

コンテンツについては、AMIのイメージが常に最新ということであれば手間がかからず楽なのですが、常時更新されるコンテンツがある場合は難しいです。ファイルサーバにファイルをおいて同期するという方法が考えられますが、同期のコンテンツが大量にあって、かつ、多数のインスタンスが起動した場合、ファイルサーバがボトルネックになりえます。S3に同期用のデータを置いておくというのも案の一つですがファイルが大量の場合、APIスロットリングが心配です。

  • できるだけAMIを最新に保つ仕組みを用意する
  • 同期があまりおきないような仕組みにする
  • ファイル同期については、同期コンテンツ量、同時起動数を考慮する

監視

nagiosを使う場合、自動の登録/削除に対応していないので、この部分の仕組みを作る必要がありました。zabbix,sensu等であれば自動登録に対応しているとのことです。監視については既存の仕組みがあることも多いですし。ASへの移行が難しいかもしれませんので確認が必要です。

性能監視

インスタンスは使い捨てなので数時間しか生存しないインスタンスが大量に発生する可能性があります。ホスト名ベースで管理する場合性能監視をどうする? という 問題がありました。

幾つか方法を検討しました(他にもあれば教えてください)。

  • タグでロール名をつけて、ロール毎に、合計CPU使用率や合計Apacheリクエスト数といったパラメータで管理する
  • ベースとなる固定サーバを用意し、ASのインスタンスと同じELBにつなげておきそのサーバを基準に管理する

インスタンス削除

ASはインスタンスを必要としなくなると削除します。このためログ等については事前に退避しておく必要があります。もしくは、fluentdのような仕組みで常にログを転送するようにします。

また、監視等のサービスを利用している場合は登録を解除する必要があります。以下のような方法があります。

  • Life cycle hooks を利用してインスタンス停止処理時に削除設定を実施
  • 定期的にモニタリングプログラムを実行し、存在しなければ削除

定期的な実行だとインスタンスが異常終了したのか、ASで終了したのかわからないアラートがあがってしまうため、Life cycle hooks を利用して停止時に終了処理を実行する方法を選択しました。

課金は1時間単位

EC2ですので当然課金は1時間単位です。ASの設定を間違えると、

  1. ASからEC2インスタンス起動
  2. EC2の起動処理が失敗してターミネート
  3. 1に戻る

というループを繰返す場合がありました。1回起動すれば1時間課金なので、この失敗に気づかないと恐ろしい事になりますので気をつけてください。防ぐ方法もいろいろあります。

設定が正しく出来た場合でも1時間単位の課金という点を考慮するとスケールアウトをした場合は1時間程度はたちあげっぱなしにしても費用はかわりません。このため、分単位で負荷がかわったとしても、スケールアウト/スケールインが頻繁におこらないようにする設定を行なう必要があります。

そういえば、今回はOSSの利用でしたが、商用ライセンスによってはASに対応していないものがあるかもしれませんので確認しないといけませんね。時間課金だと嬉しいのですが。

ELBを複数使う場合の注意点

ASはヘルスチェックとしてEC2とELBが利用可能です。WebサービスであればELBにするのが通常かとおもいますが、複数ELBにインスタンスをつなげる場合、気をつける点があります。

インスタンスがELB AとELB BにつながっているとしてELB Aのヘルスチェックが失敗したとします。インスタンスはELB Bにはサービスができているのですが、ASはこのインスタンスを削除して新しいインスタンスを起動します。ということでELBのヘルスチェックはあまり敏感にしないほうがよいです。

詳細モニタリング必須

ASのインスタンスではCloudwatchの詳細モニタリングが有効になります。有料ですが、1インスタンスあたり1日20円程度とかんがえれば気にする必要はないとおもいます。個人的にはASでなくとも詳細モニタリングおすすめします。

AutoScalingのレスポンス

ASのdesired capacity(希望するインスタンス数)を変更した場合、ASのイベントが発生するまで数十秒から2分程度かかるようです(計測ではなく感覚による)。 EC2のインスタンスの起動はこれまた数分かかり、(ヘルスチェック依存しますが)ELBへの接続に数分かかるので5-10分程度は起動にかかるイメージです。

Cloudwatchのalarmを利用してASを発動させる場合はさらに数分かかります。

利用する前は、瞬時にたちあがるというASのイメージをもっていました。アプリケーションの初期化が複雑であれば当然もっと時間がかかりますし、意外と時間かかるなというのが使った印象でした。
ただ、以前の手作業を考えるとはるかに早いです。

StandbyとDetachの違い

ASからインスタンスを一時的にはずすStandbyとDetachという機能があります。Standbyは、Standby状態をexitすると元のASに戻りますが、Detachは、明示的にASを指定して戻す必要があります。

メンテナンスや調査時に一時的にStandby状態にするということができるので便利です。これをせずにApacheをとめて、ELBのヘルスチェックがはしり折角更新したインスタンスがターミネートされるという悲劇が発生します。

デタッチうまくつかうと、ASが複数(AS1,AS2,AS3)あったとして、AS1が負荷高いから、AS3からデタッチしてAS1に足すというようなことに使えるのかもしれません。

RDBはAutoScalingしてくれない

アプリケーションサーバのEC2を増やしてもデータベースがボトルネックの場合だと意味がないです。いまのところRDBをASで実現する仕組みはAWSにはないです。RDBではないですがDynamoを使う、もしくは、分散データベースを自身でスケールアウトさせるという方法があるかもしれません。Auroraも期待できるでしょうか? ここは今後の課題です。

ELBの暖気は必要

アプリケーションサーバのEC2を増やしてもロードバランサーがリクエストを捌いてくれないと意味がないですね。徐々に負荷が増えるパターンであれば問題ないですが、イベント等で急にアクセスが増える場合は、事前に自身で大量アクセスをするか、暖気申請が必要です。

AutoScalingを使うべき状況

  • インスタンスの作成/削除の自動化が簡単にできる
  • 負荷の変動が数時間、もしくは、日中/夜間のような範囲で大きく変化する
  • イベント等、決まった時間に大量のアクセスが発生する

現場からは以上です。

元記事はこちらです。
AutoScalingを使って気づいたこと