So-net無料ブログ作成

EC2 SpotInstanceを使う [Amazon AWS]

Amazon EC2 のSpotInstanceは割とお安い訳ですよ。例えば、c3.2xlargeなら、定価0.511ドル/時のところ、SpotInstance価格ではなんと0.108ドル/時!!(この記事かいてる時点での価格)金利手数料はジャp(チガウ

SpotInstanceの仕組みとしては、Amazonさんの余剰リソースを安く使わせてもらおうというコンセプトのようで、その時のAmazonさんのリソースの空き具合に応じて「時価」が変動しますが、その時価よりも高い「スポット価格」を提示(入札)しているインスタンスに限って、リソースを使用してインスタンスを実行できるというもの。
例えば、今0.108ドル/時なので、「スポット価格」として0.2ドル/時を提示していれば、そのインスタンスは実行できるという感じ。
時折その時の「時価」がボーンと跳ね上がることがありますので、永続的に使用したいなーっていうのには向かないみたいですね。
一時的なバッチ処理をしたいとか、開発テストに使いたいとかそういう用途なら結構イケそうです。(Amazonさんもそう言ってますし。)

で、それを使ってみたいじゃないですか。コマンドラインから

という訳で試してみました。

スポットインスタンスはシャットダウン等するとインスタンス自体がTerminatedになってしまう模様(違ったらすんません)なので、1からインスタンスを立てて使おうという用途よりも、すでにあるインスタンスをスポットインスタンスで使うという感じが向いているのでしょうか。(違ったらすんません)

そんな訳でここでは「既存のEC2インスタンスからAMIを作成して、それをスポットインスタンスとして起動する」という作戦で実験したいと思います。

手順としてはこんな感じ。

① 既存のインスタンスからAMIを作成する
② (AMIの作成には時間がかかるので完成するのを待つ)
③ スポットインスタンスをリクエストする
④ (スポットリクエストが「履行中」のステータスになるのを待つ)
⑤ 必要に応じてタグを付けたりする



① 既存のインスタンスからAMIを作成する

 まず、既存のインスタンスからAMIを作成します。使用するコマンドは aws ec2 create-imageです。先に、既存のインスタンスのインスタンスIDを調べておく必要があります。

 aws ec2 create-image --instance-id (複製元となるインスタンスID) --name (AMIに付ける名前) --description (AMIに付ける説明文) --no-reboot

 「--no-reboot」オプションを省略すると、複製元となるインスタンスが強制的にリブートされます。問答無用です。このため、業務で使用中のインスタンスを指定した時などは悲しい思いをするかも知れないので要注意です。
 今のところ「--no-reboot」を付けたせいで問題になったということは経験していませんが、もしかしたら問題が発生するかもしれない?的な覚悟は一応しておいてください。(AmazonLinux以外の場合は特に…。)

 awsコマンドの実行結果は標準出力にjson型式で表示されますので、コイツを jqコマンドでパースしてやれば、AMIのIDが取得できます。取得すべき項目名は「.ImageId」です。


② (AMIの作成には時間がかかるので完成するのを待つ)

 AMIの作成には割と時間がかかりますね。ストレージの大きさにもよりますが。AmazonLinuxの標準(?)サイズの8GBでも数分はかかります。長いと10分以上要する事もあったりなかったり…。

 コマンドラインから完成したかどうかを確認したい場合は、aws ec2 describe-imagesコマンドで確認できます。

 aws ec2 describe-images --image-ids (AMIのID)

 作成が完了すると、「.Images[].State」に「available」が入ります。


③ スポットインスタンスをリクエストする

 はい。この記事の本丸です。(笑)
 スポットインスタンスをリクエストします。スポットインスタンスをリクエストすると、「リクエスト」が生成され、それにインスタンスが紐付く形になります。複数のインスタンスを同時に起動することも出来ますが、その場合は1個のインスタンスに1個のリクエストが関連付く格好になるので、スポットリクエストも複数作成されることとなります。スクリプトで処理する場合は配列処理するなり、ループ処理するなりしてください。

 使用するコマンドはaws ec2 request-spot-instancesです。
 ひとまず必要最低限のオプションとしてはこんな感じです。
 aws ec2 request-spot-instances --spot-price (提示する入札価格) --launch-specification (インスタンスをローンチするための情報)

 「提示する入札価格」は、お好みでどうぞ。単位はドル/時っぽいです。
 「インスタンスをローンチするための情報」には、最低でも次のような情報を指定することになります。
{
  "ImageId": "(AMIのID)",
  "InstanceType": "(インスタンスの種類)",
  "IamInstanceProfile": {
    "Arn": "(AMIインスタンスロールのArn)"
    },
  "SecurityGroupIds": ["(セキュリティグループID)"]
}


 VPCの中に入れたい時などは、VPCIDとかサブネットIDとかそういった情報も必要になってくると思います。(まだVPCの中に入れてテストしていないので…^^;)

 インスタンスをローンチするための情報をjson型式でファイルに書き出したら、file:///tmp/launch.json とかそんな感じで指定してコマンドに渡してやります。

 このコマンドを実行すると、実行結果がこれまたjson型式で返ってきますので、これまたjqコマンドで適宜パースしてやります。なお、「リクエストID」がこの後に必要となりますから、保存することをお忘れ無く。(リクエストIDは「.SpotInstanceRequests[].SpotInstanceRequestId」という項目に入ってきます。)


④ (スポットリクエストが「履行中」のステータスになるのを待つ)
 スポットインスタンスを生成した直後はまだインスタンスは存在しません。
 スポットリクエストが「履行中」というステータスになるのを待つ必要があります。確認するコマンドはaws ec2 describe-spot-instance-requestsです。コマンドラインで特定のリクエストIDだけ表示することが出来ないっぽいので、jqコマンドで必要な項目だけselectしてやる必要があります。
 おそらくこんな感じ。

aws ec2 describe-spot-instance-requests | jq '.SpotInstanceRequests[] | select ( .SpotInstanceRequestId == "(スポットインスタンスのリクエストID)" ) | .Status.Code'

 「.SpotInstanceRequests[].Status.Code」という項目にスポットインスタンスの状態が入っています。こいつが「fulfilled」になると、インスタンスが使用可能な状態となっていることを表します。
 また、スポットインスタンスの状態が「fulfilled」になった時、そのリクエストの「.SpotInstanceRequests[] .InstanceId」という項目を見ると、このリクエストに紐付いているEC2インスタンスのインスタンスIDが判明します。


⑤ 必要に応じてタグを付けたりする
 当たり前のように、ローンチされたばかりのEC2インスタンスにはタグも何も無いので(Nameタグすらない!!)、適宜タグを付けてあげましょう。



なお、注意点としては…
・インスタンスをshutdownするとインスタンスがterminatedになるっぽい
・スポットインスタンスの上限は20個まで(インスタンスサイズによっては10とかいう場合も有る)
・必ずしも「定価」より安いとは限らない模様
・Amazonさんの余剰リソースの状況によっては突然terminatedになる恐れがあるらしい

スポットインスタンスの上限を拡大してもらえるのかどうかは不明です。申請フォームには無かったようですが…??(私の目が節穴である可能性に注意)

それにして、安いよねー。

#トラフィック課金は高いけどなー。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

メッセージを送る