第10回:EBSに関するEucalyptusのAPI


 前回までで、インスタンスを操作するAPIとネットワークを操作するAPIについて説明しました。今回はEBSに関するAPIの説明をしますが、基本的な使い方は第8回を参照してください。

EBSを操作するAPI

 ファイルサーバーやデータベースサーバーなどデータの永続化が必要な用途にインスタンスを使用する場合、データの保存先としてEBSを利用する必要があります。EBSにはボリュームのその時点でのスナップショットをとる機能も備わっており、非常に便利な機能です。EBSを操作するAPIには、下記のAPIがあります。

【EBSを操作するAPI】
API説明
CreateVolumeボリュームを作成します。
DeleteVolumeボリュームを削除します。
AttachVolumeボリュームをインスタンスに取り付ける。
DetachVolumeボリュームをインスタンスから取り外す。
DescribeVolumesボリュームの一覧を取得します。
CreateSnapshotボリュームのスナップショットを作成します。
DeleteSnapshotスナップショットを削除します。
DescribeSnapshotsスナップショットの一覧を取得します。

 

ボリュームを作成する

 ボリュームの作成には、CreateVolume APIを使用します。CreateVolume APIを呼び出す際のパラメータと説明は下記の通りです。

【CreateVolumeのパラメータ】
パラメータ説明必須/任意
Sizeボリュームのサイズを指定します。SnapshotIdと本パラメータのどちらかが必須です。1場合により必須
SnapshotIdボリュームの元となるスナップショットのIDを指定します。Sizeと本パラメータのどちらかが必須です。snap-12345678場合により必須
AvailabilityZoneボリュームを利用するゾーンを指定します。Eucalyptusでは、クラスタ名をしてします。cluster01必須

 

 ボリュームを作成方法にはサイズを指定する方法とスナップショットからボリュームに変換する方法の2種類があります。サイズを指定してCreateVolume APIを呼び出すとレスポンスとして下記のようなXMLが返却されます。

【botoでのAllocateAddress】
<?xml version="1.0"?>  <CreateVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">    <requestId>992a5b76-a235-460f-aba7-8f03ab1b2284</requestId>    <volumeId>vol-D2FA0A1A</volumeId>    <size>1</size>    <availabilityZone>open</availabilityZone>    <status>creating</status>    <createTime>2011-01-08T12:56:46.969Z</createTime>    <attachmentSet/>  </CreateVolumeResponse>

 

 上記のレスポンスXMLに含まれる情報のうち重要な情報は下記の通りです。

【CreateVolumeの戻り値】
API説明
volumeIdボリュームのIDです。
sizeボリュームのサイズです。単位はGBです。
availabilityZoneボリュームが利用可能なゾーンです。
statusボリュームのステータスです。作成時は「creating」となり利用可能になった時点で「available」となります。
createTimeボリュームが作成された時刻です。
attachmentSetボリュームがインスタンスにアタッチされている場合の情報です。インスタンスIDとデバイスが含まれます。

 

 下記にbotoとRightAwsによるサンプルコードを示します。いずれのセットアップ方法と基本的な内容は第8回を参照してください。

【botoでのCreateVolume】
 Botoではコネクションのcreate_volumeメソッドを呼び出してボリュームを作成します。

# サイズを指定してボリュームを作成する場合
volume = connection.create_volume(size=10, zone='cluster0')

# 作成したボリュームの情報を表示
# boto.ec2.volume.Volumeクラスのインスタンスが返却される
print volume.id, volume.size, volume.status, volume.zone

# スナップショットからボリュームを作成する場合
volume = connection.create_volume(snapshot_id='snap-12345678', zone='cluster0')
print volume.id, volume.snapshot_id, volume.status, volume.zone

 

【RightAwsでのCreateVolume】
# 引数は、スナップショットID, サイズ(GB単位), ゾーン名
# 新規のボリュームを作る場合
result = @ec2.create_volume(nil, 10, 'cluster0')

# 戻り値は以下のような情報が返る
pp result
#=> {:aws_status=>"creating",
# :zone=>"cluster0",
# :aws_created_at=>"2011-01-08T11:38:54.83Z",
# :aws_size=>1,
# :aws_id=>"vol-12345678"}

# 既存のスナップショットからボリュームを作る場合
# サイズに 0 を指定した場合はスナップショットと
# 同じサイズのボリュームを作成する
result = @ec2.create_volume('snap-12345678', 0, 'cluster0')

# 戻り値は以下のような情報が返る
pp result
#=> {:aws_status=>"creating",
# :zone=>"cluster0",
# :snapshot_id=>"snap-12345678",
# :aws_created_at=>"2011-01-08T11:48:09.635Z",
# :aws_size=>0,
# :aws_id=>"vol-12345678"}

 

ボリュームを削除する

 ボリュームの削除には、DeleteVolume APIを使用します。DeleteVolume APIを呼び出す際のパラメータには削除対象のボリュームのIDを指定します。

【botoでのDeleteVolume】
# 戻り値は True か例外が返る
result = connection.delete_volume('vol-12345678')

 

【RightAwsでのDeleteVolume】

# 引数は、ボリュームID
result = @ec2.delete_volume('vol-12345678')

# 戻り値は true か例外が返る
pp result #=> true

 

ボリュームの一覧を取得する

 ボリュームの一覧を取得するには、DescribeVolumes APIを使用します。DescribeVolumes APIを呼び出す際のパラメータにはボリュームのIDを複数個指定することができます。なお指定しない場合はそのユーザのすべてのボリュームが返却されます。

【botoでのDescribeVolumes】
volumes = connection.get_all_volumes()

# ボリュームの情報を表示する
for volume in volumes:
    print volume.id # ボリュームのID
    if volume.size:
        print volume.size
    if volume.snapshot_id:
        print volume.snapshot_id
    print volume.status
    print volume.zone
    print volume.create_time
    if volume.status == 'in-use':
        # in-useの場合はインスタンスへのアタッチ情報があります
        print volume.attach_data.instance_id
        print volume.attach_data.device
        print volume.attach_data.attach_time

# ボリュームIDを指定する場合
volume_ids = ['vol-12345678', 'vol-87654321']
volumes = connection.get_all_volumes(volume_ids)

 

【RightAwsでのDescribeVolumes】
# 引数を省略した場合は所有する全てのボリューム情報が返る
# 引数は、ボリュームID を渡す。複数渡す場合は Array でも可。
result = @ec2.describe_volumes(['vol-12345678', 'vol-87654321'])

# 戻り値は以下のような情報が返る
pp result
#=> [{:aws_attached_at=>"2011-01-08T12:21:46.148Z",
#     :aws_status=>"in-use",
#     :zone=>"cluster0",
#     :aws_instance_id=>"i-12345678",
#     :aws_created_at=>"2011-01-08T11:38:54.83Z",
#     :aws_size=>1,
#     :aws_id=>"vol-12345678",
#     :aws_device=>"/dev/sdb",
#     :aws_attachment_status=>"attached"},
#     :aws_status=>"available",
#      :zone=>"cluster0",
#     :snapshot_id=>"snap-12345678",
#     :aws_created_at=>"2011-01-08T11:48:09.635Z",
#     :aws_size=>1,
#     :aws_id=>"vol-87654321"}]

 

ボリュームを取り付ける

 ボリュームをインスタンスに取り付けるには、AttachVolume APIを使用します。AttachVolume APIを呼び出す際のパラメータには以下のものがあります。

【AttachVolumeのパラメータ】
パラメータ説明必須/任意
VolumeIdアタッチするボリュームのIDを指定します。vol-12345678必須
InstanceIdアタッチするインスタンスのIDを指定します。i-12345678必須
Deviceアタッチするインスタンスのデバイスを指定します。/dev/sdb必須

 

【botoでのAttachVolume】
# 戻り値は True か例外が返る
result = connection.attach_volume(
    volume_id='vol-12345678',
    instance_id='i-12345678',
    device='/dev/sdb')
# 位置引数で指定する場合
result = connection.attach_volume('vol-12345678', 'i-12345678', '/dev/sdb')

 

【RightAwsでのAttachVolume】
# 引数は、ボリュームID, インスタンスID, デバイス名
result = @ec2.attach_volume('vol-12345678', 'i-12345678', '/dev/sdb')

# 戻り値は以下のような情報が返る
pp result
#=> {:aws_attached_at=>"2011-01-08T12:27:23.599Z",
# :aws_instance_id=>"i-4E6A0821",
# :aws_id=>"vol-5C210634",
# :aws_device=>"/dev/sdb",
# :aws_attachment_status=>"attaching"}

 

ボリュームを取り外す

 ボリュームをインスタンスから取り外すには、DetachVolume APIを使用します。DetachVolume APIを呼び出す際のパラメータには以下のものがあります。

【DetachVolumeのパラメータ】
パラメータ説明必須/任意
VolumeId取り外すボリュームのIDを指定します。vol-12345678必須
InstanceIdボリュームを取り外すインスタンスのIDを指定します。i-12345678任意
Deviceボリュームを取り外すインスタンスのデバイスを指定します。/dev/sdb任意

 

 ボリュームIDを指定しただけでも取り外すことができますが、より厳密に指定ためにインスタンスIDとデバイスも指定することが出来ます。

【botoでのDetachVolume】
# 戻り値は True か例外が返る
result = connection.detach_volume('vol-12345678')

# インスタンスIDやデバイスも指定する場合
result = connection.detach_volume('vol-12345678', 'i-12345678', '/dev/sdb')

 

【RightAwsでのDetachVolume】
# 引数は、ボリュームID
result = @ec2.detach_volume('vol-12345678')

# 戻り値は以下のような情報が返る
pp result
#=> {:aws_attached_at=>"2011-01-08T12:21:46.148Z",
# :aws_instance_id=>"i-12345678",
# :aws_id=>"vol-12345678",
# :aws_device=>"/dev/sdb",
# :aws_attachment_status=>"detaching"}

 

スナップショットを作成する

 ボリュームのスナップショットを作成するには、CreateSnapshot APIを使用します。CreateSnapshot APIを呼び出す際には、パラメータとしてボリュームのIDを指定します。

【botoでのCreateSnapshot】
snapshot = connection.create_snapshot('vol-12345678')
# 戻り値はboto.ec2.snapshot.Snapshotクラスのインスタンスが返る
print snapshot.id, snapshot.status, snapshot.start_time

 

【RightAwsでのCreateSnapshot】
# 引数は、ボリューム
result = @ec2.create_snapshot('vol-12345678')

# 戻り値は以下のような情報が返る
pp result
#=> {:aws_progress=>"0%",
# :aws_owner=>"vtaro",
# :aws_started_at=>"2011-01-08T11:42:18.826Z",
# :aws_status=>"pending",
# :aws_volume_size=>10,
# :aws_id=>"snap-12345678",
# :aws_volume_id=>"vol-12345678"}

 

スナップショットを削除する

 スナップショットを削除するには、DeleteSnapshot APIを使用します。DeleteSnapshot APIを呼び出すには、パラメータとして削除したいスナップショットのIDを指定します。

【botoでのDeleteSnapshot】
# 戻り値は True か例外が返る
result = connection.delete_snapshot('snap-12345678')

 

【RightAwsでのDeleteSnapshot】
# 引数は、スナップショットID を渡す
result = @ec2.delete_snapshot('snap-87654321')

# 戻り値は true か例外が返る
pp result #=> true

 

スナップショットの一覧を取得する

 スナップショットの一覧を取得するには、DescribeSnapshots APIを使用します。DescribeSnapshots APIを呼び出す際には、パラメータとして情報を取得したいスナップショットのIDを複数個指定することが出来ます。なお、指定しない場合はユーザのすべてのスナップショットの情報が取得できます。

【botoでのDescribeSnapshots】
snapshots = connection.get_all_snapshots()
# 戻り値はboto.ec2.snapshot.Snapshotクラスのインスタンスのリストが返る
for snap in snapshots:
    print snap.id, snap.volume_id, snap.start_time
    print snap.status, snap.progress

# スナップショットIDを指定する場合
snapshot_ids = ['snap-12345678', 'snap-87654321']
snapshots = connection.get_all_snapshots(snapshot_ids)

 

【RightAwsでのDescribeSnapshots】
#= DescribeSnapshots
# 引数を省略した場合は所有する全てのスナップショット情報が返る
# 引数は、スナップショットID を渡す。複数渡す場合は Array でも可。
result = @ec2.describe_snapshots(['snap-12345678', 'snap-87654321'])

# 戻り値は以下のような情報が返る
pp result
#=> [{:aws_progress=>"100%",
# :aws_owner=>"vtaro",
# :aws_started_at=>"2011-01-08T11:42:18.826Z",
# :aws_status=>"completed",
# :aws_volume_size=>1,
# :aws_id=>"snap-12345678",
# :aws_volume_id=>"vol-12345678"},
# {:aws_progress=>"12%",
# :aws_owner=>"vtaro",
# :aws_started_at=>"2011-01-08T12:29:54.328Z",
# :aws_status=>"pending",
# :aws_volume_size=>-1,
# :aws_id=>"snap-87654321",
# :aws_volume_id=>"vol-12345678"}]

 

次回は、イメージを操作するAPIについて

 これでボリュームとスナップショットを操作するプログラミングができるようになりました。次回は仮想マシンのイメージを操作するAPIについて説明します。

 


羽深 修
Eucalyptus歴はまだ1年ですが、周囲からはEucalyptus中毒と勘違いされているようです。Japan Eucalyptus User Groupの活動に参加し、オープンソースカンファレンスでネタなどを披露しています。度々Eucalyptusへのパッチも書いてます。ちなみに仕事ではCentOS + Xenという環境でEucalyptusを利用していますが、自宅のEucalyptus環境はGentoo Linux + KVMで動かしています。

志田 隆弘
主にEucalyptusやクラウドとはあまり関係のない分野でちょこちょこと活動していました。Eucalyptusはバージョン 1.3の頃からいじり始め、かれこれ2年近くEucalyptusに浸かった生活をしています。Eucalyptus 1.4が出たタイミングで、Tanacasinoという名前のGUIクライアントを作ったりしていました。最新のEucalyptusで動作するので、ぜひ使ってみてください。

田中 智文
志田さんとともに初期の頃からEucalyptusの調査・検証・使用してきました。志田さんの作成したTanacasinoのメンテナンスと機能拡張を行っています。新婚ほやほやなので家でのハック活動時間が少ないですが、Walrus Clientを作ってみたりbotoを使ってEucalyptusを操作して遊んでいます。

 

関連情報
(羽深 修/志田 隆弘/田中 智文)
2011/1/21 06:00