ansible的--check模式是模拟执行机制而非探针工具,通过支持check_mode的幂等模块(如setup、stat、uri)采集事实并用assert断言实现安全可观测探针,需规避command/shell等不支持模块及运行时副作用。

Ansible 的 --check 模式(Check Mode)本身不是探针工具,而是一种“模拟执行”机制。它不真正变更系统,而是让所有模块按预期逻辑运行一遍,返回“如果真实执行会怎样”的预测结果。在大规模线上集群中,用好 Check Mode + 合理设计任务,就能实现安全、无损、可量化的环境探针。
明确 Check Mode 的能力边界
Check Mode 不等于“只读”,也不等于“绝对安全”:
- 它依赖模块是否原生支持 check_mode —— 核心模块如
file、copy、yum、service等均支持;但自定义脚本、command或shell模块默认忽略 check_mode,除非显式加ignore_errors: yes并配合changed_when控制判断逻辑 - 它不能替代真实巡检脚本的输出解析 —— 比如你想知道磁盘使用率是否超阈值,Check Mode 本身不会采集数据,需靠
setup模块或自定义脚本返回 facts,并用assert或fail模块做校验 - 它不捕获运行时副作用 —— 例如某命令在 check 下返回成功,但实际执行可能触发内核 panic(极罕见),这类风险需靠模块幂等性设计和前置测试规避
构建无损探针 Playbook 的关键结构
一个面向生产集群的探针 Playbook 应聚焦“可观测性+可判定性”,而非“修复”:
-
只用幂等模块采集事实:优先使用
setup(获取 OS、CPU、内存、网络等基础 facts)、stat(检查文件存在性、权限、mtime)、uri(探测服务端口/健康接口)、community.general.systemd_service(查服务状态) -
用 assert 做策略断言:例如检查
ansible_memfree_mb / ansible_memtotal_mb | float * 100 ,失败则报 <code>critical: memory usage too high,不中断执行流 -
禁用非幂等操作:整个 playbook 中不出现
state: restarted、force: yes、backup: yes等真实变更指令;copy和template只用于下发只读探针脚本(如check_linux.sh),且目标路径设为/tmp/或/var/tmp/ -
统一输出结构:通过
set_fact聚合各节点检测结果,最后用debug或community.general.json_file输出标准化 JSON,便于后续日志采集或告警对接
适配大规模集群的实操要点
百万级节点不是靠单次全量跑完,而是靠分片+异步+反馈闭环:
-
动态 Inventory 分组:用脚本生成基于标签的 inventory(如
env=prod,role=api,region=sh),避免硬编码 IP;结合ansible-inventory --graph验证分组逻辑 -
限流与并发控制:设置
forks: 20(非盲目调高),配合throttle: 5控制单任务并发数;对核心数据库组额外加serial: 1逐台探针 -
跳过不可达节点:在 play 级加
ignore_unreachable: yes,避免一台失联导致整批中断;再用failed_when: false+register收集连接失败数 -
结果聚合与分级告警:用
delegate_to: localhost在控制节点汇总数据,按 OK/Bad/Critical 三级分类;Critical 项自动触发邮件或钉钉 Webhook,Bad 项仅记录日志
一个轻量探针示例(片段)
以下 playbook 片段仅执行检查,不修改任何配置:
- name: Probe disk usage across webgrouphosts: webgroup
gather_facts: yes
ignore_unreachable: yes
tasks:
- name: Get root fs stat
stat:
path: /
register: rootfs_stat
- name: Assert root fs usage assert:
that:
- (rootfs_stat.stat.size_total | int - rootfs_stat.stat.size_free | int) / rootfs_stat.stat.size_total | float * 100 msg: "CRITICAL: root filesystem usage exceeds 85%"
- name: Report result
debug:
msg: "{{ inventory_hostname }}: root usage {{ ((rootfs_stat.stat.size_total | int - rootfs_stat.stat.size_free | int) / rootfs_stat.stat.size_total | float * 100) | round(1) }}%"
verbosity: 1











