我想在 ansible 组上运行特定命令。然而,此命令(设备升级)使该设备不可用,也使子设备不可用。
Ansible 是否可以以某种方式定义依赖列表,即。设备拓扑并按该顺序运行命令,更重要的是,不会因为另一个父设备不可用而失败?
实际上: R1 -> SW1 -> SW2 :升级应从 SW2 开始,然后是 SW1。 R1 至少要等到 SW1 启动后才能更新,因为上行链路是从 SW1 接收的,所以它应该等待 SW1。
Ps.:我已经阅读了所有其他相关主题,我需要在多组设备上执行此操作,因此使用硬编码组创建特定的剧本并不是那么理想。
至少有两种相对简单的方法可以实现这一目标。一种看起来有点笨拙,但它既快速又安全,另一种更优雅,但包含一些警告。
最直接的方法是组织您的库存,以便层次结构反映在组名称中。如果我们考虑依赖的深度有限,我们可以简单地拥有与最大深度相对应的播放次数(请参阅下面关于硬编码的注释)。如果我们将
level_1
定义为最高级别(在您的示例中为 R1
),我们的库存将是“开放式的”,因此我们可以根据需要细化任意多个级别。我们还可以跳过一些级别和/或将它们清空。当然,您可以使用更有意义的名称来代替级别编号:
# inventory.yaml
---
devices:
vars:
ansible_python_interpreter: auto_silent
ansible_connection: local
children:
level_1:
hosts:
R[1:3]:
level_2:
hosts:
SW[1:15]:
level_3:
level_4:
level_5:
hosts:
SW[20:30]:
# playbook.yaml
---
- name: Upgrade the devices of level 6
hosts: level_6
gather_facts: false # just for testing
tasks:
- name: Upgrading the device
debug:
var: inventory_hostname
# other levels go here
- name: Upgrade the devices of level 1
hosts: level_1
gather_facts: false # just for testing
tasks:
- name: Upgrade the device
debug:
var: inventory_hostname
在评论硬编码之前:是的,但这很有意义,因为 Ansible 并行运行组内的任务,并且戏剧是按顺序执行的。如果层次结构已定义且受到限制,我会推荐此解决方案。
但是,我们可以尝试不同的方法。 Ansible 提供了多种选项来
order
基于库存的执行。请注意,虽然可以选择使用主机定义的顺序,但通常不能保证。不过,它通常适用于简单的情况,但使用依赖于主机名的 sorted
或 reverse_sorted
顺序更可靠。因此,我们可以定义依赖设备的集合,而不是定义通用级别:
# inventory.yaml
---
devices:
vars:
ansible_python_interpreter: auto_silent
ansible_connection: local
children:
set_1:
hosts:
R1:
SW[1:15]:
SW[25:30]:
set_2:
hosts:
R2:
SW[1:4]:
SW[20:24]:
set_3:
hosts:
R3:
SW[150:155]:
SW[50:60]:
SW[75:80]:
# playbook.yaml
---
- name: Upgrade the devices
hosts: devices
gather_facts: false # just for testing
order: reverse_inventory
tasks:
- name: Upgrading the device
debug:
var: inventory_hostname
# ...
- name: Upgrade the devices of level 1
hosts: level_1
gather_facts: false # just for testing
tasks:
- name: Upgrading the device
debug:
var: inventory_hostname
当然,这些示例仅用于展示订购选项,在现实生活中很可能需要
wait_for
。此外,您应该注意一些细微差别:
SW[150:155]
),Ansible 会将一些后续主机添加到批处理中,以便“依赖”命令可能会被违反。理论上,也可以将层次结构级别定义为组/主机变量。但是,我们需要实现一种极其复杂的逻辑来控制执行流程,并且内置的并行功能可能(而且很可能)会丢失。无法将批量大小定义为库存变量,并且我们无法将戏剧动态添加到剧本中。
serial
可以从hostvars
设置,但由于我们当时没有inventory_hostname
,在这种情况下它是无用的,并不是说我们必须首先计算批量大小。我尝试实现它,但我不建议重复尝试:)