vSphere API を使用して仮想マシンをプロビジョニングする

インフレートと eager zero を使用して仮想ディスクを扱う

Comments

シン・プロビジョニングは高速であるため、仮想マシン (VM) によく使用される手法です。ただし、シン・プロビジョニングの問題点として、使用するデータ・ストア内のストレージをオーバーコミットしてしまう場合があります。この欠点を克服するには VM に関連付けられたディスクをインフレートする必要があり、この記事ではその手法について説明します。

シック・プロビジョニングはオーバーコミットの問題を克服するための 1 つの手法ですが、その代わりにデータ・セキュリティーが犠牲になります。シック・プロビジョニングされた VM に対するデータ・セキュリティーを実現するには、VM に関連付けられたディスクを eager zero することができます。

この記事では、シン・プロビジョニング手法でプロビジョニングされた VM に関連付けられたディスクをインフレートする方法と、シック・プロビジョニング手法でプロビジョニングされた VM に関連付けられたディスクを eager zero する方法についての技術的な詳細を説明します。ただし、これらの方法の詳細を説明する前に、VMware vSphere ではどのように VM のプロビジョニングが行われるかを理解する必要があります。

VMware vSphere では、VM をプロビジョニングする方法として以下の 3 つのタイプをサポートしています。

  • シック・プロビジョニング (lazy zeroed) ― このタイプのプロビジョニングでは、デフォルトのシック・フォーマットで仮想ディスクを作成します。仮想ディスクに必要な領域は仮想ディスクの作成時に割り当てられます。物理デバイス上に残っているデータは仮想ディスクの作成時には消去されませんが、VM からの最初の書き込み時にオンデマンドでゼロが書き込まれます。
  • シック・プロビジョニング (eager zeroed) ― このタイプのシック仮想ディスクは、フォルト・トレランスなどのクラスタリング機能をサポートします。仮想ディスクに必要な領域は仮想ディスクの作成時に割り当てられます。フラット・フォーマットとは対照的に、物理デバイス上に残っているデータには仮想ディスクの作成時にゼロが書き込まれます。このフォーマットでディスクを作成するには、他のフォーマットの場合よりもはるかに時間がかかります。
  • シン・プロビジョニング ― このフォーマットを使用すると、ストレージ領域を節約することができます。シン・ディスクの場合、そのディスク・サイズとして入力される値を基に、ディスクが必要とするだけのデータ・ストア領域がプロビジョニングされます。

それぞれのプロビジョニング手法には、その手法に固有のタイプのディスクが必要です。VMware では以下の選択肢がサポートされており、これらの中から選択することができます。

  • シック (thick) ― VM をプロビジョニングしている間にファイル・ブロックへのゼロ書き込みは行われません。VM のプロビジョニングは高速です。
  • ゼロシック (zeroedthick) ― 仮想ディスクへの最初の書き込みの際、ファイル・ブロックにゼロが書き込まれます。VM のプロビジョニングは高速です。
  • シン (thin) ― ファイル・ブロックはそのブロックへの最初の書き込みの際にオンデマンドで割り当てられ、作成時のサイズはゼロです。プロビジョニング後にディスクをインフレートする必要があります。VM のプロビジョニングは高速です。
  • eager zero シック (eagerzeroed thick) ― VM の仮想ディスクを作成する際にファイル・ブロックにゼロが書き込まれます。VM のプロビジョニングは低速です。

インフレート手法

シン・ディスクをインフレートすると、割り当て済みサイズを拡張しながら、未使用のディスク全体に単純にゼロが書き込まれます。VMware vSphere にはディスク全体にゼロを書き込むために使用できる API (Application Programming Interface) が用意されています。

ステップ 1: VM とデータ・ストアを関連付ける

VM とデータ・ストアを関連付けるには、以下のコマンドを実行します。

Object datastoreObject = this.getSingleProperty("datastore", vmMor); 
// get the datastore property associated with virtual machine object

注: 上記の getSingelProperty のような独自のメソッドを使用することにより、vSphere で管理されるオブジェクト参照のうち、指定された任意の参照に関するプロパティーを vSphere から取得することができます。

特定のデータ・センターにある VM に関連付けられたすべてのデータ・ストアを取得するには、以下のコマンドを実行します。

ArrayOfManagedObjectReference datastoreMorArray = 
    (ArrayOfManagedObjectReference) datastoreOb-ject;

すべてのデータ・ストアを関連付けた後、その VM をインフレートするための特定の VMDK (Virtual Machine Disk) ファイルを検索する必要があります。これらの VMDK ファイルはデータ・ストア全体に分散している可能性があるため、その VM 名ですべてのデータ・ストア内を検索し、VMDK ファイルの絶対パスを取得する必要があります。

ステップ 2: VMDK のパスを取得する

searchDatastoreSubFolders_Task メソッドを使用して、VM に関連付けられた VMDK ファイルのパスを検索します。ステップ 1 で得られたすべてのデータ・ストアを検索するには、ホスト・プラットフォームに関連付けられたデータ・ストア・ブラウザーがなければなりません。リスト 1 は検索の方法を示しています。

リスト 1. データ・ストアを検索して VMDK ファイルへのパスを取得する
VirtualMachineRuntimeInfo vmRunInfo = 
    (VirtualMachineRuntimeInfo) this.getSingleProperty("runtime", vmMor);
ManagedObjectReference hostMor = vmRunInfo.getHost();
ManagedObjectReference datastoreBrowserMor = 
    (ManagedObjectReference) this.getSingleProperty("datastoreBrowser", hostMor);
path = new ArrayList<String>();
for (int i = 0; i < datastoreMor.length; i++) {
String dsName = (String) this.getSingleProperty("name",datastoreMor[i]);
HostDatastoreBrowserSearchSpec hostDatastoreBrowserSearchSpec = 
    new HostDatastoreBrows-erSearchSpec();
hostDatastoreBrowserSearchSpec.setMatchPattern(new String[] { vmName + ".vmdk" });
    // vmName here refers to the name of the virtual disk for that virtual machine 
    in the hypervisor
	ManagedObjectReference taskMor = 
	this.vimPort.searchDatastoreSubFolders_Task(datastoreBrowserMor,"[" + 
	dsName + "]",hostDatastoreBrowserSearchSpec);
	if (taskMor != null) {
		taskResult = "queued";
		while ((!taskResult.equals("success")) && 
		    (!taskResult.equals("error"))) {
			try {
				TaskInfo taskInfo = 
				    (TaskInfo) this.getSingleProperty("info", task-Mor);
				System.out.println("state:"	+ 
				    taskInfo.getState().getValue());
				taskResult = taskInfo.getState().getValue();
				Thread.sleep(5000L);
			} catch (InterruptedException localInterruptedException) {
				throw localInterruptedException;
			}
			if (taskResult.equals("error")) {
				return "FAILED";
			}
			if (taskResult.equals("success")) {
				TaskInfo taskInfo = 
				    (TaskInfo) this.getSingleProperty("info",taskMor);
				ArrayOfHostDatastoreBrowserSearchResults res = 
				    (ArrayOfHost-DatastoreBrowserSearchResults) 
				    taskInfo.getResult();
				HostDatastoreBrowserSearchResults[] resArray = 
				    res.getHostDatastoreBrowserSearchResults();
				for (int j = 0; j < resArray.length; j++) {
					System.out.println("folderpath:"+
					    resArray[j].getFolderPath());
					for (int k = 
					    0; k < resArray[j].getFile().length; k++) {
						System.out.println("filePath:"+ 
						    resAr-ray[j].getFile()[k].getPath());
						String tempstr = 
						    resArray[j].getFolderPath()	
						    + resAr-ray[j].getFile()[k].getPath();
						path.add(tempstr);
					}//end for
				}//end for
			}//end if
		}//end while

	}//endif
}//end for

VM に関連付けられた VMDK ファイルのパスをすべて取得したら、vSphere inflate API を使用して各ディスクでインフレートを呼び出します。それをステップ 3 で示します。

ステップ 3: VMDK ファイルをインフレートする

今度は、ステップ 2 で見つかったパスを inflateVirtualDisk_Task メソッドに渡し、VMDK ファイルをインフレートします (リスト 2)。

リスト 2. VMDK ファイルをインフレートする
for (int i = 0; i < path.size(); i++) {
System.out.println("this.vimPort.inflateVirtualDisk_Task("+ 
    this.virtualDiskManagerMor + "," + path.get(i) + ","+ dataCenterMor + ");");
ManagedObjectReference taskMor = 
    this.vimPort.inflateVirtualDisk_Task(this.virtualDiskManagerMor,(String) 
    path.get(i), dataCenterMor);
	if (taskMor != null) {
		taskResult = "queued";
		while ((!taskResult.equals("success"))&& (!taskResult.equals("error"))) {
			try {
				System.out.println("task type:" + taskMor.getType());
				TaskInfo taskInfo = 
				    (TaskInfo) this.getSingleProperty("info",taskMor);
				System.out.println("state:" + 
				    taskInfo.getState().getValue());
				taskResult = taskInfo.getState().getValue();
				Thread.sleep(5000L);
			} catch (InterruptedException localInterruptedException) {
				throw localInterruptedException;
			}
			if (taskResult.equals("error")) {
				TaskInfo taskInfo = 
				    (TaskInfo) this.getSingleProperty("info",taskMor);
				System.out.println("error in inflateVirtualDisk_Task:" + 
				    taskInfo.getError().getLocalizedMessage());
				return “failed”;
			}
			if (taskResult.equals("success")) {
				return "SUCCESS";
			}
		}//end while
	}//end if
}//end for

eager zero 手法

シック・ディスクを eager zero すると、VM に割り当てられた未使用領域全体にゼロが書き込まれます。そのための API が VMware vSphere に用意されています。インフレート手法のステップ 1 と 2 を実行し、VM に関連付けられた VMDK のデータ・ストア内のパスを取得します。次に、リスト 3 のように vSphere から eager zero シック API を呼び出し、ディスク全体にゼロを書き込みます。

リスト 3. eager zero シック API を呼び出し、ディスクにゼロを書き込む
for (int i = 0; i < path.size(); i++) {
System.out.println("this.vimPort.inflateVirtualDisk_Task("+ 
    this.virtualDiskManagerMor + "," + path.get(i) + ","+ 
    dataCenterMor + ");");
ManagedObjectReference taskMor = this.vimPort. eagerZeroVirtualDisk_Task 
    (this.virtualDiskManagerMor,(String) path.get(i), dataCenterMor);
	if (taskMor != null) {
		taskResult = "queued";
		while ((!taskResult.equals("success"))&& 
		    (!taskResult.equals("error"))) {
			try {
				System.out.println("task type:" + taskMor.getType());
				TaskInfo taskInfo = 
				   (TaskInfo) this.getSingleProperty("info",taskMor);
				System.out.println("state:" + 
				    taskInfo.getState().getValue());
				taskResult = taskInfo.getState().getValue();
				Thread.sleep(5000L);
			} catch (InterruptedException localInterruptedException) {
				throw localInterruptedException;
			}
			if (taskResult.equals("error")) {
				TaskInfo taskInfo = 
				   (TaskInfo) this.getSingleProperty("info",taskMor);
				System.out.println("error in inflateVirtualDisk_Task:" + 
				    taskInfo.getError().getLocalizedMessage());
				return “failed”;
			}
			if (taskResult.equals("success")) {
				return "SUCCESS";
			}
		}//end while
	}//end if
}//end for

まとめ

この記事で説明した手法は、VM のディスクにゼロを書き込むための最も単純な方法です。これらの手法を使えば、ユーザーは環境ごとに異なる可能性がある適切な検索パターンでデータ・ストアをブラウズする方法に、より一層集中することができます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing
ArticleID=947036
ArticleTitle=vSphere API を使用して仮想マシンをプロビジョニングする
publish-date=10032013