Board logo

标题: 使用 Perl 进行虚拟化环境的自动化管理(3) [打印本页]

作者: look_w    时间: 2018-4-22 14:36     标题: 使用 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 以及之前的版本的定制化流程稍有不同。主要表现在:
在实际应用中,考虑的代码的可重用性,比较合适的方法是将需要定制化的参数放到外部文件中(例如使用 XML 格式进行组织 ),以后每次批量部署虚拟机的时候只需要改动必要部分即可。但是为了突出重点,尽可能用简单的例子来说明自动化配置的逻辑流程,这里仍然把参数直接写在配置流程中。
Linux 的定制化过程和 Windows 大致相同,本文不再赘述。其主要区别在于构造 CustomizationSpec 时传入 CustomizationLinuxPrep 对象作为参数。CustomizationLinuxPrep 和 CustomizationSysprep 均继承自 CustomizationIdentitySettings。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0