首页 > Technology > 正文

Ansible 主机连不上:UNREACHABLE 排错手册

fenij 2026-10-09 4 Technology

Ansible 报 UNREACHABLE! 时,九成是 SSH 层的问题,不是 playbook 写错。按报错串分诊,三步内能定位:连不上(Connection refused / timed out)、认不了(Permission denied / Host key verification failed)、上不去(成为 root 失败)。下面按真实排查顺序来。

UNREACHABLE 和 FAILED 不是一回事

很多新手把 UNREACHABLE 当成任务失败。两者完全不同:UNREACHABLE 是传输层失败——SSH 根本没连上主机;FAILED 是连上了,但任务执行出错。连不上时 Ansible 连 Python 都没机会在目标机跑,所以先别怀疑你的剧本。

报错串 含义 主嫌疑
Connection refused 端口通了但服务拒绝 sshd 没起 / 端口写错
Connection timed out 包根本没到 防火墙 / IP 错误 / 网络
Permission denied 连上了但认证失败 密钥 / 用户名 / 权限
Host key verification failed known_hosts 指纹不匹配 主机重装过系统

第一步:手动 SSH,把 Ansible 排除在外

先证明「人」能连上,再谈「Ansible」为什么连不上。用 -vvvv 跑一次 ping 模块,Ansible 会把实际拼出的 SSH 命令打印出来:

ansible web01 -m ping -vvvv

看输出里 ssh -C -o ControlMaster=auto ... user@ip 这一段,把它整条复制出来手动执行。能通,说明问题在 Ansible 侧;不通,问题在网络/目标机侧。

第二步:按报错串对号入座

🔑 refused → 查 sshd:systemctl status sshd
🌐 timed out → 查防火墙:ufw status / iptables -L
🪪 denied → 查密钥:chmod 600 + ssh-copy-id
🔄 host key → 清指纹:ssh-keygen -R IP
# 目标机上:sshd 状态与配置校验
sudo systemctl status sshd
sudo sshd -t
sudo tail -50 /var/log/auth.log | grep -i ssh

# 控制机上:端口通不通
nc -zv 10.0.1.50 22

第三步:怀疑 inventory 和 ansible.cfg 解析

最常见也最隐蔽的坑:Ansible 实际用的不是你以为的那份清单。先看解析结果,再改配置:

ansible-inventory --host web01 --list
ansible --version   # 看顶部 Config file 指向哪份 ansible.cfg

确认 ansible_host、ansible_user、ansible_port、ansible_ssh_private_key_file 四项都对。旧主机重装后指纹变了就 ssh-keygen -R 10.0.1.50;临时环境可在 ansible.cfg 里 host_key_checking = False(生产别这么干)。

踩坑实录

上个月给一台腾讯云 2C4G 配免密,playbook 一直报 UNREACHABLE! => {"msg": "Failed to connect ... Connection timed out"},手动 ssh ubuntu@IP 却能秒连。折腾半天,最后 ansible-inventory --host web01 --list 一看,ansible_host 是 10.0.1.5——把内网 IP 填进清单了,控制机在外网当然超时。改成公网 IP 后一次通过。另一台重装系统后报 Host key verification failed,ssh-keygen -R 清掉旧指纹即好。

配置修复速查

⏱ 超时太短
timeout = 30
ansible.cfg [defaults]
🔁 失败重试
retries = 3
[ssh_connection]
🚀 提速
pipelining = True
需要目标机 /etc/sudoers 无 requiretty
[defaults]
inventory = ./inventory.ini
remote_user = ubuntu
timeout = 30
host_key_checking = False

[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ConnectTimeout=30
retries = 3

常见问题

Q:手动 SSH 能通,Ansible 却报 UNREACHABLE,为什么?
Ansible 用的用户名/密钥/端口和你不一致,或 inventory 里 ansible_host 写错。用 -vvvv 看它实际执行的 ssh 命令。

Q:报 Connection timed out 一定是防火墙吗?
不。内网 IP 填进清单、目标机离线、安全组没放行 22 都表现为超时。先 nc -zv 排除网络层。

Q:目标机没有 Python 会怎样?
连上但模块执行失败,报错是 FAILED 且提示 /usr/bin/python 缺失,不是 UNREACHABLE。可在 inventory 指定 interpreter_python。

本文是实操记录,踩过的坑都写在上面了。遇到新问题欢迎在 fenij.com 留言交流。

排错自查清单

  • ☐ UNREACHABLE 和 FAILED 不是一回事:很多新手把 UNREACHABLE 当成任务失败。两者完全不同:UNREACHABLE 是传输层失败——SSH
  • ☐ 第一步:手动 SSH,把 Ansible 排除在外:先证明「人」能连上,再谈「Ansible」为什么连不上。用 -vvvv 跑一次 ping 模块,Ansible
  • ☐ 第二步:按报错串对号入座
  • ☐ 第三步:怀疑 inventory 和 ansible.cfg 解析:最常见也最隐蔽的坑:Ansible 实际用的不是你以为的那份清单。先看解析结果,再改配置:
  • ☐ 踩坑实录:上个月给一台腾讯云 2C4G 配免密,playbook 一直报 UNREACHABLE! => {"ms
  • ☐ 配置修复速查
  • ☐ 常见问题:Q:手动 SSH 能通,Ansible 却报 UNREACHABLE,为什么?Ansible 用的用户名/密钥

关键命令速查

  • ansible web01 -m ping -vvvv
  • # 目标机上:sshd 状态与配置校验 sudo systemctl status sshd sudo sshd -t sudo tail -50 /var/log/auth.lo
  • ansible-inventory --host web01 --list ansible --version # 看顶部 Config file 指向哪份 ansible.cfg
  • [defaults] inventory = ./inventory.ini remote_user = ubuntu timeout = 30 host_key_checking

相关延伸

更系统的排查思路,见 Technology 分类归档。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: