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 侧;不通,问题在网络/目标机侧。
第二步:按报错串对号入座
🌐 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 清掉旧指纹即好。
配置修复速查
[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 留言交流。