我想仅在一台主机上使用 Ansible 运行任务。为此,我使用参数run_once
。
但真正令人惊叹的是能够指定一种策略来选择一台主机来运行该任务。例如,具有最高可用内存的主机。
如果该功能存在于在 libvirt 集群上创建新虚拟机的 playbook 上,我计划使用该功能。
答案1
据我所知,还没有这样的综合机制。该任务将从清单中的第一个主机开始,具体取决于您的游戏中匹配的内容(即参数hosts
)以及最终您在命令行上使用的限制(即-l
ansible playbook 的选项),并且将在该主机之后停止(如果run_once
是)用过的。
同时,我认为有一种方法可以实现你的目标。
背景信息
- Ansible 维护了一些魔法变量在这之中:
ansible_play_hosts
- 当前游戏运行中的活动主机列表受序列号(又称“批次”)限制hostvars
- 包含清单中所有主机和分配给它们的变量的哈希图
- 每个主机上的可用内存在 中可用
ansible_memfree_mb
。仅当您在主机上收集事实时,此变量才存在(即您gather_facts: no
在游戏中没有关闭此功能) - 该解决方案使用两个过滤器,您可能想更深入地了解它们
map
允许我们仅从中提取相关的主机信息hostvars
json_query
(实施jmespath
)允许我们过滤变量列表以查找最大内存并在最终仅获取相关节点的主机名
建议的解决方案
下面的剧本演示了如何结合上述元素来达到目标。该任务使用run_once
、delegate_to
和的组合delegate_facts
,以便它在特定主机上运行,就像首先选择它一样。
---
- name: Delegate single running task to dynamically chosen host
hosts: all
gather_facts: true
vars:
max_mem_query: max_by(@, &ansible_memfree_mb).inventory_hostname
selected_host: >-
{{
ansible_play_hosts |
map('extract', hostvars) |
list |
json_query(max_mem_query)
}}
tasks:
- name: Run a command on host with most memory
debug:
msg: "I would run on host {{ inventory_hostname }}"
run_once: true
delegate_to: "{{ selected_host }}"
delegate_facts: true
笔记:我只针对具有两个本地 docker 实例的清单进行了测试,以验证我的剧本,因此输出并不真正相关(所有实例都具有相同的可用内存,选择第一个实例恰好委托给自身)。但我非常有信心它会起作用,并且我准备对其进行编辑以适应一些最终的怪癖(如果没有的话)。