最近,我遇到了我们烦人的剧本代码中的瓶颈。我们正在按顺序部署群集(例如mongoDB Replica Set),即一个虚拟机接一个虚拟机,每个虚拟机都等待上一个虚拟机启动并运行。
这使整个集群的部署时间减慢了一个成员的速度。
为解决这个问题,我开始研究ansible's async actions and pooling,并发现了一些类似我们的方案的并行循环和“ 即弃即用”策略的示例。
特别的是,我们定义了我们自己的“定制VM并生成它” ansible任务(create_instance.yml
),该任务被包括在内并从剧本中接收不同的定制变量,并通过运行不同的程序来抽象整个过程KVM / shell命令。
使用"Parallel task execution in 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 }}"
但是,此设置似乎确实忽略了所有新的异步代码,并保留了旧的顺序行为。我猜想这与否有关。以及导入任务中的游戏粒度。如果我改为将include
替换为单个,明确的长期运行的任务-例如,
- name: Test async operation
shell: ping -c1 {{ item.hostname }} && sleep 20
这似乎确实可以正常工作,对每个item
执行一次ping操作,然后继续执行下一个操作。
这个假设正确吗?有人对include
有经验,并且在ansible中进行了异步循环吗?我是否需要将异步声明移到导入代码中的单个播放中?
答案 0 :(得分:1)
我建议您通过以下方式重新考虑您的剧本设计:
- 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
。
这为您提供了每个虚拟机的本机Ansible主机循环,同时执行每个任务。