電子の密林を開拓する

タグ:SNS

今回は CloudWatch の Alarm を CLI 経由で設定します。


・負荷をかける対象のEC2インスタンスを作成する
GUIでCloudWatchのAlarmを設定した記事でやったように、sysbench というコマンドで負荷をかけてみます。
AmazonLinux では sysbench が yum でインストールできるパッケージに含まれていないので、負荷対象として 新規に Ubuntu を OS とする EC2を起動します。
$ ec2-run-instances  \
     ami-20ad1221 \
     --group web  \
     --key innerkey  \
     --instance-count 1  \
     --instance-type t1.micro  \
     --instance-initiated-shutdown-behavior stop

RESERVATION     r-15841f16      488224276535    web
INSTANCE        i-55b38d56      ami-20ad1221                    pending innerkey        0             t1.micro        2013-02-25T07:43:21+0000        ap-northeast-1a aki-ec5df7ed                  monitoring-disabled                                     ebs                                   paravirtual     xen             sg-33bace32     default false
セキュリティグループや鍵ペアについては適切なものを指定ください。

次に、作成した 負荷対象となるEC2インスタンスにsshログインして、負荷試験ツール(sysbench)をインストールします。まずは ssh ログイン。
$ ec2-describe-instances i-55b38d56 \
     | grep '^INSTANCE'  \
     | cut --fields=5

ip-10-132-166-244.ap-northeast-1.compute.internal

$ ssh \
     -i ~/.ssh/innerkey.pem \
     -l ubuntu \
     ip-10-132-166-244.ap-northeast-1.compute.internal

続いて、EC2インスタンス上での設定。
まずは前準備の呪文として、以下の二つを実行しておきます(後者は、まぁ、無くてもOKかも)。
$ sudo apt-get update
$ sudo apt-get upgrade
次は、sysbench をインストールします。
$ sudo apt-cache search sysbench
sysbench - Cross-platform and multi-threaded benchmark tool

$ sudo apt-get install sysbench

Ubuntu 側の設定はコレで終わりなので、一旦ログアウトしておきます。
$ exit



・S
NSの設定

Alarmを利用するには通知先となるSNSが必要になります。
そのため、先に server-alarm という名前のSNSトピックを作成し、メールアドレスを登録しておきます。
手順は以前の記事を参考にしてください。
$ sns-create-topic server-alarm
arn:aws:sns:ap-northeast-1:488224276535:server-alarm

$ sns-subscribe \
     arn:aws:sns:ap-northeast-1:488224276535:server-alarm \
     --protocol email  \
     --endpoint  exploreaws@example.com

Subscription request received.

※ここでメール受信

$ sns-confirm-subscription \
     arn:aws:sns:ap-northeast-1:488224276535:server-alarm \
     --token ~メールで送られてきたTOEKN識別子~

arn:aws:sns:ap-northeast-1:488224276535:server-alarm:59bb374a-186b-40e9-8d6c-09d43d716058
念のため、sns-publish コマンドで通知が届くことを確認しておいてください。
⇒ Alarm設定後に通知が届かない場合、SNS側の設定ミスなのか、Alarm側の設定ミスなのか判断できなくなるので。
$ sns-publish \
     arn:aws:sns:ap-northeast-1:488224276535:server-alarm \
     --message 'This is sample publishing.'

13dc2c0b-069c-5820-8e6e-65965c13ae80



・Alarmの設定
(AmazonLinuxの場合) /opt/aws/bin/ にインストールされている alarm に関連しそうな mon-* 系コマンドは以下の通り。
$ ls -1 /opt/aws/bin/mon* \
     | grep -i alarm

/opt/aws/bin/mon-delete-alarms
/opt/aws/bin/mon-describe-alarm-history
/opt/aws/bin/mon-describe-alarms
/opt/aws/bin/mon-describe-alarms-for-metric
/opt/aws/bin/mon-disable-alarm-actions
/opt/aws/bin/mon-enable-alarm-actions
/opt/aws/bin/mon-put-metric-alarm
/opt/aws/bin/mon-set-alarm-state
Alarmの作成と削除は、それぞれ mon-put-metric-alarm と mon-delete-alarms が対応するようです。

まずはAlarmの作成から。

mon-put-metric-alarm で、良く使いそうなパラメータを並べてみます。
mon-put-metric-alarm

  ALARM_NAME
  --alarm-description 'COMMENT'
  --alarm-actions SNS_TOPIC_NAME,...

  --namespace  CLOUDWATCH_NAMESPACE
  --metric-name  CLOUDWATCH_METRIC
  --statistic  CLOUDWATCH_STATISTIC
  --dimensions CLOUDWATCH_DIMENSION
  --period  CLOUDWATCH_PERIOD_IN_SECOND
  --unit CLOUDWATCH_UNIT

  --threshold  VALUE_TO_COMPARE
  --evaluation-periods  NUMBER_OF_PERIODS
  --comparison-operator  (
         GreaterThanOrEqualToThreshold
       | GreaterThanThreshold,
       | LessThanThreshold
       | LessThanOrEqualToThreshold
       )
ものすごく大量にあってゲンナリしますが…。2つにグループ分けすると、以下のような感じになります。
  • 上段 - Alarmに関する名前、通知先SNSトピックの指定
  • 中段 - 監視対象となる CloudWatch の指定
  • 下段 - 条件と閾値(この値になったらAlarm作動するぜ…というモノ)

Alarm に関する名前は、EC2インスタンス自身の CPU負荷に対するAlarmを作成するので、それらしいモノにしておきます。


  cpu-overload
  --alarm-description 'CPU utlization overload'
  --alarm-actions server-alarm


CloudWatch の設定は、前回の記事で試したので特に困ることは無いですね…。以下のような感じになります。


  --namespace  AWS/EC2
  --metric-name  CPUUtilization
  --statistic  Average
  --period  300

  --unit Percent


EC2インスタンス、300秒(5分)間、CPU使用率…の平均値を監視対象とします。

どのEC2インスタンスで負荷が発生してもAlarmを出したいので、dimensions は指定しません。

period を指定させる意味が良く分かりませんが、とりあえず(CloudWatchデフォルトの)300としておきます。


最後の条件と閾値は…


  --threshold  50
  --evaluation-periods  2
  --comparison-operator  GreaterThanOrEqualToThreshold


…という設定で、「監視対象の値が 50%以上の2回以上続いたら」という条件設定にします。

ではコマンドを実行してみましょう。
$ mon-put-metric-alarm  \
     cpu-overload  \
     --alarm-description 'CPU utlization overload'  \
     --alarm-actions arn:aws:sns:ap-northeast-1:488224276535:server-alarm  \
     --namespace  AWS/EC2  \
     --metric-name  CPUUtilization  \
     --statistic  Average  \
     --period  300  \
     --unit Percent  \
     --threshold  50  \
     --evaluation-periods  2  \
     --comparison-operator  GreaterThanOrEqualToThreshold
OK-Created Alarm
先ほどのコマンド一覧にあった mon-describe-alarms で結果を確認してみます。
$ mon-describe-alarms
cpu-overload  INSUFFICIENT_DATA  arn:aws:sns:ap-nor...276535:server-alarm  AWS/EC2  CPUUtilization  300  Average  2  GreaterThanOrEqualToThreshold  50.0
それらしいものが設定されているように見えますね…。
しかし、状態(?)が INSUFFICIENT_DATA になっています。これって異常???
https://forums.aws.amazon.com/message.jspa?messageID=253009

Ensure any dimensions you specify are applicable to the metric (e.g. CPUUtilization for EC2 instances is measured against the InstanceId and AutoscalingGroup dimensions for the AWS/EC2 namespace, whereas CPUUtilization for RDS is measured against the dimensions DatabaseClass, DBInstanceIdentifier and EngineName for the AWS/RDS namespace).
上記の公式フォーラムの回答によると、CPUUtilization は Instance-ID か AutoScalingGroup を dimension として必要とするみたいですね…。どのインスタンスのCPU 負荷でも良いからアラーム対象とする…という設定にはできないみたいです…(x_x;

Alarm を再設定します。再設定(update)も 同じ mon-put-metric-alarm コマンドを使用するようです。
$ mon-put-metric-alarm  \
     cpu-overload  \
     --alarm-description 'CPU utlization overload'  \
     --alarm-actions arn:aws:sns:ap-northeast-1:488224276535:server-alarm  \
     --namespace  AWS/EC2  \
     --metric-name  CPUUtilization  \
     --dimensions 'InstanceId=i-55b38d56' \
     --statistic  Average  \
     --period  300  \
     --unit Percent  \
     --threshold  50  \
     --evaluation-periods  2  \
     --comparison-operator  GreaterThanOrEqualToThreshold

OK-Created Alarm

$ mon-describe-alarms
cpu-overload  OK  arn:aws:sns:ap-nor...276535:server-alarm  AWS/EC2  CPUUtilization  300  Average  2  GreaterThanOrEqualToThreshold  50.0
今度はバッチリ設定されているようですね。




・負荷試験の実行

負荷試験は、Ubuntu側で直接実行します。sshでログインして、そこから作業しましょう。
先に設定した mon-put-metric-alarm では「5分単位の計測で2回の高負荷」時に警告が飛ぶようにしたので、比較的な長い時間負荷試験を実行する必要があります。
ここでは、900秒(15分)実行しておくことにします。

$ ssh \
     -i ~/.ssh/innerkey.pem \
     -l ubuntu \
     ip-10-132-166-244.ap-northeast-1.compute.internal



$ sysbench \
     --max-requests=9999999 \
     --max-time=900 \
     --test=cpu run


sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!

Time limit exceeded, exiting...
Done.

Maximum prime number checked in CPU test: 10000


Test execution summary:
    total time:                          900.0490s
    total number of events:              203125
    total time taken by event execution: 899.3371
    per-request statistics:
         min:                                  1.78ms
         avg:                                  4.43ms
         max:                                229.57ms
         approx.  95 percentile:               2.11ms

Threads fairness:
    events (avg/stddev):           203125.0000/0.00
    execution time (avg/stddev):   899.3371/0.00



負荷試験対象である Ubuntu にはEC2コマンドをインストールしていないので、AmazonLinuxなインスタンスから CPUUtlization (CPU負荷)を確認してみます。
$ mon-get-stats  \
     CPUUtilization \
     --namespace AWS/EC2 \
     --statistics Maximum \
     --dimensions 'InstanceId=i-55b38d56'
2013-02-25 09:40:00  1.67   Percent
2013-02-25 09:45:00  1.67   Percent
2013-02-25 09:50:00  1.69   Percent
2013-02-25 09:55:00  1.64   Percent
2013-02-25 10:00:00  1.67   Percent
2013-02-25 10:05:00  1.75   Percent
2013-02-25 10:10:00  100.0  Percent
2013-02-25 10:15:00  100.0  Percent
2013-02-25 10:20:00  100.0  Percent
2013-02-25 10:25:00  100.0  Percent
2013-02-25 10:30:00  100.0  Percent

$ mon-describe-alarms
cpu-overload  OK  arn:aws:sns:ap-nor...276535:server-alarm  AWS/EC2  CPUUtilization  300  Average  2  GreaterThanOrEqualToThreshold  50.0

$ mon-describe-alarm-history cpuoverload
cpu-overload  2013-02-25T10:35:36.223Z  StateUpdate          Alarm updated from ALARM to OK
cpu-overload  2013-02-25T10:25:36.253Z  Action               Successfully executed action arn:aws:sns:ap-northeast-1:488224276535:server-alarm
cpu-overload  2013-02-25T10:25:36.230Z  StateUpdate          Alarm updated from OK to ALARM
cpu-overload  2013-02-25T09:46:47.720Z  StateUpdate          Alarm updated from INSUFFICIENT_DATA to OK
cpu-overload  2013-02-25T09:46:47.136Z  ConfigurationUpdate  Alarm "cpu-overload" updated
cpu-overload  2013-02-25T09:33:04.279Z  ConfigurationUpdate  Alarm "cpu-overload" created

Alarmに設定されたアクションが実行されたことになっています。

exploreaws@example.com にも、「ALARM: "cpu-overload" in APAC - Tokyo」という件名のメールが届いていました。

You are receiving this email because your Amazon CloudWatch Alarm "cpu-overload" in the APAC - Tokyo region has entered the ALARM state, because "Threshold Crossed: 2 datapoints were greater than or equal to the threshold (50.0). The most recent datapoints: [100.0, 100.0]." at "Monday 25 February, 2013 10:25:36 UTC".

View this alarm in the AWS Management Console:
https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#s=Alarms&alarm=cpu-overload

Alarm Details:
- Name:                       cpu-overload
- Description:                CPU utlization overload
- State Change:               OK -> ALARM
- Reason for State Change:    Threshold Crossed: 2 datapoints were greater than or equal to the threshold (50.0). The most recent datapoints: [100.0, 100.0].
- Timestamp:                  Monday 25 February, 2013 10:25:36 UTC
- AWS Account:                488224276535

Threshold:
- The alarm is in the ALARM state when the metric is GreaterThanOrEqualToThreshold 50.0 for 300 seconds. 

Monitored Metric:
- MetricNamespace:            AWS/EC2
- MetricName:                 CPUUtilization
- Dimensions:                 [InstanceId = i-55b38d56]
- Period:                     300 seconds
- Statistic:                  Average
- Unit:                       Percent

State Change Actions:
- OK: 
- ALARM: [arn:aws:sns:ap-northeast-1:488224276535:server-alarm]
- INSUFFICIENT_DATA: 

これでAlarmの設定が正しく機能していることが確認できました。

ちなみに、今回は「ALARMになった時」のActionだけ設定しましたが、実運用では「OKになった時」も設定しておくのが良いでしょう。負荷状態から自動的に復帰した場合、それも知りたいでしょうから…。

しかしAlarmの文面が変更できないのは、微妙に使いにくいですね…。



・後始末
mon-delete-alarm でAlarm設定を削除します。
$ mon-delete-alarms cpu-overload
    Are you sure you want to delete these Alarms? [Ny]y
OK-Deleted alarms
プロンプトがメンドくさければ、--force オプションで抑制できます。

Alarm の通知先であった、SNS も削除します。
$ sns-list-topics
arn:aws:sns:ap-northeast-1:488224276535:server-alarm

$ sns-delete-topic \
     arn:aws:sns:ap-northeast-1:488224276535:server-alarm
    Are you sure you want to delete this topic? [Ny]y
Topic deleted.
要らなくなった EC2 インスタンス (Ubuntu)も削除しておいてください。
$ ec2-stop-instances i-55b38d56
INSTANCE        i-55b38d56      running stopping

$ ec2-terminate-instances i-55b38d56
INSTANCE        i-55b38d56      stopped terminated

これで後始末も終了。




今回はここまで。


SNS(Simple Notification Service)をコマンドラインから設定します。
sns*系のコマンドライン版プログラムをインストールしていない場合は、以前の記事を参考にインストールしておいてください。


・SNS登録の手順/概要
SNSに登場するオブジェクトは3つ。
トピック           - 通知先ごとのグループ
サブスクリプション - 通知先、あるいはメッセージの購読者
メッセージ - 送信されるテキスト、あるいはデータ
SNSでは、まず 通知先ごとのグループとなるトピックを作成し、そこに購読者である通知先を登録(サブスクリプト)します。トピックへの通知先登録時には確認(confirmation)が必要になります。
その後、メッセージをトピックに対して送信すると、各登録者(通知先)にメッセージが送信されます。



・SNS系コマンドの使い方
sns*系コマンドの一覧は、http://docs.aws.amazon.com/sns/latest/cli/command-reference.htmlか、あるいは sns-cmd コマンドで入手できます。

$ sns-cmd
Command Name                       Description
------------                       -----------
help
sns-add-permission                 Add a permission to a topic.
sns-confirm-subscription           Confirm a Subscription.
sns-create-topic                   Create a topic.
sns-delete-topic                   Delete a topic.
sns-get-subscription-attributes    Get subscription attributes.
sns-get-topic-attributes           Get topic attributes.
sns-list-subscriptions             List all subscriptions.
sns-list-subscriptions-by-topic    List subscriptions by topic.
sns-list-topics                    Lists all topics.
sns-publish                        Publish a message to a topic.
sns-remove-permission              Remove permission from a topic.
sns-set-subscription-attributes    Set subscription attributes.
sns-set-topic-attributes           Set topic attributes.
sns-subscribe                      Subscribe to a topic.
sns-unsubscribe                    Unsubscribe from a topic.
version                            Prints the version of the CLI tool and the API.

    For help on a specific command, type '<commandname> --help'

コマンド一覧を見る限り、流れとしては以下のようになると思われます。
sns-create-topic                - トピックの作成
sns-list-topics - トピック一覧の表示

sns-subscribe - トピックの通知先追加を要求
sns-confirm-subscription - トピックへの通知先追加を承認
sns-list-subscriptions - 通知先一覧の表示
sns-list-subscriptions-by-topic - トピックごとの通知先一覧の表示

sns-publish - 通知の送信

sns-unsubscribe - 通知先の削除

sns-delete-topic - トピックの削除
それでは、その手順でやってみましょう。




・トピック作成
sns-create-topic コマンドでトピック名を指定するだけで作成されるらしい。
$ sns-create-topic sample_topic
arn:aws:sns:us-east-1:488224276535:sample_topic
あれ???
us-east-1 って???
環境変数の EC2_URL と EC2_REGION を指定しているハズですが、効果が無いようですね...。

sns-create-topic に --help オプションを与えて説明を見てみると… AWS_REGION と AWS_SNS_URL という環境変数が参照されるようです。メンドクサイので設定しておきましょう。ここでは、既に EC2_URL と EC2_REGION の環境変数が設定してあるので、それを利用して再設定します。マトメるとこんな感じ。
export EC2_REGION='ap-northeast-1'
export EC2_URL=ec2.${EC2_REGION}.amazonaws.com

export AWS_REGION=${EC2_REGION}
export AWS_SNS_URL=http://sns.${AWS_REGION}.amazonaws.com
バッチファイルや .bash_profile / .login にも追記しておくと良いでしょう。
⇒ AWS_SNS_URL は先頭に http:// が無いと正しく認識されないようです。EC2_URL側は 無くてもOKなのに...。

間違って作成したトピックは、↑の環境変数を設定する前に、以下のように削除しておきます。
$ sns-delete-topic \
     --force \
     --topic-arn arn:aws:sns:us-east-1:488224276535:sample_topic

Topic deleted.

$ sns-list-topics
No topics found.
で、トピックの再作成は以下のような感じ。というか、さっきと同じコマンドです。
$ sns-create-topic sample_topic
arn:aws:sns:ap-northeast-1:488224276535:sample_topic

$ sns-list-topics
arn:aws:sns:ap-northeast-1:488224276535:sample_topic
期待通りに Tokyo Region (ap-northeast-1)になってますね。



・サブスクライブ(送信先の登録)
送信先を登録するには sns-subscribe コマンドを使用します。
パラメータには TOPIC_ARN (トピックID)、--protocol オプションで http/https/email/email-json/sqs のいずれか、--endpoint オプションで URL/メールアドレス/SQS_ARN を指定します。
ここでは、「メールを送信する」という設定で登録することにします。
$ sns-subscribe \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic \
     --protocol email \
     --endpoint 'exploreaws@example.com'

Subscription request received.
sns-subscription コマンドだけでは、登録は完了しません。
sns-subscriptionが 正しく受け付けられると、指定したメールアドレスにメールが届きます。
送信主は no-reply@sns.amazonaws.com で、タイトルが「AWS Notification - Subscription Confirmation」となっているハズです。
メールには URL (リンク)が含まれていますが、ここではクリックはしないでください。
メールに含まれているURLは、以下のようになっています。
https://sns.ap-northeast-1.amazonaws.com/confirmation.html
     ?TopicArn=arn:aws:sns:ap-northeast-1:488224276535:sample_topic
     &Token=~長い文字列~
     &Endpoint=exploreaws@example.com
Token パラメータである ~長い文字列~ の部分がサブスクライブ用トークンなので、コピーしておきます。TopicArn は、先ほど作成したトピックのIDですね。

sns-confirm-subscription  コマンドを使った サブスクライブの確認(confirmation)には、先ほどコピーした サブスクライブ用トークンと TOPIC_ARN が必要です。以下のようにして sns-confirm-subscription コマンドを呼び出します。
$ sns-confirm-subscription \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic \
     --token サブスクライブ用トークン

arn:aws:sns:ap-northeast-1:488224276535:sample_topic:e39a9b52-d792-481d-a5a6-8e8763951e99
sns-confirm-subscription のレスポンスとして、サブスクリプションARN(Subscription ARN)が表示が表示されます。

登録がホントに完了しているかどうか sns-list-subscriptions と sns-list-subscriptions-by-topic  コマンドで確認してみます。
$ sns-list-subscriptions
arn:aws:sns:ap-northeast-1:488224276535:sample_topic:e39a9b52-d792-481d-a5a6-8e8763951e99  email  exploreaws@example.com


$ sns-list-subscriptions-by-topic \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic

arn:aws:sns:ap-northeast-1:488224276535:sample_topic:e39a9b52-d792-481d-a5a6-8e8763951e99  email  exploreaws@example.com
登録が1コしかないので良く分かりませんが、一応登録できているのでしょう…。
email の前に表示されているのが、Subscription ARN でしょうね。



・メッセージ送信
sns-publish コマンドで送信します。
本文は --message オプションで指定します。
プロトコルが email-json の場合は --message-structure で指定するらしいです。
更にプロトコルが email の場合、--subject でタイトルを指定できます。
$ sns-publish \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic \
     --message 'Message body.'

a225674d-2aa5-540c-9db3-2ed850443eee
レスポンスで表示される文字列は message-ID らしいです。
指定されたメールアドレス(ここでは exploreaws@example.com)に…
タイトル「AWS Notification Message」
本文「Message body.」+ 登録解除用URL等
…というメールが届きました。

今度は、タイトルを指定して送信してみましょう。ついでに複数行の送信が出来るかも試してみます。
$ sns-publish \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic \
     --message 'Message body.
<改行キー>
     Second line.' \
     --subject 'email title'

f9e9c50b-b1d3-50c2-9ab6-8c9ecad42662
この送信方法だと、
タイトル「email title
本文「Message body.
   Second line.」+ 登録解除用URL等
…というメールが届きました。バッチリですね。



・サブスクライブ解除(送信先の登録解除)
サブスクライブ解除には sns-unsubscribe コマンドを使用します。
sns-confirm-subscription あるいは sns-list-subscription コマンドなどで得られる Subscription ARN がパラメータとして必要になります。
$ sns-list-subscriptions
arn:aws:sns:ap-northeast-1:488224276535:sample_topic:e39a9b52-d792-481d-a5a6-8e8763951e99  email  exploreaws@example.com

$ sns-unsubscribe  \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic:e39a9b52-d792-481d-a5a6-8e8763951e99
Unsubscribed.

$ sns-list-subscriptions
No subscriptions found.
これで、サブスクリプション登録が消えました。



・トピックの削除

最後に残ったトピック「sample_topic」を削除します。
sns-list-topics で TopicARN を取得し、sns-delete-topic に渡すことで削除できます。
ホントに削除してよいかどうか確認するプロンプトが出るので「y」と答えれば、削除が完了します。
$ sns-list-topics
arn:aws:sns:ap-northeast-1:488224276535:sample_topic

$ sns-delete-topic \
     arn:aws:sns:ap-northeast-1:488224276535:sample_topic

    Are you sure you want to delete this topic? [Ny] y
Topic deleted.

$ sns-list-topics
No topics found
確認プロンプトを出したくない場合は --force オプションを使用してください。


これでトピックもバッチリ消えました!



今回はここまで。

CloudWatch を使いたい……のですが、以前 GUI 版で試した限りでは、先に SNS (Simple Notification Service)の設定が必要になります。
しかし、ザッと見てみた限りでは Amazon Linux でも sns-* 系のコマンドはインストールされていないように見えます…。



・SNS用コマンドラインツールの入手/ダウンロード
http://docs.aws.amazon.com/sns/latest/cli/welcome.html
上記 Amazon 公式マニュアル (API Version 2010-03-31 のモノ)を読むと、sns-* 系のコマンドは 別途インストールする必要があるようです。そもそもSNS用のコマンドラインツール自体、「コミュニティが制作したモノ」であって公式ツールではないとのこと…。

SNS用のコマンドラインツールは、以下のURLから入手できます。
⇒ http://sns-public-resources.s3.amazonaws.com/SimpleNotificationServiceCli-2010-03-31.zip

Amazon Linux に ssh し、そこから wget で取得してみます。
$ wget 'http://sns-public-resources.s3.amazonaws.com/SimpleNotificationServiceCli-2010-03-31.zip'

--2013-02-12 10:32:32--  http://sns-public-resources.s3.amazonaws.com/SimpleNotificationServiceCli-2010-03-31.zip
Resolving sns-public-resources.s3.amazonaws.com... 207.171.189.81
Connecting to sns-public-resources.s3.amazonaws.com|207.171.189.81|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6537754 (6.2M) [application/zip]
Saving to: “SimpleNotificationServiceCli-2010-03-31.zip”

100%[====================================================>] 6,537,754   1.38M/s   in 8.7s

2013-02-12 10:32:42 (736 KB/s) - “SimpleNotificationServiceCli-2010-03-31.zip” saved [6537754/6537754]

特に問題なくダウンロード成功しました。



・SNSコマンドラインツールのインストールと環境設定

ダウンロードした 付似せファイルをunzipコマンドで展開します。
$ unzip SimpleNotificationServiceCli-2010-03-31.zip
Archive:  SimpleNotificationServiceCli-2010-03-31.zip
   creating: SimpleNotificationServiceCli-1.0.3.3/
  inflating: SimpleNotificationServiceCli-1.0.3.3/README.TXT
 ~
unzipで展開したディレクトリを見てみると…
$ cd SimpleNotificationServiceCli-1.0.3.3/
$ ls -1
bin
credential-file-path.template
lib
license.txt
notice.txt
README.TXT
RELEASENOTES.TXT
THIRDPARTYLICENSE.TXT
README.TXTというのがあるので、コレの中身を確認します。期待通り、インストール手順が書かれていました。
Installation:
-------------
1. Ensure that JAVA version 1.6 or higher is installed on your system: (java -version)
2. Unzip the deployment zip file
3. Set the following environment variables:
3.1 AWS_SNS_HOME - The directory where the deployment files were copied to
        check with:
           Unix: ls ${AWS_SNS_HOME}/bin should list sns-cmd...)
           Windows: dir "%AWS_SNS_HOME%\bin" should list sns-cmd ...)
3.2 JAVA_HOME - Java Installation home directory
4. Add ${AWS_SNS_HOME}/bin (in Windows: "%AWS_SNS_HOME%\bin") to your path

READMEによると JavaVM1.6以上 が必要らしいので JVM のバージョンを調べてみます。
$ java -version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.5) (amazon-53.1.11.5.47.amzn1-i386)
OpenJDK Client VM (build 20.0-b12, mixed mode)
え゛ー。Amazon Linux ってOpenJDK がインストールされているんですね…。まぁ、互換性が問題になるようなものはインストールしていないのでコレで良いというコトにしておきます。
で、肝心のJava のバージョンは 1.6 以上なのでOK。

次は、Java用の環境変数。
$ export  | grep JAVA
declare -x JAVA_HOME="/usr/lib/jvm/jre"
JAVA_HOME 環境変数も期待通り設定されています。



次はファイルの配備場所です。
AmazonLinux では /opt/aws/ の下に AWS用コマンドラインツールがインストールされているので、それに倣って 同じような場所にインストールしてみます。
まず、展開したパッケージファイル群の所有者をrootに変更の上、/opt/aws/others/ へ移動します。
$ sudo chown -R root:root SimpleNotificationServiceCli-1.0.3.3/
$ sudo chmod -R u=rwx,og=rx SimpleNotificationServiceCli-1.0.3.3/

$ sudo mkdir /opt/aws/others
$ sudo chmod u=rwx,og=rx  /opt/aws/others
$ sudo mv SimpleNotificationServiceCli-1.0.3.3  /opt/aws/others/
別バージョンをインストールする際にカンタンに切り替えられるよう、symbolic link を作成します。
$ cd /opt/aws/others
$ sudo ln -s SimpleNotificationServiceCli-1.0.3.3/  sns
/opt/aws/others/sns/bin/ ディレクトリにある sns-* に該当するファイルの symbolic link を /opt/aws/bin/ の下に作成します。
$ cd /opt/aws/bin/
$ ls -1 /opt/aws/others/sns/bin/sns-* \
     | grep -v '.*\.cmd$' \
     | sed -e 's!^.*/!!' \
     | xargs -i sudo ln -s /opt/aws/others/sns/bin/{}  {}

ここまででファイル配備は完了。

次は…sns-* コマンド用の環境変数 AWS_SNS_HOME を設定します。
に PATH を通す必要があるので、以下のように設定します。
export AWS_SNS_HOME=/opt/aws/others/sns
環境変数PATHに、sns-* コマンドのディレクトリも登録する必要がありますが……、先にsymbolic link を /opt/aws/bin/ に作成しておいたので問題ナシです。


他に AWS_CREDENTIAL_FILE も必要なので、設定していないようなら追記しておきます。アクセスキー等は以前の方法で入手したものでOK。
$ export AWS_CREDENTIAL_FILE=~/.aws/aws-accesskey.ini

$ cat ~/.aws/aws-accesskey.ini
AWSAccessKeyId=アクセスキー
AWSSecretKey=シークレットアクセスキー
ここでは、export 設定をマトメてバッチファイルに記載しておきます。
メンドクサければ .bash_profile や .login 等に記載してもよいかもしれません。



・SNSコマンドラインツールの動作確認
環境変数が設定出来たら早速実行してみます。
⇒ ここでは、EC2_URL、EC2_REGION、AWS_CREDENTIAL_FILE、AWS_ACCESS_KEY、AWS_SECRET_KEY が正しく設定されている環境で動作確認しています。
$ sns-version
Amazon SimpleNotificationServiceCli CLI version w.x.y.z (API 2010-03-31)

$ sns-list-topics
No topics found.
バージョン表記が w.x.y.z とかなっていてチョット変ですが……バッチリ動作するようになりました!!!



これで、sns-* 系のコマンドが利用できるようになりました☆

今回は CloudWatch というか、ヘルスチェック機能(AWSではAlarmと呼ぶらしい)を設定してみます。


・WEBサーバの作成
web01、web02 という名前で、二台のWEBサーバを作成しておく。
中身は以前作ったものと同様。
※もっとも、今回はWEBサーバとしては利用しないので、単なるLinuxインスタンスでOKですが…。


・SNS Topic の作成と、通知先設定

alarm01
AWS Management Console から SNS を選択
⇒ SNS は Simple Notification Service の略




alarm02
SNS Dashboard が表示されるので、中央の Create New Topic をクリック




alarm03
TopicName と DisplayName をテキトーに設定します。
ここでは、server-alarm としておきます。




alarm04
作成した Topic に対して通知先を設定する必要があるので、
MyTopic の server-alarm を選択して、Create New Subscription をクリック。




alarm05
通知先の設定。
ここでは、Protocol を Email とし、Endpoint に自分のメールアドレスを設定します。




alarm07
Topic 設定完了後の画面。
server-alarm の topic に登録(subscription)された email アドレスは、PendingConfirmation (確認/認証待ち)状態になっています。


登録したメールアドレス宛てに no-reply@sns.amazonaes.com から、Subscription の確認メールが届いているはずなので、確認します。

(メール文面は省略)


alarm09
no-reply@sns.amazonaes.com
からのメールに含まれているURLをクリックすると、Confirmation が完了し、上記のようなブラウザ画面が表示されます。



・Alarmの作成
alarm10
EC2 Dashboard から web01 の監視状況を確認します。
自分では特に何も設定していなくても、基本的な監視(だけ)は実施されているようです。
その中から Avg CPU Utilization をクリックしてみます。
※Avg は Average (平均) の略でしょう。



alarm11
Alarm 作成画面が表示されるので、適当な値を入力します。
ここでは、CPU 利用率が 25% 以上になったら Alarm を飛ばすように設定します。
対象topic(= Send a notification to) には、先ほど作成した topic である server-alarm を指定しておきます。




alarm12
Alarm 作成完了画面。特に気になる文面はないですね…。




alarm13
似たような手順で、今度は web01 の Disk Writes 用の Alarm も設定します。




・サーバ負荷をかけてみる
サーバー負荷をかけるためには、負荷をかけるためのプログラムが必要なのですが…。
特にこだわりは無いので、sysbench というソフトを使ってみることにします。

まずはインストール。

  sudo apt-get install sysbench

特に難しいこともなくインストールは完了します。

まずは sysbench で CPU 負荷をかけてみましょう。コマンドは「sysbench --max-requests=9999999 --max-time=300 --test=cpu run」とします。詳細は man sysbench とかして調べてみてください。

上記コマンドを使って、web01 上で CPU 負荷をかけるように実行してみます。
ssh で web01 にログインして実行すると、以下のようになります。

ubuntu@ip-10-120-3-7:~$ sysbench --max-requests=9999999 --max-time=300 --test=cpu run

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!
Time limit exceeded, exiting...
Done.

Maximum prime number checked in CPU test: 10000


Test execution summary:
    total time:                          300.0011s
    total number of events:              68805
    total time taken by event execution: 299.5721
    per-request statistics:
         min:                                  1.47ms
         avg:                                  4.35ms
         max:                                157.60ms
         approx.  95 percentile:               1.50ms

Threads fairness:
    events (avg/stddev):           68805.0000/0.00
    execution time (avg/stddev):   299.5721/0.00




alarm15
EC2 Dashboard から、負荷のかかり具合を確認してみます。

グラフだと80% までCPUパワーを消費していますね。

負荷が設定した閾値を超えたので、AWS から Alarm メヘールが届いているハズです。
監視は 5分ごとのデータに依存しているので、すぐにメールが来るかどうかは分かりませんが…。




次は、HDD に負荷をかけてみます。
HDD 負荷をかける場合は、sysbench に対して、「prepare → run → cleanup」という順序で操作するようです。
テンポラリファイルがたくさん作成されるので、サブディレクトリを作成して、その中で実行するのが良いでしょう。
以下の3行のコマンドを実行してください。

  sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  prepare
  sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  run
  sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  cleanup
結果は以下のような感じ。

ubuntu@ip-10-120-3-7:~$ sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  prepare

sysbench 0.4.12:  multi-threaded system evaluation benchmark

128 files, 16384Kb each, 2048Mb total
Creating files for the test...
ubuntu@ip-10-120-3-7:~$

ubuntu@ip-10-120-3-7:~$ sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  run

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Number of random requests for random IO: 9999999
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Threads started!
Time limit exceeded, exiting...
Done.

Operations performed:  98880 Read, 65920 Write, 210931 Other = 375731 Total
Read 1.5088Gb  Written 1.0059Gb  Total transferred 2.5146Gb  (8.5832Mb/sec)
  549.33 Requests/sec executed

Test execution summary:
    total time:                          300.0037s
    total number of events:              164800
    total time taken by event execution: 50.8981
    per-request statistics:
         min:                                  0.01ms
         avg:                                  0.31ms
         max:                                207.43ms
         approx.  95 percentile:               0.99ms

Threads fairness:
    events (avg/stddev):           164800.0000/0.00
    execution time (avg/stddev):   50.8981/0.00

ubuntu@ip-10-120-3-7:~$


ubuntu@ip-10-120-3-7:~$ sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  cleanup

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Removing test files...

ubuntu@ip-10-120-3-7:~$


特に問題なく実行できているようです。




alarm16
AWS Management Conosole の EC" Dashboard から結果(HDDの DiskWriteのグラフ)を確認してみます。

あれ……?
負荷ゼロですね...?


.
.
.

嗚呼!!

作成したインスタンスは HDD として EBS を利用しているので、ローカルのHDD(Ephemeral Disk と呼ばれるらしい)は利用していないのですね。
なので、負荷を計測するべき対象は web01 サーバ(EC2)ではなく、そこにアタッチされている EBS になります。


alarm17
EC2にアタッチされている EBS を調べてみましょう。
EC2 インスタンスにアタッチされている EBS の ID を調べるには、上記のようにします。
EC2 インスタンスから見た場合、/dev/sda1 としてマウントされているので、そのデバイスの状態を確認すると、EBS の ID が入手できます。




・EBS に Alarm を設定する
alarm18
AWS Management Console の Cloud Watch から、Metrics をクリックし、先ほどの EBS ID を使って検索します。
ここでは、DiskWriteBytes で Alarm を設定します。




alarm19
名前と閾値をテキトーに設定します。




alarm20
通知先となる SNS Topic を選択します。
ここでは server-alarm を指定します。

この後、「確認画面」と「完了画面」が出ますが、特に困ることもないので省略します。




似たような感じで、EBS の 「TotalWriteTime」「TotalWriteOps」 に対する Alarm も設定しておきます。


↓ CloudWatch から 指定した EBS ID の TotalWriteBytes を検索
alarm29

↓ EBS の TotalWriteBytes に対する Alarm を設定
alarm30

↓ CloudWatch から 指定した EBS ID の TotalWriteOps を検索
alarm37

↓ EBS TotalWriteOps に対する Alarm を設定
alarm38



・再度サーバに負荷をかける

先ほどと同じ手順で HDD に負荷をかけてみます。

sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  prepare
sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  run
sysbench --max-requests=9999999 --max-time=300 --test=fileio --file-test-mode=rndrw  cleanup

状況/負荷のかかり具合にもよりますが、負荷をかけた後、設定した Alarm がメールで通知されているはずです。





alarm42
Alarm の閾値によっては、通知が来ないこともあるようですが...。

CPU 負荷の場合は期待通りに負荷がかかるのですが、EBS の場合 イマヒトツ負荷のかかり具合が不明です。何度か負荷をかけると、Alarm が発生したりしなかったりするので、キャッシュが設定されているように思えます。もっとも、詳細は不明(調べればどこかに記載されている???)。

実際に運用するか、一般的な想定値から閾値を設定してみる必要があると思います…。
(つまり、ここでは閾値の妥当性については分からない…ということです)




・INSUFFICIENT_DATA とは?

alarm44
負荷をかけずにしばらく放置しておくと、EBS の TotalWriteTime に対する Alarm が「INSUFFICIENT_DATA」という状態になります。

これは、いったい何?!
.
.
.

そうか、「書き込むべきデータが無い」状態では「書き込み回数(WriteOps)」はゼロで、
「書き込みに要した時間(write time)」もゼロだから、「0÷0=計算不可」となるのかな…たぶん…。




・後始末
alarm45
Alarm も(数が多いと)課金対象らしいので実験が終わったらサッサと削除しておきます。
Alarm の一覧で、全Alarm をチックして Delete ボタンを押下するだけです。




alarm47
EC2インスタンスとEBSも削除して、課金されないようにしておきます。
EC2 dashboard で、利用中のサービス状態を確認しておいてください。




・TIPS

  1. Alarm のメールには display name が記載される。そのため、display name には「障害の内容」あるいは「受信者に対処して欲しい作業」を記載しておくと良いかも。
  2. Alarm に設定する閾値は、実際に運用して決定する必要がある。EBS は仕組みと計測単位の詳細が良く分からないので、それも調べてみる必要がある。



今回はここまで。


次は AutoScaling を試してみたい。

このページのトップヘ