Packer 是由 Hashicorp 创建的应用程序,它使 IT 专业人员能够自动执行其 VM 模板生成。随着混合云环境的兴起,它正迅速成为在一个工具下管理每个平台的多个 VM 映像的首选实用工具之一。它自动执行建立全新 VM 的过程,并合并自定义生成脚本以动态自定义 VM,然后转换回模板以用于在云中或本地进行部署。在 VMware 环境中使用 Packer 可以带来以下好处:
- 与平台无关– Packer 不仅可以将相同的映像和配置部署到 VMware 环境,还可以将相同的映像和配置部署到 AWS 和 Azure 等公共云提供商。这大大减少了为每个环境维护映像所花费的时间,并确保每个映像都是一致的。
- 更快的部署– 将尽可能多的内容包含在映像生成中,而不是在部署时运行自定义脚本,从而创建更快的 VM 部署。
- 自动模板管理– 现在可以自动执行整个过程,并且可以对计划任务运行 Packer 映像重建,而不是每月对模板手动运行 Windows 更新。
- 基础结构即模板的代码– Packer 允许 IT 专业人员获取其模板内部版本并在代码中对其进行定义。这使我们能够将模板配置存储在源代码管理中,从而可以更轻松地管理和跟踪对模板所做的所有更改。
- 开源- Packer是一个开源软件,这意味着它是完全免费使用的,这使得它更是必须尝试的。
如何安装Packer
Packer只是一个可执行文件,可以放在任何文件夹中并从那里执行。您可以在此处下载Packer。为配合 JetBrains 的VSphere-ISO的自定义构建器需要下载1.4.5版本的packer(更高版本的packer与 JetBrains 的VSphere-ISO的不兼容)。在我们的示例中,我们将从 Windows 10 计算机运行 Packer。在本例中,packer.exe在C:\Packer目录中。
Packer使用"builders"来提供为当今各种平台(如Azure,VMware和AWS)生成映像的方法。有许多构建器与 Packer 一起提供,但是,目前默认的 VMware 构建器仅允许您使用 SSH 连接到单个主机以提供模板。这还需要在主机上进行自定义配置才能与打包程序交互。幸运的是,Packer是开源软件,并且拥有一个令人惊叹的社区,该社区一直在改进产品。JetBrains 提供了一个名为VSphere-ISO的自定义构建器,它允许我们使用 VCenter API 连接到我们的 VMware 环境,只需开始配置模板即可。因此,在此示例中,我们将下载的packer-builder-vsphere-iso.exe放置在与 packer.exe相同的目录中,Packer 将自动找到该插件:
现在,我们已准备好开始构建 VMware 模板。
在 VMware 中构建基本模板
有两种方法可以构建模板,即 OS ISO 或现有 VM。我们将从头开始,从Windows Server 2016 ISO构建一个VM。Packer 将创建 VM、安装 OS、配置 OS,然后将 VM 转换为模板映像以用于将来的部署。我们需要创建一个打包程序配置文件。打包器配置文件以 JSON 格式编写,如下所示。在我的示例中,这些设置是为我的 VMware 环境配置的。要查看可用于 VSphere-ISO 插件的不同选项,请查看Packer GitHub 页面。我将以下配置另存为名为WindowsServer.Json的文件。确保编辑字段以匹配您自己的 VCenter 环境。另外,请注意,密码都是以明文形式声明的,这不是最佳实践,仅用于演示目的。在生产环境中,我们希望将它们作为变量输入。
{
"builders": [
{
"type": "vsphere-iso","vcenter_server": "vcenter_server_ip","username": "administrator@vsphere.local","password": "vc_admin_password","insecure_connection": "true","vm_name": "windows2016packer","host": "esxi_host_ip","guest_os_type": "windows9_64Guest","communicator": "winrm","winrm_username": "vagrant","winrm_password": "vagrant","cpus": 1,"RAM": 4096,"RAM_reserve_all": true,"disk_controller_type": "lsilogic-sas","disk_size": 32768,"disk_thin_provisioned": true,"network_card": "e1000e","iso_paths": [
"[datastore1] SW_DVD9_Win_Svr_STD_Core_and_DataCtr_Core_2016_64Bit_ChnSimp_-2_MLF_X21-22842.iso","[datastore1] VMware-tools-windows-11.3.0-18090558.iso"
],"floppy_files": [
"{{template_dir}}/setup/"
]
}
],"provisioners": [
{
"type": "windows-shell","inline": ["dir c:\\"]
}
]
}
接下来,我们需要创建两个文件。我们需要一个 autounattend.xml 文件来自动安装我们的 Windows Server ISO,一个 vmtools.cmd 文件来配置静态IP,启用服务器和客户端之间的 winrm 通信,关闭防火墙,安装 Windows 期间安装 VMware Tools。这些文件将挂载到 VM 的软盘驱动器上,然后在 Windows 安装阶段运行。幸运的是,jetbrains在Github上拥有所有文件示例 。另请注意,您将需要修改 autounattend.xml 文件以匹配打包程序配置文件中的相同 winrm 凭据。所以现在我有了我的配置文件和一个"setup"文件夹,其中包含用于Windows安装的两个文件:
autounattend.xml
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SetupUILanguage>
<UILanguage>zh-CN</UILanguage>
</SetupUILanguage>
<InputLocale>zh-CN</InputLocale>
<SystemLocale>zh-CN</SystemLocale>
<UILanguage>zh-CN</UILanguage>
<UILanguageFallback>zh-CN</UILanguageFallback>
<UserLocale>zh-CN</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<diskConfiguration>
<disk wcm:action="add">
<CreatePartitions>
<CreatePartition wcm:action="add">
<Type>Primary</Type>
<Order>1</Order>
<Size>350</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Active>true</Active>
<Format>NTFS</Format>
<Label>boot</Label>
<Order>1</Order>
<PartitionID>1</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Format>NTFS</Format>
<Label>Windows 2016</Label>
<Letter>C</Letter>
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
</ModifyPartitions>
<diskID>0</diskID>
<WillWipedisk>true</WillWipedisk>
</disk>
</diskConfiguration>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/NAME</Key>
<Value>Windows Server 2016 SERVERDATACENTER</Value>
</MetaData>
</InstallFrom>
<InstallTo>
<diskID>0</diskID>
<PartitionID>2</PartitionID>
</InstallTo>
</OSImage>
</ImageInstall>
<UserData>
<!-- Product Key from https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-technical-preview?i=1 -->
<ProductKey>
<!-- Do not uncomment the Key element if you are using trial ISOs -->
<!-- You must uncomment the Key element (and optionally insert your own key) if you are using retail or volume license ISOs -->
<Key>6CNGG-BJP34-H923Y-6DMWR-37BMF</Key>
<WillShowUI>OnError</WillShowUI>
</ProductKey>
<AcceptEula>true</AcceptEula>
<FullName>Vagrant</FullName>
<Organization>Vagrant</Organization>
</UserData>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OEMinformation>
<HelpCustomized>false</HelpCustomized>
</OEMinformation>
<ComputerName>vagrant-2016</ComputerName>
<TimeZone>China Standard Time</TimeZone>
<RegisteredOwner/>
</component>
<component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DoNotOpenServerManagerAtlogon>true</DoNotOpenServerManagerAtlogon>
</component>
<component name="Microsoft-Windows-IE-ESC" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<IEHardenAdmin>false</IEHardenAdmin>
<IEHardenUser>false</IEHardenUser>
</component>
<component name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DoNotOpenInitialConfigurationTasksAtlogon>true</DoNotOpenInitialConfigurationTasksAtlogon>
</component>
<component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipAutoActivation>true</SkipAutoActivation>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Description>Set Execution Policy 64 Bit</Description>
<Path>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Description>Set Execution Policy 32 Bit</Description>
<Path>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</Path>
</RunSynchronousCommand>
<!-- <RunSynchronousCommand wcm:action="add">
<Order>3</Order>
<Description>disable WinRM</Description>
<Path>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\disable-winrm.ps1</Path>
</RunSynchronousCommand> -->
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Autologon>
<Password>
<Value>vagrant</Value>
<PlainText>true</PlainText>
</Password>
<Enabled>true</Enabled>
<Username>vagrant</Username>
</Autologon>
<FirstlogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>cmd.exe /c a:\vmtools.cmd</CommandLine>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
</FirstlogonCommands>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Home</NetworkLocation>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
<UserAccounts>
<AdministratorPassword>
<Value>vagrant</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>vagrant</Value>
<PlainText>true</PlainText>
</Password>
<Group>administrators</Group>
<displayName>Vagrant</displayName>
<Name>vagrant</Name>
<Description>Vagrant User</Description>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<RegisteredOwner />
</component>
</settings>
<settings pass="offlineservicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<cpi:offlineImage cpi:source="wim:c:/wim/install.wim#Windows Server 2012 R2 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
vmtools.cmd
netsh interface ip set address name="Ethernet0" static 192.168.1.206 255.255.255.0 192.168.1.254
rem basic config for winrm
cmd.exe /c winrm quickconfig -q
rem allow unencrypted traffic,and configure auth to use basic username/password auth
cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}
rem update firewall rules to open the right port and to allow remote administration
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
rem restart winrm
cmd.exe /c net stop winrm
cmd.exe /c net start winrm
netsh advfirewall set allprofiles state off
e:\setup64 /s /v "/qb REBOOT=R"
现在我们需要下载一个 VMware Tools ISO。您可以在此处获取它,只需匹配您的 VMware 环境的版本即可。将其传输到数据存储。我把它放在我的ESXi主机上。然后我们需要一个Windows Server 2016 ISO。下载一个并将其保存到您的数据存储中。因此,现在我的数据存储上同时具有操作系统和 VMware Tools ISO,并且该位置在我的打包器配置文件中引用。
有很多预先设置工作要做,但自动化模板构建的好处是值得的。现在,让我们验证我们的 json 文件中没有错误。为此,请打开 PowerShell 控制台并将目录更改为 WindowsServer.Json 的位置,然后运行以下语法:
packer.exe validate WindowsServer.Json
我们可以看到我们的模板已经过验证,我们很好运行我们的构建。为此,请键入以下命令:
packer.exe build WindowsServer.Json
Windows Server需要一些时间来安装,然后打包器将安装VMware工具,最后将VM转换为模板:
C:\packer>packer.exe build WindowsServer.Json
vsphere-iso output will be in this color.
==> vsphere-iso: Creating VM...
==> vsphere-iso: Customizing hardware...
==> vsphere-iso: Mount ISO images...
==> vsphere-iso: Creating floppy disk...
vsphere-iso: copying files flatly from floppy_files
vsphere-iso: copying directory: C:\packer/setup/
vsphere-iso: Adding file: C:\packer\setup\Autounattend.xml
vsphere-iso: Adding file: C:\packer\setup\vmtools.cmd
vsphere-iso: Done copying files from floppy_files
vsphere-iso: Collecting paths from floppy_dirs
vsphere-iso: Resulting paths from floppy_dirs : []
vsphere-iso: Done copying paths from floppy_dirs
==> vsphere-iso: Uploading created floppy image
==> vsphere-iso: Adding generated Floppy...
==> vsphere-iso: Set boot order temporary...
==> vsphere-iso: Power on VM...
==> vsphere-iso: Waiting for IP...
==> vsphere-iso: IP address: 192.168.1.206
==> vsphere-iso: Using winrm communicator to connect: 192.168.1.206
==> vsphere-iso: Waiting for WinRM to become available...
vsphere-iso: #< CLIXML
vsphere-iso: WinRM connected.
vsphere-iso: <Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/pow
ershell/2004/04"><Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.
Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N="SourceId">1</I
64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>
-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj><Obj S="p
rogress" RefId="1"><TNRef RefId="0" /><MS><I64 N="SourceId">1</I64><PR N="Record
"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</P
C><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>
==> vsphere-iso: Connected to WinRM!
==> vsphere-iso: Provisioning with windows-shell...
==> vsphere-iso: Provisioning with shell script: C:\Users\ADMINI~1.DCC\AppData\L
ocal\Temp\3\windows-shell-provisioner971976287
vsphere-iso:
vsphere-iso: C:\Users\vagrant>dir c:\
vsphere-iso: Volume in drive C is Windows 2016
vsphere-iso: Volume Serial Number is D0F1-E882
vsphere-iso:
vsphere-iso: Directory of c:\
vsphere-iso:
vsphere-iso: 2016/09/12 20:45 <DIR> Logs
vsphere-iso: 2016/07/16 21:23 <DIR> PerfLogs
vsphere-iso: 2021/12/21 05:46 <DIR> Program Files
vsphere-iso: 2016/07/16 21:23 <DIR> Program Files (x86)
vsphere-iso: 2021/12/21 05:45 <DIR> Users
vsphere-iso: 2021/12/21 05:46 <DIR> Windows
vsphere-iso: 0 File(s) 0 bytes
vsphere-iso: 6 Dir(s) 22,341,677,056 bytes free
==> vsphere-iso: Shut down VM...
==> vsphere-iso: Deleting Floppy drives...
==> vsphere-iso: Deleting Floppy image...
==> vsphere-iso: Eject CD-ROM drives...
==> vsphere-iso: Clear boot order...
Build 'vsphere-iso' finished.
==> Builds finished. The artifacts of successful builds are:
--> vsphere-iso: windows2016packer
C:\packer>
完成后,我们可以看到新模板在 vSphere 中可用:
您可能会想"对于Windows的普通安装来说,这是很多工作",但是,这只是一个基本的例子。Packer具有"配置器",它允许我们运行PowerShell脚本,将文件传输到VM以安装应用程序,甚至使用Puppet或Chef等配置管理工具。