Ansible批量执行必须同时满足Inventory格式正确和SSH免密通路可用两个硬性条件,且须先配置免密再验证Inventory;Inventory为INI格式,组名独占一行,主机行端口用IP:2222写法,变量需分主机行末尾与[group:vars]段定义,免密失败常见于known_hosts未预置或权限错误。

Ansible 要能批量执行,必须同时满足两个硬性条件:主机清单(Inventory)格式正确、SSH 免密通路可用。缺一不可,且顺序不能颠倒——先有免密,再测清单;否则 ansible all -m ping 会卡在 SSH 认证或 host key 检查上。
怎么写 inventory 文件才不会被解析失败
Inventory 是纯文本 INI 格式,不支持 JSON 或 YAML(除非用动态脚本)。常见错误是把变量写成 ansible_ssh_user=root 却漏掉等号前的空格,或在组名后加了冒号但没换行。
-
[webservers]这样的组名必须独占一行,后面不能跟注释或值 - 主机行支持 IP、域名、别名,但若用域名,控制节点必须能
nslookup或查/etc/hosts - 端口写法必须是
192.168.1.100:2222(冒号紧贴),不是ansible_port=2222——后者只在变量区生效 - 批量 IP 范围如
192.168.1.[10:20]只支持数字区间,不支持字母(db-[a:f].example.org是合法的,但需确保 DNS 可解析) - 变量定义要分两块:单台主机变量写在主机行末尾,组级变量必须另起
[groupname:vars]段
免密登录失败的典型报错和解法
最常遇到的是 "msg":"Using a SSH password instead of a key is not possible because Host Key checking is enabled..."。这不是密码错了,而是 SSH 第一次连接时拒绝自动接受 host key —— Ansible 默认不开这个口子。
- 不要临时关
host_key_checking(虽然ansible.cfg里设host_key_checking = False能绕过,但生产环境禁止) - 正确做法是提前用
ssh-keyscan把目标主机的公钥指纹写入控制节点的~/.ssh/known_hosts - 如果目标主机改过 SSH 配置(比如重装系统后 host key 变了),
known_hosts里旧记录会导致连接拒绝,得手动删对应行或运行ssh-keygen -R 192.168.1.100 - 用普通用户(如
yun)而非root免密时,确保该用户家目录下~/.ssh/authorized_keys权限是600,且~/.ssh是700,否则 sshd 会静默拒收密钥
inventory 中指定用户和端口的三种写法区别
同一台主机,不同写法影响作用域和可维护性:
- 写在主机行末尾:
192.168.1.100 ansible_user=yun ansible_port=2222—— 仅对该主机生效 - 写在组变量段:
[webservers:vars]下写ansible_user=yun—— 整个组统一用户,但端口仍需单台指定(ansible_port不支持组级继承) - 用别名+独立变量:
web1 ansible_host=192.168.1.100 ansible_user=yun ansible_port=2222—— 适合需要给同一 IP 绑定多个逻辑角色的场景(比如 web1 和 db1 指向同一台机器的不同服务端口)
注意:ansible_ssh_user 是旧写法,Ansible 2.0+ 推荐用 ansible_user;混用会导致后者覆盖前者,但不会报错,容易埋坑。
验证 inventory 和免密是否真通的最小命令
别一上来就跑 playbook。用最轻量的组合快速定位问题:
- 测试单台主机连通性:
ansible node1 -m ping -i ./hosts(node1必须在 inventory 里定义过) - 列出所有被识别的主机:
ansible all --list-hosts -i ./hosts,输出为空说明 inventory 语法错误或路径错 - 跳过模块,直连 SSH:
ssh -o ConnectTimeout=5 yun@192.168.1.100 -p 2222 -i ~/.ssh/id_rsa—— 这步通了,ansible才可能通;不通就别调 inventory - 如果用了非默认私钥路径,inventory 里必须显式指定:
ansible_ssh_private_key_file=/path/to/key
真正麻烦的往往不是语法,而是 SSH 层的细节:目标主机的 /etc/ssh/sshd_config 是否开了 PubkeyAuthentication yes,是否禁了密码登录却忘了配密钥,或者 SELinux 拦截了 ~/.ssh 目录访问 —— 这些都得一层层排除。

















