@ijin

[Michael H. Oshita]

Auto Scalingの設定とデプロイ方法

CDP Advent Calendar 2012に登録しました。ここ1年ちょいで使い慣れてきたパターンがあり、作った当時はクラウドデザインパターンはなかったのですが、Clone ServerScale Outパターンの組合せに当てはまると思うので紹介します。ちなみにアプリはRails。

常にデプロイして更新し続けるシステムを手動、あるいは自動スケールアウトする時に便利な手法だったりします。

図にするとこんな感じですかね。

Auto Scaling設定

Launch Config

まず、ベースとなるAMIの起動インスタンスサイズやセキュリティーグループを定義したLaunch Configを設定。

as-create-launch-config cdp-lc --image-id ami-22a51d23 --instance-type m1.small \
--group cdp_web, cdp_admin

Scaling Group

次に、Scaling Groupで適用するAvailability Zone、インスタンス数の最小・最大閾値設定、紐尽くELB、死活監視方法・開始待ち時間、タグ等を定義。(ec2addtagではスペース入りのキーを設定できるのにas-create-auto-scaling-groupではできないので注意。早く直して。。)

as-create-auto-scaling-group cdp-sg --launch-configuration cdp-lc \
--availability-zones ap-northeast-1a  --min-size 1 --max-size 9 --load-balancers cdp \
--health-check-type ELB --grace-period 300 --tag "k=Name, v=web.cdp" --tag "k=Use_Case, v=Test"

Scaling Out Policy

Scaling Outのポリシー設定。以下の例ではインスタンス1台を追加し、次のスケールアクションまでは5分間待機。ポリシーのARN (Amazon Resource Name)が出力されるので控えます。

as-put-scaling-policy CDPOut --auto-scaling-group cdp-sg --adjustment 1 --type ChangeInCapacity \
--cooldown 300

> arn:aws:autoscaling:ap-northeast-1:494850320039:scalingPolicy:d0d4dcf1-fb44-428a-a19c-38946633acf5:autoScalingGroupName/cdp-sg:policyName/CDPOut

Cloudwatchトリガー(Scaling Out)

Cloudwatchで閾値を超えたらスケールアウトするように設定。以下の例では対象Scaling Group配下のインスタンス達のCPUが1分間で平均75%以上で推移した場合、先ほど設定したScaling OutポリシーがARN経由で実行されます。また、閾値を超過あるいは下回った場合にSNS経由でアラートメールを飛ばします。

mon-put-metric-alarm  CDPHighCPUAlarm --comparison-operator GreaterThanThreshold \
--evaluation-periods 1 --metric-name CPUUtilization --namespace "AWS/EC2" --period 60 \
--statistic Average --threshold 75 --dimensions "AutoScalingGroupName=cdp-sg" \
--ok-actions arn:aws:sns:ap-northeast-1:494850320039:cdp-alert --alarm-actions \
arn:aws:sns:ap-northeast-1:494850320039:cdp-alert, arn:aws:autoscaling:ap-northeast-1:494850320039:scalingPolicy:d0d4dcf1-fb44-428a-a19c-38946633acf5:autoScalingGroupName/cdp-sg:policyName/CDPOut

Scaling Down Policy

同じくScaling Downのポリシー設定。インスタンスが起動すると最低1時間は課金されるので頻繁に伸縮するともったいないのでスケールダウンアクションはゆっくりやるのがポイントです。

as-put-scaling-policy CDPDown --auto-scaling-group cdp-sg --adjustment=-1 \
--type ChangeInCapacity --cooldown 1500

> arn:aws:autoscaling:ap-northeast-1:494850320039:scalingPolicy:de53fbd5-130c-46a8-bf47-25e29f7d358e:autoScalingGroupName/cdp-sg:policyName/CDPDown

Cloudwatchトリガー(Scaling Down)

スケールダウンのトリガーは平均CPUが35%を25分間下回った場合に実行されます。この閾値周辺のアラートメールはいらないので設定してません。

mon-put-metric-alarm CDPLowCPUAlarm --comparison-operator LessThanThreshold \
--evaluation-periods 1 --metric-name CPUUtilization --namespace "AWS/EC2" --period 1500 \
--statistic Average --threshold 35 --dimensions "AutoScalingGroupName=cdp-sg" --alarm-actions \
arn:aws:autoscaling:ap-northeast-1:494850320039:scalingPolicy:de53fbd5-130c-46a8-bf47-25e29f7d358e:autoScalingGroupName/cdp-sg:policyName/CDPDown

通知

最後にスケールアクション時に通知が飛ぶように設定。例えば、あるインスタンスが不調により反応がなく、ポリシーによってリプレースされる場合に飛んだりします。

as-put-notification-configuration cdp-sg -t arn:aws:sns:ap-northeast-1:494850320039:cdp-alert \
-n autoscaling:EC2_INSTANCE_LAUNCH, autoscaling:EC2_INSTANCE_TERMINATE, \
autoscaling:EC2_INSTANCE_LAUNCH_ERROR, autoscaling:EC2_INSTANCE_TERMINATE_ERROR

APP側の設定

ソースコード同期

同期には起動時にupstart経由でrsyncを叩いて管理サーバから最新ソースを取ってきてサービスを再起動します。転送時の圧縮モードはarcfourが一番スループットが出たのでそれに。

Capistrano

デプロイはマスターサーバ(管理兼)上でCapistranoを実行し、ELB配下の生きているインスタンスに対して更新をかけます。deploy.rbに追加する記述は以下の通り。昔はec2 api toolsを直接呼んでパースしたりしてコードが長かったのですが、今はAWS SDK for Rubyがあり、IAM roleでinstance profileを設定すればわずか数行でできてしまいます!

1
2
3
4
5
require 'aws-sdk'
AWS.config(:ec2_endpoint => 'ec2.ap-northeast-1.amazonaws.com', :elb_endpoint => 'elasticloadbalancing.ap-northeast-1.amazonaws.com')
instances = AWS::ELB.new.load_balancers['cdp'].instances.select{|i| i.exists? && i.elb_health[:state] == "InService"}.map(&:public_dns_name)
servers = instances << "localhost"
role :app do servers end

注意点

  • 同期するファイル数が多すぎる(数十万個)と、チェックサム比較で時間がかかってしまい同期が終了する前にAuto Scalingの死活監視によってインスタンスがterminateされ、またlaunchされterminateされるという恐怖のスケールループ地獄に陥る。。。(これ、制限できないのかな)
  • あらかじめトラフィック増の時間帯が分かっていたらScheduled Actionで多めに設定しておいて自動スケールダウンさせた方が吉。
  • マスタサーバがSPOFとなりうるので冗長化する、もしくはrsyncよりs3経由にした方が良い。
  • 急激なトラフィック増ではELB自体のスケールが追いつかない場合も。

Comments