跳到主要内容

Inventory 与变量

本章目标:用 分组 管理主机,用 group_vars / host_vars 分层存放配置,并学会在排障时查清「当前主机最终用的是哪个变量值」。

变量混乱是 Ansible 项目失控的第一大原因。模块会用错可以改,变量优先级一旦没人说得清,线上就会「同一份 playbook、两台主机行为不同却查不出为何」。


1. Inventory 的职责

Inventory 回答三件事:

  1. 有哪些主机(逻辑名)
  2. 怎么连上去(IP、端口、用户、解释器)
  3. 如何分组(按角色、环境、地域)

业务配置(端口、包列表、功能开关)尽量不要全塞在 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'

要点:

写法含义
web1inventory_hostname,playbook/模板里常用
ansible_hostSSH 真正连接的地址
[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. 变量优先级(实用版)

官方完整表很长。生产排障记住这条链(后者覆盖前者):

  1. Role defaults/main.yml
  2. Inventory 组变量 / group_vars
  3. Inventory 主机变量 / host_vars
  4. Play 的 vars / vars_files
  5. Task 的 vars
  6. include_vars、注册变量等(视场景)
  7. 额外变量 -e / --extra-vars(最高)
少用 -e 当长期配置

-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:覆盖关系

  1. group_vars/web.ymlhttp_port: 80
  2. host_vars/web1.ymlhttp_port: 8080
  3. debug 两台主机,确认只有 web1 为 8080

练习 B:children

  1. [staging:children] 包含 webdb
  2. ansible staging -m ping 应覆盖两类主机

练习 C:排障

  1. -e http_port=9999 跑 debug,确认它压过 host_vars
  2. 去掉 -e,确认回到文件中的值

验收清单

  • 能画出本项目的组关系(--graph
  • 业务变量在 group_vars/host_vars,不在命令行里长期存在
  • 会用 debug: var=... 证明覆盖关系

下一章:运维高频模块 —— 先把真正干活的模块逐个跑通,再进入 Playbook 编排。