0

AWSの課金状況をプログラマブルに取得する

AWSの課金状況をプログラマブルに取得するには、CloudWatch経由で取得します。
Billing用のAPIがあるわけでなく、CloudWatchでAWSの下記情報を監視するように設定し、そこから課金のメトリクスを取得します。

「課金」と書いたものの正確には「請求額」の取得ですね。
取得にあたり2つ注意点として、

  • Amazon側の請求確定のサイクルは必ずしも1時間に1回というわけではないので、ずっとEC2を使ってるのにAPIでデータを取得してみても1時間前と2時間前の料金が同じという事は多々あります。大体3時間くらいのサイクルでアップデートされてる気がします。
  • サービス別では取得できるけど、リージョン別やインスタンス別の取得等はできません。

という事があります。

以下がスクリプトです。
Pythonなんでbotoを利用しています。
どこのブログに書いてたけど確かにec2のネームスペースというのが気持ち悪い。
元々、CloudWatchはEC2の負荷状況を監視する目的だけだったからかな。

import datetime
import os
import sys
import boto.ec2.cloudwatch

AWS_REGION = "us-east-1"
AWS_KEY_ID = "***************"
AWS_SECRET_KEY = "***************"
 
cloudwatch_conn = boto.ec2.cloudwatch.connect_to_region(
        AWS_REGION,
        aws_access_key_id=AWS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_KEY)

end = datetime.datetime.utcnow()
start = end - datetime.timedelta(hours=4)
 
services = ['AWSDataTransfer', 'AmazonEC2', 'AmazonGlacier','AmazonRoute53',  'AmazonS3', 'AmazonSNS']
 
for service in services:
        value = cloudwatch_conn.get_metric_statistics(
                3600,
                start,
                end,
                'EstimatedCharges',
                'AWS/Billing',
                'Maximum',
                dimensions = {'ServiceName':[service], 'Currency':['USD']}
        )
        if not value:
                continue
        print service
        print value
        print value[0]['Maximum']

課金状況を取得するには、
metric_nameにEstimatedChargesをnamespaceにAWS/Billingにしてやる必要があります。
BillingServicesは使ってるサービスを列挙すれば良いです。

US-EASTにすべてのリージョンの課金情報があつまるので、それに接続します。

4時間前から取得していますが、これも前述通り1時間前とかだと請求額が確定してないからかデータの取得はできません。

色々おもしろいことができそうですね。
現在は、これをFluentdに投げて、Kibanaで読み込むということをしています。
CloudWatchのグラフみとけというツッコミはいらないです。

0

RDSでのリストア方法

mySQLに限らず、バックアップの手段は熟知してても、いざ不測の事態が起こってデータをリストアをしようとしたらやり方がよくわからないってことがあります。
RDSでもインスタンスを作成時、何も指定してなくてもバックアップの設定を行ってくれますが、リストアは当然コマンドを記述しなくてはいけません。

RDSのバックアップには手動によるスナップショット方式と自動でバックアップを行ってくれるものの2種類ありますが、今回の説明は後者です。
バックアップする期間はインスタンス起動時のオプション(backup-retention-period)で指定できるけど、指定しなくても1日間のデータをバックアップとってくれます。
例えば今が2010-02-02 23:30だとしたら 2010-02-01 23:30から2010-02-02 23:25のどのタイミングのデータでもリストアすることができます。
リストアは下記コマンドを使います。

rds-restore-db-instance-to-point-in-time new-db -s kowareta-db -r 2010-01-29T16:00:00Z

リストアは別インスタンスを立ち上げるので第一引数で新しいインスタンス名、
-sはバックアップしたいデータベース名、
-eはどの時間の状態に戻すか(指定はUTCで)
となります。

リストアはデータの量によるけど10分前後かかります。その間statusはcreatingとなります。

0

EBSをバックアップとして使う

EC2のインスタンスのバックアップは前回の通りS3にイメージ化して保存しておくのがいいと思うけど、/mnt以下のイメージ化の対象外ファイルをバックアップするにはEBSの方が便利です。
EC2とS3の関係はそんな密なものでもなく、EC2にS3を直接マウントすることができません。(擬似的には可能かも)
しかもS3へのアクセスはhttp経由ということでrsyncも使えず速度が遅い。

そもそもEBSが何かというと外付け可能な永続的ブロックストレージです。わかりやすく言うとUSB接続の外付けハードディスクみたいなものです。
料金はインスタンスにマウントするしないに関わらず、EBSを借りた時点で1Gにつき一ヶ月当たり$0.1 + 100万リクエストにつき$0.1です。

一度マウントしてしまうと後はローカルドライブ同様に扱えます。
EBSの素晴らしいところは、一旦アンマウントして別のインスタンスにデータはそのままマウントすることが可能ということ。
これで万が一カーネルパニックでインスタンスが動かなくなってもデータの救出が可能です。
但し、一つ残念なのが同時に複数からのマウントはできません。これができたらNFSとも決別できて、かなり幸せになれそうだけど現時点では不可能です。
直接データをEBSに保存してもいいと思うけど、私の場合、データは/mntに保存しておいて定期的にEBSにrsyncしてバックアップストレージとして使っています。

使い方

扱い方は以下の通り。今回はAWS management consoleを使ってます。
ELASTIC BLOCK STORE→ Volumes → create Volumeを選択
Sizeは1G以上、Availability ZoneはEC2のインスタンスのゾーンと合わしておく。

しばらくしてStatusが「available」になれば使用可能です。

次の作成したこのボリュームをインスタンスに関連付けします。
上メニューのAttach Volumeを選択するだけです。

Instancesを関連付けたインスタンスをDeviceを適当なものに(本例では/dev/sdb)を選択。

これでAWS management consoleの設定が終了。
残念ながらこの時点ではマウントする準備が出来ただけです。
続けてECのインスタンスでの作業です。

# mkfs -t ext3 /dev/sdb
ke2fs 1.40.4 (31-Dec-2007)
/dev/sdb is entire device, not just one partition!
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
26214400 inodes, 52428800 blocks
2621440 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
1600 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872
 
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
 
This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

ディレクトリを生成
# mkdir /vol

マウント実行
# mount /dev/sdb /vol

確認
# df -h
Filesystem サイズ 使用 残り 使用% マウント位置
/dev/sda1 9.9G 5.8G 3.6G 62% /
/dev/sda2 147G 38G 102G 27% /mnt
none 854M 0 854M 0% /dev/shm
/dev/sdb 197G 188M 187G 1% /vol

これでマウントは完了です。
あとは必要に応じてバックアップ用rsyncのcron設定する。
0 */3 * * * rsync -avz --delete /mnt /vol/backup/ 1> /dev/null

0

EC2のUS-EASTで作ったAMIをUS-WESTで使えるようにする

EC2にはリージョン(region)とゾーン(zone)という概念があります。
リージョンは物理的なデータセンターの場所で現在世界に3箇所あります。

  • ヨーロッパ
  • アメリカ西海岸
  • アメリカ東海岸

ゾーンはリージョンの中でさらに細かく別れた仮想的な地域です。
例えば、ヨーロッパだと下記のようなゾーンがあります。

  • eu-west-1a
  • eu-west-1b

ゾーンに関しては普通にEC2を使う場合は特に意識することはないけど、リージョンはそれぞれが別世界です。
用意されてるAMIや料金体系も違うしセキュリティーグループもそれぞれ独立しています。なので、東海岸で作成したAMIというのもそのままでは西海岸では使えません。
西海岸で使えるようにする為にEC2ではコマンドが用意されているのでそれを使います。
下記をEC2上で実行します。
ec2-migrate-bundle -k pk-******************.pem -c cert-******************.pem -a (アクセスキー) -s (シークレットキー) --bucket (今のイメージファイルが置いてるS3のディレクトリ) --manifest image.manifest.xml --location us-west-1 --region us-west-1 --destination-bucket (西海岸用のイメージファイルを置くS3のディレクトリ)

-k
Private Key File

-c
X.509 certificate file

-a
アクセスキー
例 R54S74PGDB0436KD7G2

-s
シークレット
例 gQbGdc/GzNTJDm54dvab/URn9D8Beriq2/LJ/MIGO1

–bucket
今のイメージファイルが置いてるS3のディレクトリ(image.manifest.xmlがあるディレクトリ)
例 /hogehoge-backup/20100114/

–destination-bucket
西海岸用のイメージファイルを置くS3のディレクトリ
例 /hogehoge-west-backup/20100114/

destination-bucketは予めディレクトリを用意しておく必要はありません。
深い階層を指定してもディレクトリを再帰的に生成してくれます。

ElasticIPがリージョンをまたいで使えないので、IPが変わるのを覚悟の上移行してください。
西海岸のゾーンを使うと40%くらいレイテンシーが改善されました。

0

EC2インスタンスをS3にバックアップ&AMIを作成

順調に動いてる俺々LAMP環境のAMIを作成したい時の方法です。
EC2にS3にバックアップ用のコマンドが用意されてるのでそれを使います。
イメージを作成→S3に保存→AMIを登録といった流れになります。

まずは、AWSの管理画面で発行されたPrivate Key File(pk-*******************.pem)とX.509 certificate file(cert-*******************.pem)をローカルから俺々LAMP環境に送る。
scp -i oreore.pem *.pem root@ec2-**-**-**-**.compute-1.amazonaws.com:/mnt

ローカルでの作業はこれだけで、以下、EC2の俺々LAMP環境の/mntでの作業。
ec2-bundle-vol -d /mnt --privatekey pk-*******************.pem --cert cert-*******************.pem --user (Account Number)

-privatekeyと-certはそれぞれ先程ローカルから転送したファイルを指定する。
Account NumberはAWS管理画面のAccount Activityのページにある。
「welocome, hogehoge」の下あたりにある9152-8254-1321といった数字の羅列。

Copying / into the image file /mnt/image…となって容量によるけど15分かけて大量のimageファイルとimage.manifest.xmlを生成する。
実行中、下記のようなメッセージが表示されるけどこのディレクトリ以外のものでimageファイル作りますよ〜っということ。

Excluding:
/sys
/proc
/sys/fs/fuse/connections
/dev/pts
/proc/sys/fs/binfmt_misc
/dev
/media
/mnt
/proc
/sys
/mnt/image
/mnt/img-mnt

/mntも対象外。
あくまでシステム(OS)をバックアップしてAMIを作成するということなので、/mntは対象外。

EBSで/vol以下にマウントしてたらこれもimage作成の対象となる。
これがでか過ぎるとエラーがでるので要注意。
他に手段があるかもしれないけど、一時的にアンマウントしてimageを作成する。
umount /vol

完了したら/mnt以下に大量のimage.*というファイルが出来上がるので、今度はこれをS3に転送する。
ec2-upload-bundle -b (S3の保存するディレクトリ) -m image.manifest.xml -a (Access Key ID) -s (Secret Access Key)

S3の保存するディレクトリは/hogehoge-backup/20100112/等で指定する。
予めディレクトリを作って置くこと。
Access Key IDとSecret Access Keyはそれぞれ管理画面で確認できる。
1XPzt7fLWEKJ8jQDu0lyfdscImb0といった英数字の羅列。

あとはElasticfoxでAMIを登録。
imagesタブを選択後+ボタンをクリック
S3にimage.manifest.xmlというファイルが転送されているので、これのパスを指定する。
例) /hogehoge-backup/20100112/image.manifest.xml

これでプライベートなAMIが完成です。
cronの設定も生きたままです。これによって、新たにインスタンスを起動後、予期せぬ動きをするかもしれないので、一旦cronを止めてimageファイルを生成する方が幸せになれます。

0

EC2のReserved Instances

EC2では通常の従量課金制(On-Demand Instances)の他にイニシャル+従量課金制(Reserved Instances)が用意されています。
長期契約で先に多めに払ってくれたらランニング費用を安くしますよー的なもので、一般的な専用サーバーの初期費用+月額に近い。金額はEC2の方が安いと思う。

契約期間は1年と3年があるけど、3年だとアジアにデータセンターができた時に残念な思いをしそうなのでとりあえず現状の東海岸で申込んでみた。
たぶんこの認識であってると思うけど、Reserved Instancesといってもそれ専用のインスタンスが用意されているわけでもなく、ゾーンとインスタンスタイプのセットの枠買いのようなものです。
us-east-1aのm1.large枠を購入。そこに好きなAMIを突っ込むといった形。途中でAMIを変えてもOKだし使わなければその期間の費用はかかりません。

現在運用中のOn-Demand Instancesにも適用できるので、サービスを止めることなくReserved Instancesの料金を適用させることができます。

実際の例をだすとOn-Demand Instances(us-east-1aのm1.large)の場合
$0.34 * 24時間 * 365日 = $2,978.4
これをReserved Instancesに切り替えると
$910 + ($0.12 * 24時間 * 365日) = $1,961.2
となり年間$1,017.2のコスト削減となります。
おお、素晴らしい!

これだけ差がでると予定してる利用期間が11ヶ月とかでもReserved Instancesの方が得じゃないのかと思い計算したところ、
利用日数240日(約8ヶ月)を超えて使う予定があるのならReserved Instancesの方が安い。
そうでなければOn-Demand Instancesで払ってる方が安いといった結果でした。

上記の金額に転送量に応じての費用も多少かかります。

0

/mntを有効活用しよう

今回もしつこくEC2ネタ。

Filesystem サイズ 使用 残り 使用% マウント位置
/dev/sda1 9.9G 8.9G 467M 96% /
/dev/sda2 147G 34G 107G 24% /mnt
none 854M 0 854M 0% /dev/shm

上記はスモールインスタンスのサーバーの状況です。
EC2はインスタンスを立ち上げたらすぐでも使えるけれども、実際は設定をちょこちょこ変えないと本番環境としては使えません。
その代表たるものが/dev/sda1の容量。
/dev/sda1にOSが入っていてwindowsでいうところのCドライブで、/dev/sda1がDドライブになります。
この/dev/sda1というのが最大10Gとなっており、OSをインストール後は実際使えるのは5〜6Gくらいしかない状態になります。
バックアップデータ等人為的に作成するデータはもちろん/mnt(/dev/sda1)以下におけばいいのだけど、システム的に肥大化していくファイルたちも/mntで展開するようにしないといけません。
これを忘れるとあっという間にHDがいっぱいになってしまいます。

/mntに移すファイルとしては下記のようなものがあります。
1、/var/log/httpd→/mnt/log/httpd
アクセスログやエラーログの保存場所を変更ローテーションしていても少し大きなサイトなら5Gくらいのログはあっという間です。
httpd.confで設定変更

2、/var/lib/mysql/→/mnt/mysql
mySQLのデータが肥大化していくので保存先を変更。
バイナリログを吐き出す設定にしている場合はなおさら。
my.confで設定変更

3、/var/www/→/mnt/www
apacheの公開ディレクトリもサービスによってはユーザーのデータが増えたりログが増えたりするので変更。
httpd.confで設定変更

4、/home/(ユーザーディレクトリ)/→/mnt/home/(ユーザーディレクトリ)
ユーザーによってどんなファイルをおくかわかないのでユーザー作成時に/mnt以下にホームディレクトリを作るように癖付けとく。
useradd -d /mnt/home hogeで明示

もちろんシンボリックでもOK。

但しこの/mnt以下はイメージを作成しようとしても対象外となる。
イメージ化できるのは/dev/sda1のみです。
またこうしてできたAMIで新たにインスタンスを立ち上げても/mnt以下に適切なディレクトリができてないためapacheやmySQLの起動にこけるので注意。
ここは起動スクリプトでも書いとけばok。

0

Elastic Load Balansing

EC2のロードバランサーです。
先のRDSと同様でロードバランサーだけを貸してくれるサービスです。
ロードバランサーにぶら下がるwebサーバーはec2のサーバーに限ります。
設置も手軽でhealth checkもでき、落ちてるサーバーが発見されれば正常なサーバーだけでバランシングを行います。
RDSもELBにしてもサービスだけを提供するのでsshでログインしたりログをみたりすることはできません。
料金は$0.025/1h+0.008/ギガなので月2000円くらいなのでお手軽に導入できます。

新規作成
test-lbというインスタンス名のロードバランサーを作成する。
elb-create-lb test-lb --availability-zones us-east-1c --listener "protocol=HTTP, lb-port=80, instance-port=80"
そうすると下記のようにFQDNを発行してくれます。
これをCNAMEにして実際は運用します。
DNS-NAME test-lb-532214734.us-east-1.elb.amazonaws.com

ぶら下がるwebサーバーを指定
i-fab73c92というi-c6b73caeというインスタンスをぶら下げる。
この二つのコマンドでロードバランサーが動き出します。
elb-register-instances-with-lb test-lb --headers --instances i-fab73c92,i-c6b73cae

health checkの閾値を設定
30秒おきにアクセスして5秒間2度応答なかったら落ちてると判断する。
elb-configure-healthcheck test-lb --headers --target "HTTP:80/index.html" --interval 30 --timeout 5 --unhealthy-threshold 2 --healthy-threshold 2

health checkの状況を確認
elb-describe-instance-health test-lb

動作してたら
INSTANCE-ID i-fab73c92 InService
動作してなかったら
INSTANCE-ID i-c6b73cae OutOfService
となります。

ぶら下がるインスタンスを削除
削除したいインスタンス(i-fab73c92)を指定する。
elb-deregister-instances-from-lb test-lb --instances i-fab73c92

0

amazonRDS

だいぶ乗り遅れた感があるけどmySQLのみをホスティングするamazonRDSでました。
さっそく使ってるのですが、ざっと使う分には確かに便利。
インスタンスの立ち上げて使いだすまでに15分くらいです。
ただ残念ながら良くも悪くもシンプルでレプリケーションもできなければsshでログインもできないmy.cnfも編集できないとほんとmySQLを使うだけといった感じです。
致命的なのはどれくらいの負荷がかかってるのかが分からないこと。
実務では少々扱いにくいかなという印象です。

色々ログ

■DBインスタンスを作成
100ギガの容量のhogedbというデータベースを立ち上げある。
rds-create-db-instance --db-instance-identifier hoge --allocated-storage 100 --db-instance-class db.m1.small --engine MySQL5.1 --master-username hogename --master-user-password hogepass --db-name hogedb --headers

■アクセスの許可
どこからでもアクセス可能。
rds-authorize-db-security-group-ingress default --cidr-ip 0.0.0.0/0 --headers

■snapshotを作成
snapshot01というスナップショットを作成。
これを作成中I/Oが停止するらしい。
rds-create-db-snapshot -i hoge -s snapshot01

■snapshotから復元
snapsho01からhoge2というインスタンス名で復元
rds-restore-db-instance-from-db-snapshot hoge2 -s snapshot01 -c db.m1.small

■DBインスタンスを削除
最後にバックアップ(スナップショット)をとらずに削除する。
rds-delete-db-instance hoge --skip-final-snapshot

■DBのインスタンスをアップグレードする
Small DB InstanceからDouble Extra Large DB Instanceへ変更。
立ち上げたままできるのがすばらしい。
10分くらいかかって変更される。
rds-modify-db-instance myinstance -c db.m2.2xlarge -apply-immediately

下記のコマンドで状況がわかる。
activeとかdeletingとかmodifyingとか。
この辺は他のec2APIと同じ。
rds-describe-db-instances