Ansible包含任务报错:failed to open a SFTP connection问题排查
这个问题的核心在于Ansible默认的文件传输行为,以及动态添加主机(add_host)与静态清单主机在连接配置上的差异。
为什么会触发SFTP错误?
Ansible在执行任务时,默认会尝试建立SFTP连接——哪怕你用的是raw模块。这是因为Ansible会提前初始化SFTP会话,为后续可能的文件传输(比如拷贝模板、上传文件)做准备。但iLO的SSH服务(racadm环境)通常不支持SFTP协议,所以当Ansible尝试建立SFTP连接时,就会抛出Garbage packet received的错误。
而你单独运行collect_mac.yml时没有问题,是因为静态清单中的主机已经配置了合适的连接参数(可能你在清单里隐式设置了文件传输方式为SCP,或者禁用了SFTP),但通过add_host动态添加的ilohosts组主机,只设置了基础的SSH认证参数,缺少了禁用SFTP或指定SCP传输的关键配置。
解决方案:明确指定文件传输方式
你只需要在动态添加主机或任务中补充配置,强制Ansible使用SCP而非SFTP,或者直接禁用SFTP尝试即可。
方法1:在动态添加主机时指定传输方式
修改parent.yml中的add_host任务,添加ansible_ssh_transfer_method: scp:
- add_host: name: "{{ item.value['hostname'] }}" ansible_host: "{{ item.value['oob_ip'] }}" ansible_user: "{{ servers.web_servers.vars.ilousername }}" ansible_ssh_pass: "{{ servers.web_servers.vars.ilopassword }}" ansible_ssh_transfer_method: scp # 新增这一行 group: ilohosts
方法2:禁用SFTP(适用于Ansible 2.10+版本)
如果你的Ansible版本较新,可以直接添加ansible_sftp_enabled: false:
- add_host: name: "{{ item.value['hostname'] }}" ansible_host: "{{ item.value['oob_ip'] }}" ansible_user: "{{ servers.web_servers.vars.ilousername }}" ansible_ssh_pass: "{{ servers.web_servers.vars.ilopassword }}" ansible_sftp_enabled: false # 新增这一行 group: ilohosts
方法3:在collect_mac.yml的任务中临时指定
如果不想修改父Playbook的add_host配置,也可以在raw任务中通过vars临时设置传输方式:
- name: collect MAC address raw: "racadm getsysinfo" register: eth_info vars: ansible_ssh_transfer_method: scp
验证原理
添加这些配置后,Ansible会跳过SFTP连接的初始化,直接使用SCP进行文件传输(如果后续有需要),或者完全禁用SFTP尝试,这样就不会和iLO的SSH服务产生协议冲突,raw命令就能正常执行了。
内容的提问来源于stack exchange,提问作者Chamisxs

