Amazon VPCでVPNコネクションの状態をAPI監視する
VPCでデータセンターと接続する
Amazon VPCは、仮想プライベートネットワークを構築できるサービスです。プライベートネットワークという名前から、一切インターネットに接続されないネットワークを組むことができます。インターネットに繋げるときにはインターネットゲートウェイ(igw)の設定、バックネットとVPN接続するときにはバーチャルプライベートゲートウェイ(vgw)の設定が必要です。今回はバックネットとの接続状態を監視する小さなプログラムをご紹介します。
VPNコネクションの状態を確認する
VPNコネクションの状態は、AWS管理コンソールのVPC内にあるVPN Connectionsから確認することができます。1つのコネクションには2つのトンネルが張ってありまして、それぞれの状態を確認することができます。グリーン(UP)なら接続OK、レッド(DOWN)なら接続NGです。画面から直ぐに確認できますが、運用を考えるとプログラムでチェックしたいですよね。
未接続の状態
TUNNEL1つ繋がった状態。1つでも通信できます。
TUNNEL2つ繋がった状態。2つ繋がっていれば安心。
VPCのAPIを使う
VPNコネクションの状態を確認するためのコマンドが用意されています。ec2-describe-vpn-connectionsです。早速使ってみましょう。
$ export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com $ export AWS_ACCESS_KEY=****************** $ export AWS_SECRET_KEY=****************** $ export PATH=$PATH:/opt/aws/bin/:/home/ec2-user/scripts/lib/ $ export EC2_HOME=/opt/aws/apitools/ec2 $ ec2-describe-vpn-connections VPNCONNECTION vpn-XXXXXXXX available ipsec.1 cgw-XXXXXXXX vgw-XXXXXXXX true TUNNEL 27.0.1.XXX UP Fri Nov 23 10:14:44 UTC 2012 0 TUNNEL 27.0.1.YYY UP Fri Nov 23 10:14:36 UTC 2012 0 ROUTE 192.168.100.0/24 static available
たしかに接続状態を取得できましたね。では次に、UPが含まれている行数を取得してみたいと思います。
$ ec2-describe-vpn-connections | grep TUNNEL | grep UP | wc -l 1
1とでましたね。1つのVPNコネクションが取れる値は、0/1/2のどれかになります。では、この値をCloudWatchにカスタムメトリクスとして上げてみましょう。
$ sudo vi check_vpn_connection.sh #!/bin/bash IS_CONNECT=$(ec2-describe-vpn-connections | grep TUNNEL | grep UP | wc -l) INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id` INSTANCE_AZ=`curl -s curl http://169.254.169.254/latest/meta-data/placement/availability-zone/` INSTANCE_REGION=${INSTANCE_AZ%?} mon-put-data --region $INSTANCE_REGION --metric-name VpnConnection --namespace EC2/VPN --value $IS_CONNECT
これを2分に1回とかCronで回してみてはいかがでしょうか。そして、CloudWatch側では5分の平均が0のときにアラームするとかどうだろう。
*/2 * * * * * check_vpn_connection.sh
それではCloudWatchで統計をみてみましょう。概ね繋がりっ放しですね。おそらくデータのやり取りが無いときにタイムアウトしているかと思います。ここらへんはVPCの設定ではなくルータ側の設定ですね。
おまけ:mon-put-dataの重さに耐えかねる
1分に1回とかCloudWatchにメトリクスを上げるときに標準ツールとして用意されているコマンドを使うと、JVMが裏で走り始めます。毎回新規に立ち上がるので非常に重いです。そこで、軽量なツールを使ってみたいと思います。
botoを使ってカスタムメトリクスを投げる
軽量で軽快というキーワードで思い浮かんだのが、RubyとPython。ということで、今回はPythonでやってみます。
$ sudo vi mon-put.sh #!/usr/bin/python # coding: utf8 import sys,boto,boto.ec2,datetime argvs = sys.argv from boto.ec2.cloudwatch import CloudWatchConnection AWS_ACCESS_KEY = "******************" AWS_SECRET_ACCESS_KEY = "******************" def main(): try: conn = boto.ec2.cloudwatch.connect_to_region( aws_access_key_id=AWS_ACCESS_KEY , aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name="ap-northeast-1") metrics = conn.put_metric_data(argvs[1], argvs[2], float(argvs[3]), datetime.datetime.now(), argvs[4], None,None) except Exception,e: print e raise main()
呼び出すときはこんな感じ。
$ ./mon-put.sh EC2/VPN VPNConnection $IS_CONNECT Count
これをやる前JVMはCPU使用率50%でしたがw、Pythonにしたら8%程度になりました。めでたしめでたし。
まとめ
AWSの状態を監視したいとき、まずはAWS APIを活用しましょう。定期的にチェックをしてCloudWatchに上げたり、SNSに通知することで、サーバにログインせずとも詳細な状態を把握することができるようになります。今日から君も非ログイン検査だ!