Ansible pipelining 是通过复用 SSH 会话、跳过临时文件上传步骤,将模块执行直接在单次 SSH 连接中完成的加速机制;它默认关闭,因需远程主机 sudo 配置 Defaults !requiretty 支持免 TTY 提权,否则会因缺少伪终端失败。

Ansible pipelining 是什么,为什么能提速
pipelining 是 Ansible 通过复用 SSH 连接通道、减少远程命令调用次数来加速任务执行的机制。默认关闭,因为需要远程主机的 sudo 配置支持免密码 TTY(否则会因缺少伪终端而失败)。开启后,Ansible 把多个操作(如模块传输、解压、执行、清理)合并进单次 SSH 会话,省去反复建立连接和上传临时文件的开销,尤其对小任务或高延迟网络效果明显。
它不改变任务逻辑,只优化底层传输链路,适用于大多数 command、shell、copy 等模块,但对依赖交互式终端(如需 sudo -i 或 expect 类行为)的场景可能失效。
如何安全开启 pipelining
开启前必须确认远程节点的 /etc/sudoers 允许当前用户无 TTY 执行命令:
- 在目标主机上运行
sudo visudo,添加行:%wheel ALL=(ALL) NOPASSWD: ALL(若用 wheel 组)或更精确地:ansible_user ALL=(ALL) NOPASSWD: ALL
- 关键:追加
Defaults !requiretty(全局)或 Defaults:ansible_user !requiretty(仅该用户),否则 pipelining 会卡在 sudo 密码提示或报错 sudo: sorry, you must have a tty to run sudo
- 在 Ansible 控制端配置
pipelining = True,位置优先级:inventory 变量 > ansible.cfg > 命令行 -e 'ansible_pipelining=True'
sudo visudo,添加行:%wheel ALL=(ALL) NOPASSWD: ALL(若用 wheel 组)或更精确地:ansible_user ALL=(ALL) NOPASSWD: ALL
Defaults !requiretty(全局)或 Defaults:ansible_user !requiretty(仅该用户),否则 pipelining 会卡在 sudo 密码提示或报错 sudo: sorry, you must have a tty to run sudo
pipelining = True,位置优先级:inventory 变量 > ansible.cfg > 命令行 -e 'ansible_pipelining=True'
推荐写入 ansible.cfg(项目根目录或 ~/.ansible.cfg):
分析 CI/CD 流水线(GitHub Actions、GitLab CI、CircleCI)并提出优化建议——缓存策略、并行化、步骤精简、Docker 层等。
[ssh_connection] pipelining = True
开启后常见失败现象和排查点
pipelining 开启却没提速,甚至报错,多数是环境未对齐:
- 错误信息含
Failed to connect to the host via ssh 或 sudo: no tty present → 检查 !requiretty 是否生效,用 ssh user@host 'sudo -n whoami' 验证
- 某些任务突然失败,比如
copy 模块报 MODULE FAILURE 且 traceback 提到 stdin → pipelining 下模块执行环境无完整 shell 上下文,避免在 shell 中依赖 source ~/.bashrc 或未导出的 alias
- 使用
become_method: su 时 pipelining 无效 → pipelining 仅支持 sudo 和 pfexec,不支持 su 或 doas
- Ansible 2.8+ 默认禁用 pipelining,且部分云厂商镜像(如 AWS Amazon Linux 2)默认关掉
requiretty,但新版本 sudo 可能重置策略 → 建议显式配置并验证
是否所有场景都该开 pipelining
不是。它在以下情况收益有限或应禁用:
- 远程主机 CPU/IO 极度受限:pipelining 把多步压缩进单次执行,可能加剧瞬时负载
- 调试阶段频繁修改 playbook:pipelining 会隐藏中间文件路径,不利于手动检查临时模块文件(如
/tmp/ansible_*)
- 使用自定义模块且依赖本地 shell 初始化(如需要
rbenv 或 pyenv 的 PATH)→ 此时建议关 pipelining 或改用 environment: 显式设置
- SSH 连接本身极快(如本地 Docker 容器),提速感知微弱,但引入配置复杂度不划算
Failed to connect to the host via ssh 或 sudo: no tty present → 检查 !requiretty 是否生效,用 ssh user@host 'sudo -n whoami' 验证copy 模块报 MODULE FAILURE 且 traceback 提到 stdin → pipelining 下模块执行环境无完整 shell 上下文,避免在 shell 中依赖 source ~/.bashrc 或未导出的 aliasbecome_method: su 时 pipelining 无效 → pipelining 仅支持 sudo 和 pfexec,不支持 su 或 doas
requiretty,但新版本 sudo 可能重置策略 → 建议显式配置并验证- 远程主机 CPU/IO 极度受限:pipelining 把多步压缩进单次执行,可能加剧瞬时负载
- 调试阶段频繁修改 playbook:pipelining 会隐藏中间文件路径,不利于手动检查临时模块文件(如
/tmp/ansible_*) - 使用自定义模块且依赖本地 shell 初始化(如需要
rbenv或pyenv的 PATH)→ 此时建议关 pipelining 或改用environment:显式设置 - SSH 连接本身极快(如本地 Docker 容器),提速感知微弱,但引入配置复杂度不划算
真正起效的关键不在“开了没”,而在“sudo 免 TTY + pipelining + 任务粒度适中”三者同时成立。漏掉任意一环,都只是白配。










