You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible中并行执行localhost的VMware虚拟机启动任务?

问题描述

我正在使用Ansible的community.vmware.vmware_guest_powerstate模块启动虚拟机,但单台虚拟机启动耗时2-5秒,启动50台时效率极低。请问有没有办法实现并行执行?

我的Playbook:

- hosts: localhost
  gather_facts: false
  collections:
    - community.vmware
  vars:
    certvalidate: "no"
    server_url: "vc01.x.com"
    username: "{{ lookup('ansible.builtin.env', 'API_USER', default=Undefined) }}"
    password: "{{ lookup('ansible.builtin.env', 'API_PASS', default=Undefined) }}"
  tasks:
    - name: "设置虚拟机状态为{{ requested_state }}(vCenter)"
      community.vmware.vmware_guest_powerstate:
        username: "{{ lookup('ansible.builtin.env', 'API_USER', default=Undefined) }}"
        password: "{{ lookup('ansible.builtin.env', 'API_PASS', default=Undefined) }}"
        hostname: "{{ server_url }}"
        datacenter: "DC1"
        validate_certs: no
        name: "{{ item }}"
        state: "powered-on"
      loop: "{{ hostlist }}"

Ansible执行输出(每一行耗时2-5秒):

TASK [设置虚拟机状态为powered-on(vCenter)] ************************************************************************************************************
Monday 19 September 2022  11:17:59 +0000 (0:00:00.029)       0:00:08.157 ****** 
changed: [localhost] => (item=x1.com)
changed: [localhost] => (item=x2.com)
changed: [localhost] => (item=x3.com)
changed: [localhost] => (item=x4.com)
changed: [localhost] => (item=x5.com)
changed: [localhost] => (item=x6.com)
changed: [localhost] => (item=x7.com)
解决方案

可以通过以下几种方式实现并行启动虚拟机,大幅提升效率:

1. 使用异步任务(Async)

通过async和poll参数将每个虚拟机的启动任务设为异步执行,让Ansible同时处理多个任务,而非串行等待每个任务完成。

修改后的Playbook示例:

- hosts: localhost
  gather_facts: false
  collections:
    - community.vmware
  vars:
    certvalidate: "no"
    server_url: "vc01.x.com"
    username: "{{ lookup('ansible.builtin.env', 'API_USER', default=Undefined) }}"
    password: "{{ lookup('ansible.builtin.env', 'API_PASS', default=Undefined) }}"
  tasks:
    - name: "异步启动虚拟机"
      community.vmware.vmware_guest_powerstate:
        username: "{{ username }}"
        password: "{{ password }}"
        hostname: "{{ server_url }}"
        datacenter: "DC1"
        validate_certs: no
        name: "{{ item }}"
        state: "powered-on"
      loop: "{{ hostlist }}"
      async: 300  # 设置异步任务超时时间(秒),可根据虚拟机实际启动耗时调整
      poll: 0     # 提交任务后立即返回,不等待当前任务完成
      register: vm_start_tasks

    - name: "等待所有虚拟机启动完成"
      ansible.builtin.async_status:
        jid: "{{ item.ansible_job_id }}"
      loop: "{{ vm_start_tasks.results }}"
      register: vm_results
      until: vm_results.finished
      retries: 30  # 重试次数,配合delay参数控制等待逻辑
      delay: 10    # 每次重试间隔(秒)

说明:

  • async: 300确保每个异步任务有足够时间完成(覆盖单台2-5秒的启动耗时)
  • poll: 0让Ansible同时提交所有启动任务,无需等待单台完成
  • 第二个任务通过async_status轮询所有异步任务状态,直到全部完成

2. 调整Ansible并发数(Forks)

Ansible默认并发数(forks)为5,意味着同时最多执行5个任务。可通过以下方式增大并发数:

方法一:命令行参数指定

执行Playbook时通过-f参数设置并发数:

ansible-playbook -f 50 your_playbook.yml

方法二:在Playbook中配置

在Playbook开头添加forks参数:

- hosts: localhost
  forks: 50  # 设置并发数为50
  gather_facts: false
  # 其余配置保持不变

方法三:修改全局配置(ansible.cfg)

在ansible.cfg中修改默认forks值:

[defaults]
forks = 50

3. 可选优化细节

  • 避免重复调用lookup:原Playbook中任务重复使用lookup('ansible.builtin.env'),直接引用vars里的username和password即可,减少不必要的计算
  • 确认vCenter API限制:vCenter本身有API请求并发上限,需确保设置的并发数不超过vCenter的限制(默认上限通常足够处理50台虚拟机的启动请求)

内容的提问来源于stack exchange,提问作者chenchuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:55:21