使用 vSphere API 配置虚拟机

使用解压缩 (inflate) 和快速归零 (eagerzero) 来操纵虚拟磁盘

Comments

精简配置是面向虚拟机(VM)的一种流行技术,因为它很快。不过,这种配置的问题在于,它可能导致它所用的数据存储中出现过量使用存储的情况。为了克服这个缺点,您必须解压缩与 VM 有关联的磁盘,本文将解释这种技术。

密集配置(thick provisioning)是克服过量使用问题的方法之一,但它的代价是数据安全性。为了在密集配置的虚拟机上实现数据安全性,您可以快速归零与 VM 有关联的磁盘。

本文提供了有关如何使用精简配置技术解压缩与 VM 有关联的磁盘,以及如何使用密集配置技术快速归零与 VM 有关联的磁盘的技术细节。不过,在开始详细介绍这些技术之前,您必须了解 VM 配置如何在 VMware vSphere 中工作的。

VMware vSphere 支持三种类型的 VM 配置:

  • 密集配置延迟置零(Thick provision lazy zeroed)。这种类型的配置创建了一个默认的厚格式的虚拟磁盘。虚拟磁盘所需的空间是在创建虚拟磁盘时分配的。在创建过程中不会清楚保留在物理设备上的数据,但在首次从 VM 执行写操作时会根据需要将数据清零。
  • 密集配置快速归零(Thick provision eager zeroed)。这种类型的密集虚拟磁盘支持集群特性,比如容错。虚拟磁盘所需的空间是在创建虚拟磁盘时分配的。与平面格式相反,在创建虚拟磁盘时,保留在物理设备上的数据被清零。创建这种格式的磁盘可能比创建其他格式所需的时间长。
  • 精简配置。使用这种格式可以节省存储空间。对于薄盘(thin disk),可根据您为磁盘大小所输入的值,配置磁盘所需的尽可能多的数据存储空间。

每个配置技术都要求它自己的磁盘类型。您可以选择以下 VMware 支持的选项:

  • Thick。在配置 VM 时,文件块也不会被清零。VM 配置是快速的。
  • Zeroedthick。在第一次写入虚拟磁盘时,可以根据需要将文件块置零。VM 配置是快速的。
  • Thin。在第一次写入块时,可以根据需要分配文件块,在创建时,存储的大小为零。在配置后必须解压缩磁盘。VM 配置是快速的。
  • Eagerzeroed thick。在创建 VM 的虚拟磁盘时,文件块被清零。VM 配置是缓慢的。

解压缩技术

解压缩薄盘只是在扩大所分配的大小时将整个未使用的磁盘清零。VMware vSphere 提供了一个应用程序编程接口(API),您可以使用它来将整个磁盘清零。

步骤 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 找到要解压缩的特定 Virtual Machine Disk (VMDK) 文件。因为这些 VMDK 文件可能会分散在整个数据存储中,所以您必须用 VM 名称在所有数据存储中进行搜索,并检索其绝对路径。

步骤 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

快速归零技术

快速归零紧密磁盘,将分配给 VM 的所有未使用空间清零,并且 VMware vSphere 针对该用途提供了一个 API。完成 解压缩技术 的步骤 1 和步骤 2,在数据存储中检索与 VM 有关联的 VMDK 路径。然后,从 vSphere 调用 eagerzero thick API,清零整个磁盘,如清单 3 所示。

清单 3. 调用 eagerzero thick 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=10
Zone=Cloud computing
ArticleID=958256
ArticleTitle=使用 vSphere API 配置虚拟机
publish-date=12232013