如何让Ansible Playbook独立运行于多主机?为何久未返回UNREACHABLE?
Ansible批量打补丁:主机独立执行与连接超时问题解析
问题场景
我使用Ansible Playbook为100+台Linux服务器打补丁,有时部分主机的补丁进程会长时间卡住。当前配置为forks = 20,执行时出现如下情况:
TASK [Patching] ********************************************************************************************************************************** changed: [host1] changed: [host2] changed: [host3] STUCKED HERE
1小时后返回:
changed: [host1] changed: [host2] changed: [host3] fatal: [host4]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh
一、如何让Playbook独立运行于每台主机,无需等待其他主机?
- 调大forks并行数:当前
forks=20限制了同时执行的主机数量,可根据控制机硬件资源调高该值(例如forks = 100),让更多主机同时执行补丁任务。注意:forks值过高会消耗控制机大量CPU和内存,需根据实际情况调整。 - 使用异步任务模式:这是解决单主机卡住阻塞全流程的关键方案。通过
async和poll参数让补丁任务后台异步执行,控制机无需等待单台主机完成即可继续处理其他节点,后续再统一检查任务状态。示例Playbook片段:- name: 异步执行系统补丁 yum: name: '*' state: latest async: 3600 # 允许任务最长运行3600秒(1小时) poll: 0 # 立即返回,不等待任务结束 register: patch_task - name: 轮询检查补丁任务状态 async_status: jid: "{{ item.ansible_job_id }}" loop: "{{ patch_task.results }}" register: patch_status until: patch_status.finished retries: 60 # 最多重试60次 delay: 60 # 每次重试间隔60秒 - 拆分主机组分批执行:将100+台主机按业务、机房等维度拆分为多个小组,分别运行Playbook,避免单批次任务规模过大导致的阻塞。
二、为何等待1小时才返回UNREACHABLE状态?
这是Ansible默认的SSH连接超时与重试机制导致的:
- 默认超时参数过长:Ansible的
ansible_ssh_timeout默认值(或系统SSH配置的超时)通常较长,加上SSH连接的重试逻辑,会反复尝试连接不可达的host4,直到耗尽所有重试次数和超时时间才会抛出UNREACHABLE错误。 - 任务无超时限制:若补丁任务未设置超时,当主机连接异常时,Ansible会一直等待SSH响应,直到达到系统级的SSH超时上限(部分环境默认接近1小时)。
解决方法
缩短连接超时时间,可通过两种方式配置:
- Playbook内指定:
- hosts: all vars: ansible_ssh_timeout: 30 # 连接超时设为30秒 tasks: - name: 执行系统补丁 yum: name: '*' state: latest - 全局配置文件
ansible.cfg:
配置后,主机无法连接时会在30秒内返回错误,无需长时间等待。[defaults] timeout = 30
内容的提问来源于stack exchange,提问作者andrew
相关产品推荐
相关产品推荐

