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

Alf*_*eme 5 asynchronous ansible

最近我在我们的 ansible playbook 代码中遇到了一个瓶颈。我们按顺序部署集群(例如mongoDB 副本集),即一个虚拟机一个接着另一个虚拟机,每个虚拟机都等待前一个虚拟机启动并运行。

这会减慢整个集群的部署时间,其影响因素是其成员的一个因素。

为了解决这个问题,我开始深入研究ansible 的异步操作和池化,并找到了一些关于并行循环和“即发即忘”策略的示例,适用于像我们这样的场景。

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

使用Ansible 中的并行任务执行作为参考,我最终得到了类似的结果:

- 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 }}"
Run Code Online (Sandbox Code Playgroud)

但是,此设置似乎确实忽略了所有新的异步代码并保留了旧的顺序行为。我猜这与否有关。以及导入任务中的播放粒度。如果我将 替换include单个显式的长时间运行的任务 - 比如说,例如

- name: Test async operation
  shell: ping -c1 {{ item.hostname }} && sleep 20
Run Code Online (Sandbox Code Playgroud)

这似乎工作得很好,对每个运行一次 ping item,然后继续执行下一个操作。

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

Kon*_*rov 5

我建议您按照以下方式重新考虑您的剧本设计:

- 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
Run Code Online (Sandbox Code Playgroud)

并内create_instance.ymldelegate_to: hypervisor_fe

这为每个虚拟机提供了本机 Ansible 主机循环,并并发执行每个任务。

  • 您可以使用“gather_facts: no”禁用它,并稍后使用“setup”模块收集它们。您可以将 `delegate_to: localhost` 应用于 `include` 语句,或者将 `block` 添加到任务文件中并将 `delegate_to` 应用于该块。 (3认同)