Ansible连接交换机报Failed to open session错误求助
你遇到的问题很典型:明明能直接SSH登录交换机,Ansible却连不上报会话打开失败。结合你的配置和Ansible 2.4.2.0的版本特性,我来一步步帮你排查解决:
先明确你的现有配置与操作
1. Ansible配置文件 (ansible.cfg)
[defaults] enable_task_debugger=True hostfile=inventory transport=paramiko host_key_checking=False
(注:你原来写的[Ansible.cfg]应该是[defaults]配置段,这个小细节得修正)
2. 库存文件 (inventory/hosts)
[127.0.0.1] ansible_connection=local [routers] 192.168.10.1
3. Playbook文件 (test.yaml)
--- - hosts: routers gather_facts: true connection: paramiko tasks: - name: show run ios_command: commands: - show version
4. 执行命令
ansible-playbook -vvv -i inventory test.yaml -u username -k
5. 核心报错
EXEC /bin/sh -c 'echo ~ && sleep 0' fatal: [192.168.10.1]: UNREACHABLE! => { "changed": false, "msg": "Failed to open session", "unreachable": true }
问题根源分析
从报错里的EXEC /bin/sh能看出关键问题:你开启了gather_facts: true,但IOS交换机不是类Unix系统,根本无法执行/bin/sh这类命令,这是导致会话打开失败的核心原因。另外,Ansible 2.4.x的paramiko连接方式可能存在兼容性问题,加上库存里没明确指定设备类型,也会让Ansible自动检测出错。
分步解决办法
1. 禁用默认事实收集(最关键的一步)
直接把playbook里的gather_facts改成false,因为IOS设备不支持Ansible默认的系统事实收集:
--- - hosts: routers gather_facts: false # 必须禁用 connection: paramiko tasks: - name: show version ios_command: commands: - show version
2. 在库存里明确设备参数
给交换机添加ansible_network_os和连接参数,避免Ansible自动检测错误:
修改inventory/hosts:
[routers] 192.168.10.1 ansible_network_os=ios ansible_connection=paramiko
3. 安装必要的依赖包
Ansible的IOS模块需要paramiko等依赖,确保你的环境安装正确:
pip install ansible[network] paramiko==2.4.2
(注:Ansible 2.4.2.0和paramiko 2.4.x版本兼容性最好,不要装太高版本)
4. 尝试改用network_cli连接(可选但推荐)
Ansible 2.4已经支持专门的network_cli连接方式,比paramiko更适配网络设备,你可以试试替换:
- 库存文件修改:
[routers] 192.168.10.1 ansible_network_os=ios ansible_connection=network_cli
- Playbook里的
connection改成network_cli
验证测试
修改完成后,重新执行playbook:
ansible-playbook -vvv -i inventory test.yaml -u username -k
如果还是有问题,先用Ansible的ping模块测试连通性(注意IOS的ping是特殊模块,需要指定network_os):
ansible routers -i inventory -m ping -u username -k -vvv
内容的提问来源于stack exchange,提问作者Gerald Germain

