4. 批量虚拟机创建与配置

当运维环境从“偶尔建几台虚拟机”进入“一次交付几十台、上百台”的阶段,逐台点击向导的方式就不可持续了。批量部署的核心思路是:把虚拟机的“不变部分”固化成模板,把“可变部分”抽象成参数,再通过自定义规范(Customization Specification)在克隆时注入主机名、IP、网关、DNS、域信息等,使同一份模板能派生出大量配置各异的虚拟机。vSphere 中实现这一目标的主要工具是 New-VM、New-OSCustomizationSpec 与 Invoke-VMScript 等 PowerCLI 命令,配合 CSV 参数表即可完成参数化批量部署。

模板与自定义规范的分工

模板负责“操作系统层面已经装好、打好补丁、装好 VMware Tools、做过基础优化”的黄金镜像;自定义规范负责“每台机器不一样的部分”。在 vSphere Client 中,自定义规范通过“策略和配置文件 → 虚拟机自定义规范”创建,本质是一组应答文件参数;在 PowerCLI 中则用 New-OSCustomizationSpec 生成,可复用于任意次克隆。规范中需要重点确认的字段包括:

  • 主机名:可使用“使用虚拟机名称”或固定前缀加序号,批量场景推荐前者,避免手工维护序号。
  • 网络:选择“手动”并指定 IP、子网掩码、网关,或选择 DHCP;批量静态 IP 时通常由 CSV 逐台传入。
  • DNS 与域:主/备 DNS、DNS 搜索域、是否加入 Windows 域及域账号。
  • 时区与许可:Windows 规范可设置时区、许可模式;Linux 规范则通过 LinuxPrep 或 CloudInit 完成主机名与网络注入。
自定义规范只对“克隆”和“从模板部署”生效,对已有虚拟机重新应用规范不会自动改主机名,需要借助 Invoke-VMScript 或客户机内工具二次处理。

参数化批量部署的数据流

批量部署的输入不是零散命令,而是一张“每行一台虚拟机”的参数表。典型字段包括 VMName、Template、Cluster、Datastore、Network、IP、Prefix、Gateway、DNS、CPU、MemoryGB、DiskGB。PowerCLI 读取 CSV 后循环执行克隆,并在克隆时套用自定义规范。下图展示了从参数表到虚拟机落地的完整数据流与关键对象关系:

批量虚拟机部署数据流:参数表 → 克隆 → 自定义规范 → 落地校验 参数表 vms.csv VMName, Template Cluster, Datastore Network, IP, Prefix Gateway, DNS CPU, MemoryGB, DiskGB 每行 = 一台虚拟机 黄金模板 OS + 补丁 + Tools 基础优化 / 安全基线 只读,不直接运行 自定义规范 主机名:使用 VM 名称 网络:手动 IP/掩码/网关 DNS / 搜索域 / 域加入 时区 / 许可模式 LinuxPrep 或 CloudInit PowerCLI 克隆循环 New-VM -VM $row.VMName -Template -OSCustomizationSpec 逐行读取,失败可重试 目标资源 集群 / 资源池 数据存储(精简置备) 端口组 / VLAN CPU / 内存 / 磁盘规格 按参数表逐台设定 批量虚拟机 VM-Web-01 … VM-Web-20 主机名 / IP 已注入 开机后进入就绪状态 结果校验 PowerState=PoweredOn Tools=Running IP / 主机名一致 异常机重跑或回滚 逐行读取 作为源 套用 克隆 放置

关键参数化配置的实现

下面是一段可直接参考的 PowerCLI 批量部署脚本骨架。它读取 CSV,为每台虚拟机克隆模板、套用自定义规范,并在克隆后调整 CPU、内存和磁盘。示例中的参数均为教学示例值,实际执行前需替换为环境中的真实名称。

# 1. 连接 vCenter
Connect-VIServer -Server vcsa.lab.local -User administrator@vsphere.local

# 2. 读取参数表
$vms = Import-Csv .\vms.csv

# 3. 逐台部署
foreach ($row in $vms) {
    $spec = Get-OSCustomizationSpec -Name $row.SpecName
    New-VM -Name $row.VMName `
           -Template $row.Template `
           -VMHost $row.Host `
           -Datastore $row.Datastore `
           -OSCustomizationSpec $spec `
           -DiskStorageFormat Thin

    # 4. 参数化调整 CPU / 内存
    Set-VM -VM $row.VMName -NumCpu $row.CPU -MemoryGB $row.MemoryGB -Confirm:$false

    # 5. 网络接入指定端口组
    Get-NetworkAdapter -VM $row.VMName |
        Set-NetworkAdapter -NetworkName $row.Network -Confirm:$false

    # 6. 启动并等待 Tools 就绪
    Start-VM -VM $row.VMName | Out-Null
}

磁盘扩容需要特别注意:模板中的系统盘通常已固定大小,若参数表中的 DiskGB 大于模板磁盘,应在克隆后使用 Set-HardDisk -CapacityGB 扩容,再进入客户机扩展分区;若小于模板磁盘则无法缩小,只能重新制作更小的模板。CPU 与内存的调整必须在虚拟机开机前完成,否则部分配置需要重启才生效。

自定义规范中的网络注入要点

静态 IP 批量部署最容易出错的环节是“规范里的网络设置”和“参数表里的 IP”不一致。推荐做法是:自定义规范中网络选择“手动”,但具体 IP 留空或使用占位,由脚本在克隆前动态生成一份临时规范,把 CSV 中的 IP、掩码、网关写入。Linux 虚拟机若使用 CloudInit,则通过 guestinfo 或 user-data 注入网络配置,此时应确认模板中已安装 open-vm-tools 与 cloud-init,且 /etc/cloud/cloud.cfg 未被禁用网络配置。

批量部署前务必确认 vCenter 的 MAC 地址分配策略、端口组 VLAN 与 IP 规划一致;若同一端口组内 IP 冲突,虚拟机会出现“网络已连接但无法通信”的现象,排查时应先在客户机内执行 ipconfig /all 或 ip addr 核对实际生效地址。

部署后的结果校验

批量任务结束后不能只看“命令是否报错”,而应逐项核对:虚拟机是否处于 PoweredOn、VMware Tools 是否 Running、主机名是否与 VMName 一致、IP 是否与参数表一致、磁盘容量是否符合预期。可用如下命令快速汇总:

Get-VM -Name (Import-Csv .\vms.csv).VMName |
  Select-Object Name, PowerState,
    @{N='IP';E={$_.Guest.IPAddress -join ','}},
    @{N='Tools';E={$_.ExtensionData.Guest.ToolsRunningStatus}},
    NumCpu, MemoryGB

对于校验失败的虚拟机,优先检查自定义规范日志:Windows 可查看 C:\Windows\Temp\vmware-imc 下的日志,Linux 可查看 /var/log/vmware-imc 或 cloud-init 日志。确认是规范参数错误还是客户机内服务未启动,再决定重跑克隆或仅修复客户机配置。批量部署的价值不仅在于“快”,更在于每一次部署都可重复、可审计、可回滚,这正是自动化运维与手工操作的本质区别。