Ansible 的 forks 指并发 SSH 连接数而非线程数,默认值 5 是为避免控制节点资源耗尽和目标端 SSH 拒绝连接;合理值通常为 20–50,需结合硬件、目标端限制及任务类型动态调整,并配合 serial 实现分批执行。

Ansible 的 forks 不是“线程数”,而是并发 SSH 连接数;盲目调高反而容易触发连接拒绝、任务失败或控制节点卡死。
为什么默认 forks=5 这么低
Ansible 默认设为 5,不是性能差,而是保守设计:避免控制节点被大量 SSH 进程压垮(尤其在内存小、CPU 少的跳板机上),也防止目标端 SSH 服务因并发登录过多而拒绝新连接(比如 OpenSSH 的 MaxStartups 默认常为 10)。实测中,forks=50 在百台主机规模下已可能让控制节点 CPU 持续 >90%,而部分被控端开始报 Failed to connect to the host via ssh: ssh: connect to host x.x.x.x port 22: Connection refused。
-
forks实际受限于控制节点的可用文件描述符(ulimit -n)、SSH 连接池容量和目标端 SSH 配置 - Ansible 2.9+ 版本中,
forks超过 100 后性能提升趋缓,但错误率明显上升 - 建议先用
ansible-config dump | grep DEFAULT_FORKS确认当前值,再结合ansible all -m ping -f 20做压力探针
怎么设一个靠谱的 forks 值
别拍脑袋填 100 或 200。真实场景里,最优值往往落在 20–50 区间,且需动态调整:
- 若控制节点是 4 核 / 8GB 内存的普通 VM:
forks = 30是较稳的起点 - 若被控端全是容器或轻量云主机(如 t3.micro):
forks宜降到 10–20,避免触发其 SSH 限流 - 若 playbook 中含大量
copy或template(高带宽/磁盘 I/O):forks超过 25 后,控制节点磁盘写入可能成为瓶颈,此时降为 15 反而更快 - 可在命令行临时覆盖:
ansible-playbook site.yml -f 40,比改ansible.cfg更安全
forks 和 serial 必须配合用
只调 forks 不设 serial,等于把“并发压力”全堆在单次任务上——比如一次对 200 台机器跑 yum update,哪怕 forks=30,仍可能集体夯住目标端包管理器或镜像源。
-
serial: 10表示每次只对 10 台主机执行完整 play(所有 tasks),其余等待;适合滚动更新、服务重启等敏感操作 -
serial: "25%"更灵活,适用于主机数不固定时(如 autoscaling 组) - 注意:
serial作用于 play 级别,不是 task 级别;它和forks是正交关系:前者控制“批大小”,后者控制“每批并发度” - 典型组合:
forks=30+serial: 15,即每次发 15 台主机的任务,每批内部最多并行 30 连接(实际受限于 15)
真正影响效率的,常不是 forks 本身
很多人调完 forks 发现没变快,问题往往在别处:
- SSH 连接开销占大头?加
ssh_args = -o ControlMaster=auto -o ControlPersist=60s到ansible.cfg的[ssh_connection]段 - 每次执行都重收集 facts?在 play 中加
gather_facts: false,或全局设gathering = explicit - 任务本身慢(比如
pip安装)?用async/poll把它扔后台,而不是靠提高forks硬扛 - 发现
copy模块特别拖?确认是否启用了pipelining = true(需目标端 Python 支持)
真正卡点,往往藏在连接复用、facts 收集、模块实现细节里,而不是 fork 数字本身。











