在软件开发和测试中,您经常需要同时创建一批虚拟机。您必须查找并复制一个模板虚拟映像,修改其显示名称和硬件设置,并解决网络接口硬件地址冲突。与此同时还需要完成网络设置、主机名和域设置的配置 — 这些工作很快就变成了体力活。

在本文中,查看如何开发一种自动化虚拟机部署解决方案,以帮助您快速自动地部署和激活一批自配置的虚拟机。这种方法还允许您在系统启动后对各个已部署虚拟机独立运行自定义应用程序。

自动化 VM 部署的架构和工作流程

我们要提供的自动化虚拟机部署解决方案主要包含两个部分 - 虚拟机部署管理器(Virtual Machine Deployment Manager,VDM)和虚拟机配置管理器(Virtual Machine Configuration Manager,VCM)。

虚拟机部署管理器负责处理用户的 VM 部署请求,例如复制虚拟映像、配置 VM 硬件设置及在 VM 管理程序中注册 VM

虚拟机配置管理器安装在用作 VM 模板的虚拟映像中;它将在系统启动后自动配置 VM。图 1 显示了自动化 VM 部署解决方案的架构和工作流程。

图 1. 自动化 VM 部署框架的架构

 

正如您所见,VDM 包含三个部分:

  • VDM 引擎,它是 VDM 的核心。
  • VM 部署任务是特定 VM 部署任务的描述文件,在一定程度上是用户的配置文件。
  • VM 模板定义(VM Template Definition,VTD)文件定义诸如 VM 模板的位置和描述之类的 VM 模板信息。VM 模板是在复制时作为源 VM 的虚拟机。

一般地,VM 部署过程包含以下步骤:

  1. VDM 将读入 VM 部署任务。
  2. VDM 将浏览包含 VTD 文件的目录以查找相应的 VM 模板,并将 VM 模板复制到部署任务文件中指定的目标位置。
  3. 在复制源 VM 之后,VDM 将收集所有配置数据,将其存档到 ISO 文件中,然后将该文件复制到复制的 VM 的目标位置中。
  4. VDM 将根据 VM 部署任务文件中定义的配置修改已复制 VM 的硬件设置;它将创建一个 CD-ROM 设备以装入在第 3 步中创建的 ISO 文件。
  5. 最后一个部署步骤是调用 VM 管理程序工具以在 VM 管理程序服务器中注册 VM,然后再启动该 VM。

第 5 步是可选的;用户可以通过配置 VM 部署任务文件来取消这个操作。VM 管理程序可以是 VMware 服务器、Xen 等。本文的样例实现将使用 VMware 服务器作为 VM 管理程序服务器。

VCM 是安装在 VM 模板中的。在系统启动后,它将自动启动并搜索包含配置数据的 CD,然后启动其中的配置应用程序以完成所有预定义的工作。

创建自配置的模板 VM

很明显,要让 VM 在系统启动后进行自配置,用作模板的源 VM 必须是自配置的。要创建一个自配置的 VM 模板,必须在初始创建后用 VCM 安装源 VM,如图 2 所示。

 

VCM 的主要功能是找到标签为 VMCONIFG 的 VM 配置 CD,并在系统启动后运行其中的配置应用程序。由于源 VM 可以是 Linux®、Windows® 或其他操作系统,因此不同操作系统的 VCM 是不同的。在本文的样例代码中,提供了适用于 Linux 和 Windows 的 VCM。

适用于 Linux 的 VM 配置管理器

Linux VM 配置管理器将在安装后被注册为 Linux 服务。它将在系统第一次启动时运行。在启动时,它将执行配置,然后在配置完成时注销并将自身删除。

要安装适用于 Linux 的 VCM,请将 VCM 包复制到源 VM 中,将其解压缩到某个目录中,并运行 VCM 安装程序 install.sh。清单 1 显示了 install.sh 的工作原理。

清单 1. VCM 安装程序 install.sh 的样例代码片段

...
VCM_HOME=$(cd $(dirname $0);pwd)
start=`getStartNum`
stop=`getStopNum`
sed -e "s!^VCM_HOME=.*!VCM_HOME=$VCM_HOME!;/
  s!^# chkconfig: 35!# chkconfig: 35 $start $stop!"/
  "$VCM_HOME/vmconfigmgr" > "/etc/init.d/vmconfigmgr"
chmod +x "/etc/init.d/vmconfigmgr"
echo "Register service vmconfigmgr"
chkconfig --add vmconfigmgr
if [ $? -eq 0  ];then
    echo "Install Complete Successfully!"
else
    echo "Install Failed."
Fi

由于所有配置应用程序和数据都保存在 VM 配置 CD 中,因此 VCM 将首先查找 CD 并将其装入到 /media/VMCONFIG 中,然后再执行配置。清单 2 显示了 Linux VCM 在系统启动后如何查找 VM 配置 CD。

清单 2. VCM 查找并装入 VM 配置 CD 的样例代码

LABEL="VMCONFIG"
VM_CFG_DIR=/media/$LABEL
for device in `dmesg | grep "^.*:.*CD-ROM" | awk -F':' '{print $1}'`
do
    volumeName=`volname "/dev/$device" | awk '{print $1}'`
    PrintString "CD-ROM Drive: $device | Label: $volumeName"	
    if [ "$volumeName" == "$LABEL" ];then
        PrintString "VM Configuration CD-ROM is: /dev/$device"
        # Mount the CD-ROM 
        mkdir -p "$VM_CFG_DIR"        
        mount -t iso9660 -o ro,nosuid,nodev,utf8,uid=0 "/dev/$device" "$VM_CFG_DIR" 
        break
    fi
done

适用于 Windows 的 VM 配置管理器

安装后,Windows VM 配置管理器将创建一项预定任务,这项任务将在系统启动后运行。像适用于 Linux 的 VCM 一样,Windows VCM 也将在第一次运行后删除预定任务。

要安装 Windows VCM,请将 Windows VCM 包复制到 Windows VM 模板中,将其解压缩到某个目录中,然后运行 install.bat。清单 3 显示了 install.bat 的工作原理。

清单 3. 安装 Windows VCM 的样例代码

@echo offset VCM_HOME=%~dp0REM Create scheduled task to run VM Configuration Manager when system bootsschtasks /create /tn "VMCONFIG"  /tr %VCM_HOME%vmconfigmgr.bat /sc onstart /ru "System"@echo on

类似于 Linux VCM,Windows VCM 也需要知道 VM 配置 CD 的盘符。Windows VCM 将使用 WMI 脚本完成此工作。清单 4 显示了 VB 脚本。

清单 4. Windows VCM 获得 VM 配置 CD 的盘符所使用的 VB 脚本样例代码

Function getDriveLetter(label)
	Const wbemFlagReturnImmediately = &h10
	Const wbemFlagForwardOnly = &h20
	strComputer="."
	driveLetter=""
	Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/CIMV2")
	Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_CDROMDrive", "WQL", _
                                          wbemFlagReturnImmediately + 
                                           wbemFlagForwardOnly)
	For Each objItem In colItems
		WScript.Echo "Drive: " & objItem.Drive & "  VolumeName: " 
                      & objItem.VolumeName  & "  Status: " & objItem.Status
		If StrComp(objItem.VolumeName, label) = 0 Then
			driveLetter=objItem.Drive
			WScript.Echo "driveLetter: " & driveLetter
			Exit For 
		End If  
	Next
	getDriveLetter=driveLetter
End Function

drive=getDriveLetter("VMCONFIG")

在将 VCM 安装到源 VM 中之后,源 VM 将变成自配置的 VM 模板。请将其关闭并保存到某个位置。

创建 VM 模板定义文件

VM 模板可以存储在不同的位置,因此 VM 部署管理器需要一种查找某个 VM 模板所在位置的机制。VM 模板定义文件是专门为此设计的;它将描述 VM 模板的属性。

单个 VTD 文件将指向单个 VM 模板。所有 VTD 文件都存储在 VDM 的 vtds 文件夹中。VDT 文件的文件名类似 OSName.vtd(其中 OSName 是用作区分 VM 模板的关键字)。例如,您可以使用 SLES10SP2.vtd 作为指向 SLES 10 SP2 VM 模板的 VTD 的文件名。清单 5 显示了 SLES10 SP2 VM 模板的样例 VTD。

清单 5. SLES 10 SP2 VM 模板的样例 VTD

# VM Template Definition File# OS Type of the template VM, possible values are Windows, Linux.OSType=Linux# Description of the VM template.Description=SuSE Linux Enterprise Server 10 SP2# Directory where the VM template locates in.SRCVMDIR=/local/vmware/SuSE Linux Enterprise Server 10 SP2

创建 VM 部署任务

现在所有准备工作均已完成,您可以开始创建 VM 部署任务。VM 部署任务是用 VM 部署任务文件定义的。一项 VM 部署任务将定义部署某个 VM 所需的所有配置命令。VM 部署任务的所有这些配置命令可以分为不同的类别:

  • 一般 VM 配置
  • 网络配置
  • 自定义用户配置
  • VM 注册/启动配置

清单 6、7、8 和清单 9 显示了独立于部署任务 sles10sp2vm.task 的配置设置。

清单 6. VM 部署任务文件中的一般 VM 配置设置

# Task description
TaskDescription=SLES 10 VM used for BVT
# OS name of the VM to be created, a file with the name OSName.vtd should has been 
# defined in vtds directory.
OSName=SLES10SP2
# Size of the memory in MB that should be assigned to the VM
MemorySize=1300
# Disk size in GB of the first hard disk, if the number specified is not specified or 
# is smaller than the disk size of template VM, it will has same disk size as 
# template VM.
DiskSize=10
# Display Name of the VM.
DisplayName=SLES10SP2-143-50
# The destination directory of the VM to be created to.
Destination=/vmware/SLES10SP2-143-50
# Overwrite specifies if overwrite the existing VM.
OverwriteOnExist=Yes

这些一般设置将定义 OS 类型、内存大小、磁盘大小以及要创建的 VM 的目标位置。它还允许用户选择是否覆盖目标位置中已有的虚拟机。

清单 7. VM 部署任务文件中的网络配置设置

# Specify if to configure the network during the first boot of the VM. Yes to configure,
# or No for not configure. 
# If No is specified, all properties start with ConfigNet will be ignored.
ConfigNet=yes
# Network connection type of Virtual Ethernet card eth0, possible values are Bridged,
# NAT and HostOnly. Default value is Bridged if not specified.
ConfigNet.ConnectType=NAT
# Mac address of the ethernet card, possible values are:
#    1) auto                 the mac will be generated automatically.
#    2) xx:xx:xx:xx:xx:xx        user defined mac address. (For VMware, the valid range
#       is 00:50:56:00:00:00 to 00:50:56:3F:FF:FF)
ConfigNet.MacAddress=00:50:56:3A:01:02
# Network configuration mode, dhcp or static.
ConfigNet.Mode=static
# IP address to be used for the VM.
ConfigNet.IPAddress=192.168.143.50
ConfigNet.Netmask=255.255.255.0
ConfigNet.Gateway=192.168.143.2
ConfigNet.Hostname=sles10vm-143-50
ConfigNet.Domain=ibm.com
ConfigNet.PrimaryDNS=9.181.32.72
ConfigNet.SecondDNS=9.181.2.101

在部署时,网络配置信息将由 VDM 来收集,并被保存到 VM 配置 ISO 文件中,以便在 VM 启动时可以访问这些信息。

清单 8. VM 部署任务文件中的自定义用户配置设置

# Folder holding user's configuration data. The content of this folder will be archived# into an ISO file, with label VMCONFIG and be mounted in the VM CD-ROM.UserConfigDataDir=/root/mydata/# The application users want to run after system boot and network configuration.# It will also be archive to the VMCONFIG ISO file.UserConfigApp=/root/myapp.sh

所有用户配置数据也将被收集并保存到 VM 配置 ISO 文件中。

清单 9. VM 部署任务文件中的 VM 注册/启动配置设置

# Register VM to local vmware server or not. Yes for register, false for not register.# Default value is No.RegisterVM=Yes# Parameters used to register VM. Not needed by VMware Server 1.x.RegisterVM.HostURL=https://localhost:8333RegisterVM.Username=rootRegisterVM.Password=password# Power on VM after deployment or not. Yes for power on, No for not power on.# Default value is false.PowerOn=Yes

这些参数用于在部署后注册或启动 VM。对于 VMware Server 2.0,您必须提供服务器 URL、用户名和密码。

部署 VM

既然 VM 模板和 VM 部署任务文件已就绪,现在该进行部署了。VM 部署过程包括:

  • 解析 VM 部署任务的设置
  • 查找正确的 VM 模板并将其复制到目标文件夹中
  • 生成包含配置数据的 ISO 文件
  • 修改新 VM 的硬件配置并装入作为 CD 的 ISO 文件
  • 最后,如果 VM 部署任务文件中的 RegisterVMPowerOn 属性都被设为 Yes,则注册并启动 VM。

在本文的样例代码中,VM 部署管理器被设计为解压缩后即可运行的代码,因此您不需要执行附加步骤来安装它,只需将其解压缩到便于访问的位置(例如,/opt/vmdeploymgr)。但是,要注册并启动新 VM,安装了 VDM 的服务器应当安装一些 VM 管理程序工具。VDM 应当能够调用 VM 管理程序工具来注册并启动 VM。在样例代码中,VDM 安装在 VMware 服务器所在的服务器中。

VM 部署选项

VDM 提供了三个部署选项:

  1. 部署单个 VM。
  2. 使用任务列表部署多个 VM 部署任务。
  3. 部署存储在文件夹中的所有 VM 部署任务。

为了支持这些选项,提供了 vmdeploymgr.sh 命令的三个选项,这是 VDM 的主要应用。

  1. 部署单个 VM 部署任务。

VDM 将允许您按照如下所示使用 -f 选项来指向指定的 VM 部署任务文件:localhost:/opt/vmdeploymgr/bin # ./vmdeploymgr.sh -f ../tasks/sles10sp2.task

  1. 使用任务列表部署多个 VM 部署任务。

您还可以列出任务列表文件中的所有 VM 部署任务,并要求 VDM 按顺序处理该列表中的所有任务。任务列表文件是一个纯文本文件。清单 10 显示了包含三项 VM 部署任务的样例任务列表文件,VDM 将不处理最后一项任务(win2003vm2.task),因为该任务已被注释掉。

清单 10. 样例 VM 部署任务列表文件

/opt/vmdeploymgr/tasks/sles10sp2vm.task/opt/vmdeploymgr/tasks/rhel5u2vm.task/opt/vmdeploymgr/tasks/win2003vm.task#/opt/vmdeploymgr/tasks/win2003vm2.tas

k

选项 -t 用于部署 VM 部署任务列表。以下清单显示了样例命令:

localhost:/opt/vmdeploymgr/bin # ./vmdeploymgr.sh -t ../tasks/vmtasklist
  1. 部署存储在文件夹中的所有 VM 部署任务。

VM 部署的第三个选项是部署指定文件夹中的所有任务文件。命令选项 -d 用于执行此操作;如果提供 -d,VDM 将在给定文件夹中搜索带有 .task 扩展名的所有文件,然后处理这些任务。以下清单显示了样例命令:

localhost:/opt/vmdeploymgr/bin # ./vmdeploymgr.sh -d ../tasks

VM 配置 CD

VM 配置 CD 是自动化 VM 部署解决方案的最重要组件,因为它包含来自 VDM 和用户的配置数据。它使得使用同一个 VM 模板为拥有不同配置的不同操作系统创建虚拟机成为可能。换言之,对于各种操作系统,您都只需要使用一个 VM 模板 —— 这可以节省时间和磁盘空间。

该 CD 是由 VDM 所生成的 ISO 文件根据 VM 部署任务模拟的,并且将被装入虚拟光驱,这样它可以比软盘保存更多的数据。使用 VM 配置 CD 可以让您在 VM 启动后灵活地运行任何需要的应用程序。VM 配置 ISO 文件被命名为 VMCONFIG.iso 并且它的标签为 VMCONFIG。图 3 显示了适用于 Linux 的 VM 配置 CD 的文件结构。适用于 Windows 的 VM 配置 CD 的文件结构是类似的。

图 3. 适用于 Linux VM 的 VM 配置 CD 的文件结构

 

如图 3 所示,vdm 文件夹主要包含 VDM 所定义的预定义配置任务(例如,网络配置),而 usr 文件夹包含 VM 部署任务文件中定义的用户自定义配置数据。run.conf 文件用于告诉 VCM 需要运行 CD 中的哪个应用程序。清单 11 显示了它的样例内容。

清单 11. run.conf 的样例内容

# Configuration application to perform predefined VM Deployment Manager configuration,# for example, network configuration.VDM_CFG_APP=vdm/run.sh# User defined configuration application that will run after system boot.USR_CFG_APP=usr/myapp.sh

在启动已部署的 VM 时,VCM 将启动并尝试找到 VM 配置 CD。当它找到 CD 后,它将读取 run.conf 的内容,然后按顺序执行 VDM_CFG_APPUSR_CFG_APP 所定义的应用程序。如果用户没有在 VM 部署任务文件中指定任何自定义配置,则 run.conf 中就不会设置 USR_CFG_APP 属性。

将为已复制的 VM 创建一个新 CD-ROM 以装入 VM 配置 CD,并且 VDM 将搜索 VM 的 IDE 总线(先搜索 IDE 总线,再搜索 SCSI 总线)以为 CD-ROM 查找一个空闲总线。在它找到一个空闲总线后,它将修改 VM 配置文件,创建一个新 CD-ROM,然后将 CD 装入到其中。

注册并启动 VM

要在 VM 管理程序服务器中注册 VM 并启动该 VM,VDM 需要支持一些 VM 管理程序工具。对于 VMware Server 2.0,主要工具是 vmrun;对于 VMware Server 1.0,需要支持 vmware-cmd。安装 VMware 服务器时将默认安装这些工具。

清单 12 显示了演示如何使用 vmware-cmd 注册和启动 VM 的样例代码;清单 13 显示了演示如何使用 vmrun 注册和启动 VM 的样例代码:

清单 12. 使用 vmware-cmd 注册和启动 VM 的样例代码

vmware-cmd  -s register "$vmxfile"vmware-cmd  "$vmxfile" start hard



清单 13. 使用 vmrun 注册和启动 VM 的样例代码


vmrun -T server -h "${hostURL}/sdk" -u "$username" -p "$password"/       register "[$datastoreName] $vmxfile"vmrun -T server -h "${hostURL}/sdk" -u "$username" -p "$password"/      start "[$datastoreName] $vmxfile"

结束语

通过本文所述的自动化虚拟机部署解决方案可以看到,虚拟机的部署和初始配置已变得非常简单。您只需在 VM 部署任务文件中写下配置,然后 VM 部署管理器将为您自动部署和配置所有虚拟机。

此解决方案也是非常灵活的 —— 您可以在已部署的 VM 启动后运行您自己的应用程序。例如,您可以通过在 VM 部署任务中设置 USR_CFG_APP,要求 VM 在系统启动后运行一个应用程序以自动下载并安装新软件版本。

总而言之,在部署和管理一组虚拟机时,此解决方案应当可以帮助您节省大量时间并且更高效地工作。