这是针对一组主机的,其中最多只有一台提供服务的主机可能同时处于关闭状态,并且主机的设置可能是一个复杂的例程。我已经尝试过serial: 1
(在 Ansible 术语中是滚动更新)、、--limit $host
。--fork 1
它们都以不理想的方式工作:它仍然逐个运行,而不是逐个主机运行。
以下是解决方案的当前属性和所需属性(这是一个主题问题,也可以从头开始重写解决方案):
- 我有一套剧本——可以随时使用的解决方案。
- 我想针对每个主机逐一运行此解决方案。
- 在游戏启动之前使用 Python 逻辑创建库存(已完成)。
- 主机已经分布在任意一组组中。某些主机只是一个组的成员,某些主机只是另一个组的成员。我有动态的inventory(Ansible 动态库存功能)并且 inventory 中总是有一个自动生成的组,其中包含全部涉及的主持人。
寻找如何:
- 所有比赛都应在第一场赛事中进行并结束。
- 所有比赛都应在第二台主机上运行并完成。
- 以此类推,主机数量任意。
- 如果主机不是来自剧本的组,则不应在该主机上应用剧本。
请告诉我:我怎样才能实现它?
以下是剧本集的简化部分。它已经创建完毕,并且通常可以正常工作。
我的顶级剧本site.yaml
---
- name: Site set up
hosts:
- masters
- replicas
serial: 1
roles:
- role: do-01
- role: do-02
- import_playbook: play-do-11.yaml
- import_playbook: play-do-12.yaml
我有剧本:play-do-11.yaml
,play-do-12.yaml
就像这样:
---
- name: play-do-11
hosts: satellites
serial: 1
roles:
- role: actor
我正在以这种方式启动 Ansible 剧本:
for single_host in host-a host-b host-c ; do
ansible-playbook \
--forks 1 \
--limit "$single_host" \
--inventory inventory.json \
"site.yaml"
done
PS 这超出了范围,但它为我正在寻找的解决方案增加了灵活性。事实上,我有动态库存。它可以在任何其他项目启动之前启动。有一个自动添加的组,其中包含库存中所有主机的简单列表。因此,我可以创建预生成的 Json,并且在启动之前,我将所有主机名作为纯字符串。它在 Shell 启动器中的使用方式如下:
for host in $( cat inventory.json | jq -r ".\"group-with-all\".hosts | keys[]" ) ; do
ansible-playbook --limit "${host}" ...
done
对于自动化来说它已经足够好了:主机分组和属性仍然在一个地方进行管理。
答案1
问:“所有比赛都应在第一个主机上运行并结束。所有比赛都应在第二个主机上运行并结束。依此类推,在任意数量的主机上运行。”
答:不可能。串行和战略是一个剧本。所有主持人必须完成一个剧本后才能开始下一个剧本。导入剧本相当于开始一个新剧本。
问:“如果主机不是来自剧本的组,则不应将游戏应用于该主机。”
答:可以在第一个剧本中创建一个新组,并在导入的剧本中使用它。例如,库存
shell> cat hosts
[test]
test_01
test_02
test_03
[satellites]
test_03
和剧本
shell> cat play-do-11.yml
- hosts: my_dynamic_group
tasks:
- debug:
var: inventory_hostname
从剧本中导入
shell> cat site.yml
- hosts: test
tasks:
- add_host:
name: "{{ item }}"
groups: my_dynamic_group
loop: "{{ groups.test }}"
when: item in groups.satellites
run_once: true
- debug:
var: inventory_hostname
- import_playbook: play-do-11.yml
注意:(可选)相交组并忽略条件:
- add_host:
name: "{{ item }}"
groups: my_dynamic_group
loop: "{{ groups.test|intersect(groups.satellites) }}"
run_once: true
给出
shell> ansible-playbook site.yml
PLAY [test] ***
TASK [add_host] ***
skipping: [test_01] => (item=test_01)
skipping: [test_01] => (item=test_02)
changed: [test_01] => (item=test_03)
TASK [debug] ***
ok: [test_01] => {
"inventory_hostname": "test_01"
}
ok: [test_03] => {
"inventory_hostname": "test_03"
}
ok: [test_02] => {
"inventory_hostname": "test_02"
}
PLAY [my_dynamic_group] ***
TASK [debug] ***
ok: [test_03] => {
"inventory_hostname": "test_03"
}
PLAY RECAP ***