ansible 的 group_by 模块不能直接感知实时负载,但可通过三步实现按实时负载动态分组:1. 用 shell/command 采集负载并 set_fact 注入变量;2. 用 group_by key 引用变量生成 load_high/load_normal 等动态组;3. 在后续 play 中以动态组名为 hosts 执行差异化策略,且须在同一 play 内完成。

Ansible 的 group_by 模块本身不直接感知“实时负载”(如 CPU 使用率、内存占用、任务队列长度等),它只能基于 Ansible 在运行时收集到的主机事实(Facts) 进行动态分组。而标准 Facts(如 ansible_processor_vcpus、ansible_memtotal_mb、ansible_distribution 等)是静态快照,不是持续采集的实时指标。
但你可以通过组合方式,在 playbook 执行过程中注入实时负载信息,并以此驱动 group_by 分组,从而实现“按线上实时负载动态创建任务组并发布策略”。关键在于:先获取负载数据 → 注入为自定义事实 → 再用 group_by 分组。
以下是最实用、可落地的三步实现路径:
1. 在目标主机上采集实时负载并注册为变量
使用 `shell` 或 `command` 模块调用系统命令(如 `uptime`、`mpstat`、`free`),提取关键指标,并用 `set_fact` 将其转为可用变量:
- 例如,判断当前 1 分钟平均负载是否超过 CPU 核心数的 70%:
-
shell: awk '{print $1}' /proc/loadavg获取 loadavg -
shell: nproc获取逻辑 CPU 数 - 再用
set_fact计算比值并设标记:load_level: "{{ (load_avg | float) / (cpu_cores | int) | round(1) }}"和is_high_load: "{{ (load_avg | float) / (cpu_cores | int) > 0.7 }}"
2. 将负载状态映射为可分组的键值
用 `group_by` 的 key 参数引用你刚定义的变量,生成带语义的动态组名:
group_by: key=load_{{ 'high' if is_high_load else 'normal' }}- 执行后自动创建
load_high和load_normal两个内存中组 - 支持更细粒度,比如:
key=env_{{ env_type }}_load_{{ load_level | replace('.', '_') }}
3. 针对不同负载组执行差异化策略
后续 play 可直接以动态组名为 hosts,分别应用发布逻辑:
-
- hosts: load_high→ 执行降级策略、跳过非关键服务重启、启用熔断开关 -
- hosts: load_normal→ 执行标准滚动更新、健康检查、配置热加载 - 也可结合
when:做条件控制,例如仅在load_level 时触发灰度扩容
注意:整个过程必须在同一个 play 中完成(或至少同一 inventory scope),因为动态组只存在于当前 playbook 运行生命周期内;不能跨 play 直接引用前一个 play 创建的组,除非用 add_host 或外部缓存机制持久化。











