parallel-processing - 使用 ansible 与多个组和服务器一起播放和执行任务
问题描述
我们有这个包含数十台服务器的 Ansible 清单,按微服务分组在服务器中。假设我们在清单中有几个应用程序组,其中包含服务器。
说:
[group1]
server1
server2
server3
server20
server27
server38
[group2]
server4
server5
[group3]
server7
server8
server9
server6
该库存已用于数十场比赛,因此仅更改它不是一种选择。我需要处理这个设置。
我需要知道是否有可能以某种方式在每个组的一台服务器上并行运行一个剧本而不在剧本中明确命名它们?(组和服务器可以由其他人添加,我需要玩才能应付)
因此,当播放开始时,它可能会在 server1、server4 和 server7 上并行处理。server2 上的处理可能在 server1 完成时开始,server5 的处理可能在 server4 完成时开始,等等。你明白我的意思。这将意味着,在开始时,每个组的一个服务器被处理,但随着时间的推移,较小的组将完成,而在较大的组中仍然会进行处理。
有没有办法做到这一点?
蒂亚
解决方案
问:“在每个组中的 1 台服务器上并行运行......在 server1、server4 和 server7 上并行处理。server1 完成时可能会开始 server2 上的处理,当 server4 完成时可能会开始 server5 的处理,等等......迭代编写代码时未知的多个组和服务器。 ”
A:作为一个不完整的提示,下面的剧本
- hosts: all
gather_facts: false
vars:
_groups: "{{ groups.keys()|difference(['all', 'ungrouped']) }}"
# _hosts: [0, 1, 2] # Range of minimal common leght perhaps?
_groups_len_min: "{{ _groups|map('extract', groups)|map('length')|min }}"
_hosts: "{{ range(_groups_len_min|int) }}"
my_hosts: "{{ query('cartesian', _hosts, _groups) }}"
tasks:
- add_host:
name: "{{ groups[item.1][item.0] }}"
groups: my_group
loop: "{{ my_hosts }}"
run_once: true
- hosts: my_group
gather_facts: false
serial: 3 # TODO: Number of the groups involved
order: inventory
tasks:
- debug:
var: inventory_hostname
给
PLAY [my_group] ***************************************************
TASK [debug] ******************************************************
ok: [server4] =>
inventory_hostname: server4
ok: [server1] =>
inventory_hostname: server1
ok: [server7] =>
inventory_hostname: server7
PLAY [my_group] ***************************************************
TASK [debug] ******************************************************
ok: [server2] =>
inventory_hostname: server2
ok: [server5] =>
inventory_hostname: server5
ok: [server8] =>
inventory_hostname: server8
PLAY [my_group] ***************************************************
TASK [debug] ******************************************************
ok: [server6] =>
inventory_hostname: server6
ok: [server3] =>
inventory_hostname: server3
ok: [server9] =>
inventory_hostname: server9
如果你想包括所有主机,用假人填充缺失的主机,例如给定库存
shell> cat hosts
[group1]
server1
server2
server3
[group2]
server4
server5
[group3]
server7
剧本
- hosts: all
gather_facts: false
vars:
_groups: "{{ groups.keys()|difference(['all', 'ungrouped']) }}"
_groups_len_max: "{{ _groups|map('extract', groups)|map('length')|max }}"
_hosts: "{{ range(_groups_len_max|int) }}"
my_hosts: "{{ query('cartesian', _hosts, _groups) }}"
tasks:
- add_host:
name: "{{ groups[item.1][item.0]|default('dummy-' ~ ansible_loop.index) }}"
groups: my_group
loop: "{{ my_hosts }}"
loop_control:
extended: true
run_once: true
- hosts: my_group
gather_facts: false
serial: 3 # TODO: Number of the groups involved
order: inventory
tasks:
- name: Proceed if not dummy
block:
- debug:
var: inventory_hostname
when: inventory_hostname is not match('^dummy-\d*$')
给
PLAY [my_group] *****************************************************
TASK [debug] ********************************************************
ok: [server1] =>
inventory_hostname: server1
ok: [server4] =>
inventory_hostname: server4
ok: [server7] =>
inventory_hostname: server7
PLAY [my_group] *****************************************************
TASK [debug] ********************************************************
skipping: [dummy-6]
ok: [server2] =>
inventory_hostname: server2
ok: [server5] =>
inventory_hostname: server5
PLAY [my_group] *****************************************************
TASK [debug] ********************************************************
ok: [server3] =>
inventory_hostname: server3
skipping: [dummy-8]
skipping: [dummy-9]
笔记
一个简单的选择是创建动态组,例如
- hosts: all
gather_facts: false
vars:
my_groups:
my_group1: [[group1,0], [group2,0], [group3,0]]
my_group2: [[group1,1], [group2,1], [group3,1]]
my_group3: [[group1,2], [group2,2], [group3,2]]
tasks:
- add_host:
name: "{{ groups[item.1.0][item.1.1] }}"
groups: "{{ item.0.key }}"
with_subelements:
- "{{ my_groups|dict2items }}"
- value
run_once: true
- hosts: my_group1
gather_facts: false
tasks:
- debug:
var: inventory_hostname
- hosts: my_group2
gather_facts: false
tasks:
- debug:
var: inventory_hostname
- hosts: my_group3
gather_facts: false
tasks:
- debug:
var: inventory_hostname
给出(删节)
PLAY [my_group1] *******************************************************
TASK [debug] ***********************************************************
ok: [server1] =>
inventory_hostname: server1
ok: [server7] =>
inventory_hostname: server7
ok: [server4] =>
inventory_hostname: server4
PLAY [my_group2] *******************************************************
TASK [debug] ***********************************************************
ok: [server5] =>
inventory_hostname: server5
ok: [server2] =>
inventory_hostname: server2
ok: [server8] =>
inventory_hostname: server8
PLAY [my_group3] *******************************************************
TASK [debug] ***********************************************************
ok: [server3] =>
inventory_hostname: server3
ok: [server6] =>
inventory_hostname: server6
ok: [server9] =>
inventory_hostname: server9
下一个选项是创建具有所需主机顺序的单个组并设置serial和order,例如
- hosts: all
gather_facts: false
vars:
my_groups:
my_group1: [[group1,0], [group2,0], [group3,0]]
my_group2: [[group1,1], [group2,1], [group3,1]]
my_group3: [[group1,2], [group2,2], [group3,2]]
tasks:
- add_host:
name: "{{ groups[item.1.0][item.1.1] }}"
groups: my_group
with_subelements:
- "{{ my_groups|dict2items }}"
- value
run_once: true
- hosts: my_group
gather_facts: false
serial: 3
order: inventory
tasks:
- debug:
var: inventory_hostname
给出(删节)
PLAY [my_group] ****************************************************
TASK [debug] *******************************************************
ok: [server1] =>
inventory_hostname: server1
ok: [server7] =>
inventory_hostname: server7
ok: [server4] =>
inventory_hostname: server4
PLAY [my_group] ****************************************************
TASK [debug] *******************************************************
ok: [server2] =>
inventory_hostname: server2
ok: [server5] =>
inventory_hostname: server5
ok: [server8] =>
inventory_hostname: server8
PLAY [my_group] ****************************************************
TASK [debug] *******************************************************
ok: [server3] =>
inventory_hostname: server3
ok: [server6] =>
inventory_hostname: server6
ok: [server9] =>
inventory_hostname: server9
为了避免手动编写大型矩阵的繁琐工作,可以动态创建结构,例如下面的播放创建相同的动态组
- hosts: all
gather_facts: false
vars:
_groups: [group1, group2, group3]
_hosts: [0, 1, 2]
_dgroups: [my_group1, my_group2, my_group3]
_groups_hosts: "{{ query('cartesian', _hosts, _groups)|
batch(_dgroups|length) }}"
my_groups: "{{ dict(_dgroups|zip(_groups_hosts)) }}"
tasks:
- add_host:
name: "{{ groups[item.1.1][item.1.0] }}"
groups: my_group
with_subelements:
- "{{ my_groups|dict2items }}"
- value
run_once: true
推荐阅读
- spring - spring kafka消费者单批拉取不同分区的数据
- html - 我如何将这 2 个按钮以不同的形式并排放置
- azure - 如何将 Azure 资源从一个目录迁移到另一个目录
- java - 需要为 SseEmitter rest 编写 Swagger yaml (MVC server-sent-events)
- python - 使用 ffmpeg 调整大小后文件损坏
- c# - 如何以编程方式设置面板上控件的位置?
- go - 当其中一个关闭时交换 websocket 连接
- angular - 如何以角度为组件的“主体”设置样式?
- java - Mac 上的 JFileChooser 不返回文件
- git - 使用 TortoiseGIT 创建修补程序