使用 Ansible 管理 VMware 模板生命周期
使用 Ansible 管理 VMware 模板生命周期
当我们管理大量虚拟机 (VM) 时,我们希望减少它们之间的差异并创建标准模板。通过使用标准模板,可以更轻松地管理并在不同节点上传播相同的操作。当使用 VMware vSphere 时,共享标准化的 VM 模板并使用它创建新的 VM 是一种常见做法。此模板通常称为黄金映像。其创建涉及一系列可以使用 Ansible 自动化的步骤。在本篇博文中,我们将了解如何创建和使用新的黄金映像。
准备黄金映像
我们使用 镜像构建器 来准备新的镜像。该工具提供了一个用户界面,允许用户定义自定义镜像。在本例中,我们包含了 SSH 服务器和 tmux。生成的镜像是一个 VMDK4 格式的文件,VMware vSphere 7 不完全支持,因此我们使用 .vmdk-4
后缀。
我们使用 uri 模块上传镜像。使用此方法上传大文件相当缓慢。如果可以,您可能希望直接将文件放到数据存储中(例如:NFS/CIFS)。以下示例认为数据存储名为 rw_datastore,数据中心名为 my_dc。以下摘录自剧本,展示了我们如何上传镜像。
- name: Upload from contents of remote file ansible.builtin.uri: force_basic_auth: true url: 'https://vcenter.test/folder/my-vmdk/my-golden-image.vmdk-4?dcPath=my_dc&dsName=rw_datastore' url_username: '{{ lookup("ansible.builtin.env", "VMWARE_USER") }}' url_password: '{{ lookup("ansible.builtin.env", "VMWARE_PASSWORD") }}' method: PUT status_code: 201 src: my-golden-image.vmdk-4 validate_certs: false follow_redirects: yes
现在我们已上传文件,我们将将其转换为最新的 VMDK 文件。为此,我们使用 vmkfstools。该工具默认在 ESXi7 主机上可用。在下面的任务中,我们使用 delegate_to: esxi1.test
在我们的一个主机上运行该命令。
- name: Convert the image in an up to date VMDK format ansible.builtin.command: "vmkfstools -i /vmfs/volumes/rw_datastore/my-vmdk/my-golden-image.vmdk-4.vmdk-4 /vmfs/volumes/rw_datastore/my-vmdk/my-golden-image.vmdk -d thin" delegate_to: esxi1.test vars: ansible_user: root ansible_python_interpreter: /bin/python3
准备黄金 VM
在此阶段,磁盘已准备就绪,我们可以将其连接到 VM。
- name: Create a VM vmware.vmware_rest.vcenter_vm: placement: cluster: "" datastore: "" folder: "" resource_pool: "" name: my-golden-vm guest_OS: RHEL_7_64 hardware_version: VMX_11 memory: hot_add_enabled: true size_MiB: 1024 disks: - type: SATA backing: type: VMDK_FILE vmdk_file: "[rw_datastore] my-vmdk/my-golden-image.vmdk" cdroms: - type: SATA sata: bus: 0 unit: 2 nics: - backing: type: STANDARD_PORTGROUP network: "" register: my_vm
有四种不同的方法可以使用 Ansible 的 vmware.vmware_rest 集合克隆 VM。本文解释了它们之间的区别以及如何使用 Ansible 使用它们。
克隆 VM
当我们克隆 VM 时,我们会创建一个原始 VM 的副本。但是,原始 VM 仍然可以发展,并且从同一 VM 进行的第二次克隆很可能会有所不同。无法保证两个克隆都基于完全相同的镜像。
vmware.vmware_rest.vcenter_vm
模块允许我们准备瞬时克隆或常规克隆。
瞬时克隆
根据 VMware 官方文档,瞬时克隆是正在运行的 VM 的轻量级副本。它与原始 VM 共享内存块。这就是为什么在克隆之前必须运行原始 VM 的原因。
- name: Turn the power on the VM on, since it's are pre-condition for Instant Clone vmware.vmware_rest.vcenter_vm_power: state: start vm: '{{ my_vm.id }}' - name: Wait until my VM is ready vmware.vmware_rest.vcenter_vm_tools_info: vm: '{{ my_vm.id }}' register: vm_tools_info until: - vm_tools_info is not failed - vm_tools_info.value.run_state == "RUNNING" retries: 10 delay: 5
现在我们已启动并运行了 VM,我们可以对其进行瞬时克隆
- name: Create an instant clone of a VM vmware.vmware_rest.vcenter_vm: placement: datastore: "{{ lookup('vmware.vmware_rest.datastore_moid', '/my_dc/datastore/local') }}" folder: "{{ lookup('vmware.vmware_rest.folder_moid', '/my_dc/vm') }}" resource_pool: "{{ lookup('vmware.vmware_rest.resource_pool_moid', '/my_dc/host/my_cluster/Resources') }}" state: instant_clone source: "{{ my_vm.id }}" name: instant_clone_1
常规克隆
我们还可以 克隆现有的 VM。如果 VM 带有大型磁盘,则该操作需要更多时间,最多可能需要几个小时。该操作会创建原始 VM 的完整克隆。这次,原始 VM 不需要运行。
- name: Create a full clone of a VM vmware.vmware_rest.vcenter_vm: placement: datastore: "{{ lookup('vmware.vmware_rest.datastore_moid', '/my_dc/datastore/local') }}" folder: "{{ lookup('vmware.vmware_rest.folder_moid', '/my_dc/vm') }}" resource_pool: "{{ lookup('vmware.vmware_rest.resource_pool_moid', '/my_dc/host/my_cluster/Resources') }}" state: clone source: "{{ my_vm.id }}" name: full_clone_1
构建模板
与克隆不同,模板可以保证 VM 继承自静态 VM 镜像。vmware.vmware_rest 集合使我们能够准备 OVF 包,并且从 2.2.0 版本开始,我们还可以准备模板 VM。
将 VM 导出为内容库中的 OVF 包
我们可以将 VM 导出为 OVF 包并将包上传到内容库中。如果您想准备一个将在 vSphere 基础架构中重复使用的标准模板,这将非常方便。此外,OVF 包可以从一个 vSphere 下载并在另一个 vSphere 中重新上传。
在本例中,我们使用 Ansible 来准备 OVF 包。在本例中,my_vm 未运行,内容库名为 my_library_on_nfs。
- name: List all Local Content Library vmware.vmware_rest.content_locallibrary_info: register: all_content_libraries - name: Use the name to identify the right Content Library set_fact: nfs_lib: "{{ all_content_libraries.value | selectattr('name', 'equalto', 'my_library_on_nfs')|first }}" - name: Export the VM as an OVF on the library vmware.vmware_rest.vcenter_ovf_libraryitem: session_timeout: 2900 source: type: VirtualMachine id: "{{ my_vm.id }}" target: library_id: "{{ nfs_lib.id }}" create_spec: name: golden_image description: an OVF example flags: [] state: present
要基于此 OVF 包生成新的 VM,您首先需要在内容库中识别其项目条目。
- name: Get the list of items of the NFS library vmware.vmware_rest.content_library_item_info: library_id: '{{ nfs_lib.id }}' register: lib_items - name: Define a new fact with the golden image ID ansible.builtin.set_fact: golden_image_id: '{{ (lib_items.value|selectattr("name", "equalto", "golden_image")|first).id }}'
获得项目 ID 后,我们可以调用 vcenter_ovf_libraryitem
来生成新的 VM。由于 ID 是不变的,因此我们可以将其保存以供将来使用。
- name: Create a new VM based on the OVF vmware.vmware_rest.vcenter_ovf_libraryitem: ovf_library_item_id: '{{ golden_image_id }}' state: deploy target: resource_pool_id: "{{ lookup('vmware.vmware_rest.resource_pool_moid', '/my_dc/host/my_cluster/Resources') }}" deployment_spec: name: my_vm_from_ovf accept_all_EULA: true storage_provisioning: thin
将 VM 导出为内容库中的 VM 模板
模板创建通过一次调用 vmware.vmware_rest.vcenter_vmtemplate_libraryitems
模块来完成。此模块是在 vmware_rest 集合 2.2.0 中引入的。
这里,nfs_lib
是您的内容库,您的 VM 详细信息已注册到 my_vm
变量中。
- name: Create a VM template on the library vmware.vmware_rest.vcenter_vmtemplate_libraryitems: name: golden-template library: "{{ nfs_lib.id }}" source_vm: "{{ my_vm.id }}" placement: cluster: "{{ lookup('vmware.vmware_rest.cluster_moid', '/my_dc/host/my_cluster') }}" folder: "{{ lookup('vmware.vmware_rest.folder_moid', '/my_dc/vm') }}" resource_pool: "{{ lookup('vmware.vmware_rest.resource_pool_moid', '/my_dc/host/my_cluster/Resources') }}"
要基于此模板生成新的 VM,我们再次需要识别内容库中的项目。
- name: Get the list of items of the NFS library vmware.vmware_rest.content_library_item_info: library_id: '{{ nfs_lib.id }}' register: lib_items - name: Use the name to identify the item set_fact: my_template_item: "{{ lib_items.value | selectattr('name', 'equalto', 'golden-template')|first }}"
我们使用相同的模块进行部署
- name: Deploy a new VM based on the template vmware.vmware_rest.vcenter_vmtemplate_libraryitems: name: vm-from-template library: "{{ nfs_lib.id }}" template_library_item: "{{ my_template_item.id }}" placement: cluster: "{{ lookup('vmware.vmware_rest.cluster_moid', '/my_dc/host/my_cluster') }}" folder: "{{ lookup('vmware.vmware_rest.folder_moid', '/my_dc/vm') }}" resource_pool: "{{ lookup('vmware.vmware_rest.resource_pool_moid', '/my_dc/host/my_cluster/Resources') }}" state: deploy
总之,只需几个 Ansible 任务,我们就可以将现有 VM 提升为模板。这使我们能够依靠 Ansible 自动化 VM 模板的维护并确保流程的可重复性。