首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Perl 进行虚拟化环境的自动化管理(3)

使用 Perl 进行虚拟化环境的自动化管理(3)

VMware 服务器端对象与 Perl 视图用户编写 vSphere SDK for Perl 脚本的目的是访问和修改服务器端对象,如虚拟机、集群、快照等。为此我们需要了解 vSphere 服务器端对象的组织、服务器端对象与本地 Perl 对象的关系。
vSphere 服务器端对象被称为 managed object。每个 managed object 都具有属性集 (properties) 并提供相关服务 (methods)。下图显示 managed object 的继承结构(部分 ):
图 2. 服务器端 managed object 继承结构(部分 )抽象类 ManagedEntity 为服务器端对象定义了最基本的属性集(如 name,parent 等)和方法(如 Reload,Rename_Task 等)。常见的服务器端对象,如 ResoucePool、HostSystem、Datacenter、VirtualMachine 等都继承自 ManagedEntity,提供特定的属性及方法。感兴趣的读者可以通过访问 MOB 或者 来深入了解各种 managed object 的细节。
vSphere SDK for Perl 可以将服务器端对象的属性和方法映射为本地 Perl 对象,即服务器端对象的本地 Perl 视图,所以 Perl 视图可以看作服务器端对象的本地副本,其属性和方法和服务器端对象一一对应。不过需要注意的是,服务器端对象会实时更新,而 Perl 视图是静态的副本,所以当需要最新状态信息时,用户必须使用 Vim::update_view_data 显式刷新 Perl 视图。
我们通常可以使用 Vim::find_entity_views 和 Vim::find_entity_view 函数来获得获得本地 Perl 视图(参考 simple_flow.pl 中的示例 )。有时 Vim::find_entity_views 返回结果过多,而 Vim::find_entity_view 返回的结果集中的第一个结果可能并不是我们需要的,此时我们可以使用 filter 参数细化查询条件、控制查询结果。下面的代码片段使用 guestFullName 属性进行过滤,获得所有 Windows 虚拟机的视图:
清单 3. 使用 filter 参数过滤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
my $vm_views = Vim::find_entity_views(
    view_type => 'VirtualMachine',
    filter => {
    # config(VirtualMachineConfigInfo 类 ) 是 VirtualMachine 类的属性
    # guestFullName(xsd:string 类 ) 是 VirtualMachineConfigInfo 类的属性
   'config.guestFullName' => qr/Windows/
    }
);

foreach my $vm (@$vm_views) {
print "Name: " . $vm->name . "\n";
}
...




大部分服务器端 managed object 拥有大量的属性,而我们编写任务脚本时往往只对其中的一部分感兴趣。为得到某个属性值而构造完整的 Perl 视图是非常低效的,为此我们可以通过 properties 参数来指定 Perl 视图中需要的属性:
清单 4. 使用 properties 参数获取必要属性
1
2
3
4
5
6
7
8
9
10
...
my $vm_view = Vim::find_entity_view(
    view_type => 'VirtualMachine',
    filter => { 'name' => 'foo' },
    # 只获取 runtime 属性中的 powerState 属性
    properties => [ 'runtime.powerState' ]
);
# 读取 Perl 视图的 powerState 属性
my $state = $vm_view->runtime->powerState;
...




使用 vSphere SDK for Perl 完成虚拟机的部署和定制虚拟机模板是一种可重用的虚拟机映像,通过模板来部署虚拟机可以避免在安装系统过程中很多重复操作,极大地提高了效率。但是即使使用模板来部署系统,我们仍然需要手动为各个虚拟机完成一些定制性的工作,如配置 IP、主机名之类。这些定制化工作可以在部署模板时使用 vSphere 提供的 Customization Wizard 或者 Customization Specification 文件来完成。Customization Wizard 以向导的形式让用户输入自定义信息,用户也可以把定制信息保存为 Customization Specification 文件以便以后复用。对于小规模的部署,这些工具已经足够。但是当规模变大时,手动输入、编辑、维护这些信息也会消耗相当多的精力。下面给出的示例代码将自动化地完成虚拟机部署以及网络配置工作。
w2k8_deploy.pl 演示了如何通过 Window 2008R2 模板自动部署虚拟机并配置其网络。该脚本适用于 XP/2003 以后的 Windows 版本,包括 Windows 2008/Windows 2008 R2/Vista/Win 7 sp1。其中 Windows 2008R2 和 Win7 sp1 的定制需要 vCenter 4.1 update 1。具体 Windows Guest OS 定制化支持请参考 vSphere 相关文档。
清单 5. w2k8_deploy.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/perl -w
use strict;
use warnings;
use VMware::VIRuntime;

Opts::parse();
Opts::validate();
Util::connect();
# 部署 Windows 目标虚机并配置网络
deploy_W2K8();
Util::disconnect();Virt-top documentation

sub deploy_W2K8 {
    my $vmhost = "9.115.208.49";    # 目标虚机所在 ESX server 的地址
    my $ds = "datastore1";          # 目标虚机所在的 datastore
    my $vm_template = "WIN2K8R2";   # 部署目标虚机用的模板
    my $respool = "ResPool";        # 目标虚机所在的 resource pool
    my $vm_name = "WIN2K8R2A";          # 目标虚机的虚机名

    # 获得模板视图
    my $vm_template_view = Vim::find_entity_view(
        view_type => 'VirtualMachine',
        filter => {name => $vm_template}
    );
    # 获得 ESX server 视图
    my $vmhost_view = Vim::find_entity_view(
        view_type => 'HostSystem',
        filter => {name => $vmhost}
    );
    # 获得 resource pool 视图
    my $respool_view = Vim::find_entity_view(
        view_type => 'ResourcePool',
        filter => {name => $respool}
    );
    # 获得 datastore 视图
    my $ds_view = Vim::find_entity_view(
        view_type => 'Datastore',
        filter => {name => $ds}
    );
    # 目标虚机重定位信息,指定目标虚机的 datastore/host/resource pool
    my $relocate_spec = VirtualMachineRelocateSpec->new(
               datastore => $ds_view,
               host => $vmhost_view,
               pool => $respool_view,
    );

    # 自定义 Guest Windows os 的网络配置信息
    # 主机名 /DNS 域 /IP 地址 / 网关 / 子网掩码 /DNS 服务器 / 用户及组织 / 序列号 / 密码等
    my $host_name = "WIN2K8R2A";
    my $domain = "cn.ibm.com";
    my $ip_address = "9.115.208.62";
    my @gateway = ("9.115.208.1");
    my $netmask = "255.255.255.0";
    my @dnsServers = ("9.181.2.101", "9.181.2.102");
    my $full_name = "IBMCN";
    my $org_name = "IBMCN";
    my $prod_ID = "";
    my $password = "passw0rd";

    # Windows Guest OS 的定制不需要指定 Global IP 设置
    my $cust_global_settings = CustomizationGlobalIPSettings->new();

    # 加入 workgroup 组。
    # 若使用域配置,需提供 domainAdmin/domainAdminPassword/joinDomain 参数
    my $cust_identification = CustomizationIdentification->new(
        joinWorkgroup => "workgroup",
    );         
    my $cust_gui_unattended = CustomizationGuiUnattended->new(
               autoLogon => 1,      
               autoLogonCount => 1,
               timeZone => 190,  
        password => CustomizationPassword->new(
            plainText => "true",
            value => $password
        ),
    );
    my $cust_user_data = CustomizationUserData->new(
        computerName => CustomizationFixedName->new(name => $host_name),
        fullName => $full_name,
        orgName => $org_name,
        productId => $prod_ID,
    );
    my $win_prep = CustomizationSysprep->new(
        guiUnattended => $cust_gui_unattended,
        identification => $cust_identification,
        userData => $cust_user_data,
    );
    my $cust_IP_settings = CustomizationIPSettings->new(
        dnsDomain => $domain,
        dnsServerList => \@dnsServers,
        ip => CustomizationFixedIp->new(ipAddress => $ip_address),
        gateway => \@gateway,
        subnetMask => $netmask,
    );
    my $cust_adapter_mapping = CustomizationAdapterMapping->new(
        adapter => $cust_IP_settings,
    );
    my $cust_adapter_mapping_list = [$cust_adapter_mapping];
    my $cust_spec = CustomizationSpec->new(
        globalIPSettings => $cust_global_settings,
        identity => $win_prep,
        nicSettingMap => $cust_adapter_mapping_list,
    );
    my $clone_spec = VirtualMachineCloneSpec->new(
        powerOn => 1,
        template => 0,
        location => $relocate_spec,
        customization => $cust_spec,
    );
    # 启动任务
    $vm_template_view->CloneVM_Task(
        folder => $vm_template_view->parent,
        name => $vm_name,
        spec=>$clone_spec
    );
}




CloneVM_Task 方法执行定制化的模板部署,其中 folder 参数确定目标虚机所在目录,name 参数确定目标虚机的虚机名,VirtualMachineCloneSpec 类型的 spec 参数用于自定义虚拟机克隆的过程(包括虚拟机硬件配置的定制,Guest OS 定制等 )。可以看到前面大段的代码都是在构造 VirtualMachineCloneSpec 对象。下面的类图显示了各定制对象之间的关系:
图 3. VirtualMachineCloneSpec 组成         windows 2003/xp 以及之前的版本的定制化流程稍有不同。主要表现在:
  • 构造 CustomizationSysprep 时需要提供 CustomizationLicenseFilePrintData 对象作为参数。至于 CustomizationLicenseFilePrintData 对象的具体构造方法,读者可以参考 。
  • 在 vCenter 端需要准备 sysprep 文件 (vista/2008 之后的 OS 具有内置的 sysprep,不再需要在 vCenter 端准备 )。从 OS 安装介质中找到 DEPLOY.cab,解压到 vCenter sysprep 的相关 OS 目录下:
    若 vCenter 安装在 2003 Server 上,此路径为
                     C:\Documents and Settings\All Users\Application Data\VMware\VMware VirtualCenter\sysprep\<os-level>\
                    若 vCenter 安装在 2008 Server 上,此路径为
                     C:\ProgramData\VMware\VMware VirtualCenter\sysprep\<os-level>\
在实际应用中,考虑的代码的可重用性,比较合适的方法是将需要定制化的参数放到外部文件中(例如使用 XML 格式进行组织 ),以后每次批量部署虚拟机的时候只需要改动必要部分即可。但是为了突出重点,尽可能用简单的例子来说明自动化配置的逻辑流程,这里仍然把参数直接写在配置流程中。
Linux 的定制化过程和 Windows 大致相同,本文不再赘述。其主要区别在于构造 CustomizationSpec 时传入 CustomizationLinuxPrep 对象作为参数。CustomizationLinuxPrep 和 CustomizationSysprep 均继承自 CustomizationIdentitySettings。
返回列表