Inventory 与变量
本章目标:用 分组 管理主机,用 group_vars / host_vars 分层存放配置,并学会在排障时查清「当前主机最终用的是哪个变量值」。
变量混乱是 Ansible 项目失控的第一大原因。模块会用错可以改,变量优先级一旦没人说得清,线上就会「同一份 playbook、两台主机行为不同却查不出为何」。
1. Inventory 的职责
Inventory 回答三件事:
- 有哪些主机(逻辑名)
- 怎么连上去(IP、端口、用户、解释器)
- 如何分组(按角色、环境、地域)
业务配置(端口、包列表、功能开关)尽量不要全塞在 inventory 的 xxx=yyy 里,而是放到 group_vars / host_vars,inventory 保持「拓扑 + 连接」。
2. 静态 Inventory 进阶
inventory/hosts.ini:
# ===== 按角色 =====
[web]
web1 ansible_host=10.0.1.11
web2 ansible_host=10.0.1.12
[db]
db1 ansible_host=10.0.1.21
# ===== 按环境(children 组合)=====
[staging:children]
web
db
[prod]
# 生产可另写 inventory/prod.ini,这里示意
; prod-web1 ansible_host=10.1.1.11
# ===== 全站连接默认值 =====
[all:vars]
ansible_user=ops
ansible_ssh_common_args='-o StrictHostKeyChecking=accept-new'
要点:
| 写法 | 含义 |
|---|---|
web1 | inventory_hostname,playbook/模板里常用 |
ansible_host | SSH 真正连接的地址 |
[group:children] | 组的组,-l staging 一次选中多角色 |
[all:vars] | 全局连接参数 |
查看解析结果:
ansible-inventory --list
ansible-inventory --graph
ansible-inventory --host web1
--graph 适合确认 children 有没有拼错。
3. YAML Inventory(可选)
团队更爱可读性时可改用:
all:
vars:
ansible_user: ops
children:
web:
hosts:
web1:
ansible_host: 10.0.1.11
web2:
ansible_host: 10.0.1.12
db:
hosts:
db1:
ansible_host: 10.0.1.21
staging:
children:
web:
db:
与 ini 可并存于不同文件;用 -i 指定即可。本系列正文继续用 ini。
4. group_vars / host_vars 分层
目录约定:
group_vars/
all.yml # 所有主机
web.yml # web 组
db.yml
staging.yml # 若 inventory 有 staging 组
host_vars/
web1.yml # 单机覆盖
group_vars/all.yml:
---
org_name: rootwiki
timezone: Asia/Shanghai
ntp_servers:
- 10.0.0.10
- 10.0.0.11
# 全局安全基线开关
ssh_password_authentication: false
group_vars/web.yml:
---
http_port: 80
nginx_worker_processes: 2
nginx_packages:
- nginx
app_root: /var/www/html
host_vars/web1.yml:
---
# 仅灰度机改端口
http_port: 8080
nginx_worker_processes: 4
Playbook 里直接用:
- name: 打印有效配置
ansible.builtin.debug:
msg: >-
host={{ inventory_hostname }}
port={{ http_port }}
workers={{ nginx_worker_processes }}
tz={{ timezone }}
ansible-playbook playbooks/debug_vars.yml -l web
预期:web1 的 port=8080,web2 的 port=80。
目录式 group_vars(多文件)
当一组变量很多时:
group_vars/web/
vars.yml
vault.yml # 下一章 Vault 会用到
nginx.yml
Ansible 会合并目录内文件;敏感与非敏感拆开是好习惯。
5. 变量优先级(实用版)
官方完整表很长。生产排障记住这条链(后者覆盖前者):
- Role
defaults/main.yml - Inventory 组变量 /
group_vars - Inventory 主机变量 /
host_vars - Play 的
vars/vars_files - Task 的
vars include_vars、注册变量等(视场景)- 额外变量
-e/--extra-vars(最高)
-e http_port=9090 适合紧急热修或 CI 注入一次。长期有效值应落入 group_vars/host_vars/Role defaults,否则「文档、仓库、线上」三套真相。
查清某主机最终变量
# 清单侧看到的变量
ansible-inventory --host web1
# 合并 facts + 变量后的视图(较大)
ansible web1 -m debug -a 'var=hostvars[inventory_hostname]'
# 只看某一个键
ansible web1 -m debug -a 'var=http_port'
6. 魔法变量(务必认识)
| 变量 | 含义 |
|---|---|
inventory_hostname | 清单中的名字(如 web1) |
ansible_host | 连接地址 |
group_names | 当前主机所属组列表 |
groups['web'] | web 组全部主机名列表 |
hostvars['web2'].http_port | 读其它主机变量(编排时有用) |
示例:生成 upstream 列表:
- name: 组装后端列表
ansible.builtin.set_fact:
backend_servers: "{{ groups['web'] | map('extract', hostvars, 'ansible_host') | list }}"
7. 多环境:两套常见做法
做法 A:多 inventory 文件(推荐起步)
inventory/staging.ini
inventory/prod.ini
ansible-playbook -i inventory/staging.ini playbooks/site.yml
ansible-playbook -i inventory/prod.ini playbooks/site.yml --check
环境差异放在各自 group_vars,或:
inventory/staging/
hosts.ini
group_vars/...
inventory/prod/
hosts.ini
group_vars/...
(把 -i 指到目录时,Ansible 会读取目录中的清单与 vars。)
做法 B:同一清单,用组区分环境
[web_staging]
...
[web_prod]
...
简单,但生产/测试变量容易看串。主机规模上来后更推荐做法 A。
8. 动态 Inventory(概念与边界)
云主机频繁增减时,可使用:
- 云厂商官方 dynamic inventory 插件
- 自研脚本:stdout 打印 Ansible 认可的 JSON
本系列以静态清单把基础打牢。上动态清单前先保证:分组命名稳定、变量分层清晰;否则动态只是把混乱自动化了。
9. 反模式对照
| 反模式 | 后果 | 建议 |
|---|---|---|
| playbook 里写死 IP | 无法复用 | IP 只出现在 inventory |
| 密码写在 inventory 明文 | 泄露 | Vault / 私钥登录 |
全部变量塞 all.yml | 冲突难查 | 按组拆分 + 前缀 |
| 同名变量到处覆盖 | 行为不可解释 | 统一前缀,少用 -e |
| 用 hostname 当唯一标识却常变 | 历史状态错乱 | 逻辑名稳定,ansible_host 可变 |
10. 练习与验收
练习 A:覆盖关系
group_vars/web.yml设http_port: 80host_vars/web1.yml设http_port: 8080- debug 两台主机,确认只有 web1 为 8080
练习 B:children
- 建
[staging:children]包含web与db ansible staging -m ping应覆盖两类主机
练习 C:排障
- 用
-e http_port=9999跑 debug,确认它压过 host_vars - 去掉
-e,确认回到文件中的值
验收清单
- 能画出本项目的组关系(
--graph) - 业务变量在 group_vars/host_vars,不在命令行里长期存在
- 会用
debug: var=...证明覆盖关系
下一章:运维高频模块 —— 先把真正干活的模块逐个跑通,再进入 Playbook 编排。