Asynchronous 如何在ansible中使用include并行化循环

Asynchronous 如何在ansible中使用include并行化循环,asynchronous,ansible,Asynchronous,Ansible,最近我在ansible剧本的代码中遇到了一个瓶颈。我们按顺序部署集群(例如a),即一个接一个的VM,每个VM都等待前一个VM启动并运行 这使整个集群部署时间减慢了一倍于集群上成员的速度 为了解决这个问题,我开始深入研究,并找到了一些类似于我们的场景的并行循环和“开火并忘记”策略的例子 特别是,我们已经定义了自己的“定制VM并生成它”ansible任务(create_instance.yml),该任务包含并从playbook接收不同的定制变量,并通过运行不同的KVM/shell命令来抽象整个过程

最近我在ansible剧本的代码中遇到了一个瓶颈。我们按顺序部署集群(例如a),即一个接一个的VM,每个VM都等待前一个VM启动并运行

这使整个集群部署时间减慢了一倍于集群上成员的速度

为了解决这个问题,我开始深入研究,并找到了一些类似于我们的场景的并行循环和“开火并忘记”策略的例子

特别是,我们已经定义了自己的“定制VM并生成它”ansible任务(
create_instance.yml
),该任务包含并从playbook接收不同的定制变量,并通过运行不同的KVM/shell命令来抽象整个过程

作为参考,我最终得到了如下结果:

- name: Generate VMs for DB
  hosts: hypervisor_fe
  tags: platform,mongodb
  tasks:
    - include: tasks/create_instance.yml
      vars:
        vm: "{{ item }}"
      with_items: "{{ mongodb.vms }}"
      register: mongo_instances
      async: 7200
      poll: 0

    - name: Wait for instance creation to complete
      async_status: jid={{ item.ansible_job_id }}
      register: mongo_jobs
      until: mongo_jobs.finished
      retries: 300
      with_items: "{{ mongo_instances.results }}"
但是,此设置似乎忽略了所有新的异步代码,并保留了旧的顺序行为。我猜这与导入任务中播放的次数和粒度有关。如果我替换
include
来执行一个单一的、明确的长时间运行的任务,比如说

- name: Test async operation
  shell: ping -c1 {{ item.hostname }} && sleep 20
这似乎很好,对每个
项运行一个ping,然后继续执行下一个操作


这个假设正确吗?是否有人有过ansible中的
include
和异步循环的经验?我是否需要将异步声明移动到导入代码中的单个播放中?

我建议您以以下方式重新考虑playbook设计:

- hosts: localhost
  tasks:
    - add_host:
        name: "{{ item.name }}"
        groups: new_vms
        vm: "{{ item }}"
      with_items: "{{ mongodb.vms }}"

- hosts: new_vms
  tasks:
    - include: create_instance.yml
create_instance.yml
中使用
delegate_to:hypervisor_fe


这将为每个vm提供本地Ansible主机循环,同时执行每个任务。

根据@konstantin suvorov在文章中所读到的内容:“include不能使用async关键字”-因此,这似乎现在不是一个选项。在ansible的GH上挖掘发现了这个FR:当试图收集
新虚拟机(尚未创建)的事实时,这不会因为“无法访问”而失败吗?是否有方法将
委托应用于include上的所有任务?(~30)您可以使用
collect\u facts:no
禁用它,然后使用
setup
模块收集它们。您可以将
delegate_应用于:localhost
应用于
include
语句,或将
block
添加到任务文件中,并将
delegate_应用于块。