精读笔记(RHCA 英文教材)· DO447 Chapter 2 Managing Inventories
精读笔记(RHCA 英文教材)· DO447 Chapter 2 Managing Inventories
教材原文:RHCA 官方英文教材(教材第 37~66 页)(OCR 整书版已从本站移除,本页为章节精读) 关联知识:
02-08-Ansible自动化(RH294DO447)、05-认证考试要点;本系列配套00-RHCA教材精读-导航与学习法.md
Chapter Goal / Objectives(原文+译)
- GOAL: Manage inventories using advanced features of Ansible.(用 Ansible 高级特性管理清单)
- OBJECTIVES: ① 用 YAML 格式写静态清单,替代旧 INI 风格;② 用“每主机/每组的多个文件”组织主机与组变量,并用特殊变量覆盖特定主机的连接主机名/端口/远程用户。
- 结构:2.1 Writing YAML Inventory Files(含 Guided Exercise)+ 2.2 Managing Inventory Variables(含 Guided Exercise)+ Lab
Managing Inventories。
2.1 Writing YAML Inventory Files(YAML 格式静态清单)
Inventory Plugins(清单插件)
- Ansible 2.4 起,清单的不同格式由插件实现;传统 INI 静态清单与动态清单脚本各自对应一个插件。
- 默认启用顺序在
ansible.cfg的[inventory]段配置:enable_plugins = host_list, script, auto, yaml, ini, toml(不写则用该默认);解析清单源时按列表顺序逐个尝试。 - 内置插件优势:随 Ansible 核心一起维护;自带云插件(openstack、aws_ec2 等)可替代手写动态脚本;自定义动态脚本只要“可执行文件”即可,可用任意语言,插件系统继续支持。
YAML 静态清单语法
- 用
yaml插件可写 YAML 版静态清单(默认启用):易读、易解析、与 playbook/变量文件统一 YAML。 - INI 与 YAML 对照: | INI | YAML | | --- | --- | |
[lb_servers]+ 每行主机 |lb_servers:组名 +hosts:子块 + 每主机一行末尾冒号 | | 组名下主机 |servera.lab.example.com:| | 数字/字母范围 |server[b:f].lab.example.com:(b~f 共 5 台) | |[web_servers:children]| 组内放children:块 + 子组名末冒号 | - 结构示例:
web_servers: hosts: serverb.lab.example.com: serverc.lab.example.com: children: active_web_servers: active_web_servers: hosts: server[b:c].lab.example.com: all_servers: hosts: servera.lab.example.com: children: web_servers: - 格式要点:组名不加方括号但要冒号结尾;组名下缩进 2 空格写
hosts:(或children:组合子组);主机名再缩进 2 空格、冒号结尾;缩进空格数不强制,但必须一致且层级递增。
YAML 细节(与变量文件通用)
- 列表用
-;Map 用key: value;多个文档---;不要用 Tab。 - 冒号陷阱:
key: value: more会被当成新字典 → 值中含冒号要加引号,如simple: 'Quoting the value with the : character solves the problem';冒号后无空格则无特殊含义(Not:a:problem合法)。 - 以
{开头要引号:Ansible 用{{ }}替换,但 YAML 认为{是字典开始 → 写成foo: "{{ variable }} rest of the value";其它保留字符[] {} > | * & ! % #@ ,` 一般也用双引号包裹。 - 字符串 vs 布尔/浮点:布尔与浮点不加引号(
active: yes、temperature: 36.5);加引号则是字符串(default_answer: "yes"、version: "2.0")。
Guided Exercise 要点(lab: inventory-yaml)
lab inventory-yaml start → 目录 /home/student/DO447/labs/inventory-yaml → cp inventory inventory.yml → 把组/主机/children 转 YAML(active_web_servers、inactive_web_servers、region_eu、web_servers、all_servers)→ ansible -i inventory.yml all_servers -m ping 全部 SUCCESS → lab inventory-yaml finish。
2.2 Managing Inventory Variables(清单变量管理)
变量基本设计原则
- 变量可在多处定义:角色 defaults/vars、清单主机/组变量、playbook 或清单旁的
group_vars/host_vars、play/role/task 内。项目设计三原则:- Keep It Simple:只用少数几种定义方式、放在少数几个位置;
- Don't Repeat Yourself(DRY):一批系统有共同配置就建组,把变量放
group_vars,改一处生效; - Organize in Small, Readable Files:大项目把变量拆成按主题命名的小文件;
group_vars/组名/与host_vars/主机名/还支持子目录(如group_vars/web_servers/firewall.yml只放防火墙变量)。
变量优先级(重点,从低到高)
- 命令行选项(除 -e 外,如
-u可被更高优先级的ansible_user覆盖); - 角色 defaults(
roles/名/defaults/,最低便于被覆盖,用于给角色默认值); - 主机/组变量(自低到高):清单文件/动态脚本中的组变量 → inventory 的
group_vars/all→ playbook 的group_vars/all→ inventory 的其它group_vars→ playbook 的其它group_vars→ 清单文件/脚本中的主机变量 → inventory 的host_vars→ playbook 的host_vars→ 主机 facts/缓存 facts;
- ⚠️ 易混点:
group_vars/host_vars既可相对 inventory 目录也可相对 playbook 目录;playbook 目录下的值覆盖 inventory 目录下的同名值。用途:inventory 侧的group_vars放跨 playbook 共享的默认值,playbook 侧再按项目覆盖。 - 建议不要把变量直接写在 inventory 文件里(大清单难维护、易错)。
- Play 变量(自低到高):play 的
vars→vars_prompt→vars_files/include_vars(注意 include_vars 优先级高,会覆盖角色/块/任务变量;不想覆盖就用 vars_files)→ block/task 内vars; set_fact与register:把主机级结果设成高优先级,持续到本 playbook 结束;缓存后以普通 fact 优先级存储;- Extra Variables(-e)永远最高:便于不改项目文件临时覆盖。
变量与清单分离(目录组织)
- 别把变量堆进 inventory 文件;按组拆文件:
group_vars/db_servers.yml、lb_servers.yml、web_servers.yml(组少变量少时够用)。 - 大而多样环境:每组建子目录(
group_vars/lb_servers/下多文件),Ansible 解析子目录内所有 YAML,按父目录名关联组;文件按主题命名(如 mysql.yml、firewall.yml、haproxy.yml、ssl.yml);用角色时常按角色名命名变量文件;group_vars/all/common.yml放全组公共变量。
特殊连接变量(special inventory variables)
| 变量 | 作用 |
|---|---|
ansible_connection | 连接插件;默认 ssh,localhost 用 local |
ansible_host | 真正连接的 IP/FQDN,替代清单里的 inventory_hostname |
ansible_port | 连接端口(SSH 默认 22) |
ansible_user | 连接用户名(默认与控制节点当前用户同名) |
ansible_become_user | 连接后切换的用户(配合 ansible_become_method,默认 sudo) |
ansible_python_interpreter | 被管端 Python 路径;2.8+ 默认 auto 自动探测,跨发行版基本不用手设 |
可读性强的清单主机名
- 输出(PLAY RECAP)显示的是 inventory 主机名 → 用“有意义别名 + ansible_host”替代裸主机名,一眼看出哪台失败及角色:如
loadbalancer:+ansible_host: server103.example.com、webserver_1/2/3:+ 各自ansible_host。 - 适用场景:DNS 解析的地址不适合直连(内网管理地址)、云主机名字随机、清单用短名但连接需 FQDN。
- 标识当前主机的变量:
inventory_hostname(清单中的名字)、ansible_host(实际连接地址)、ansible_facts['hostname'](被管端短主机名 fact)、ansible_facts['fqdn'](FQDN fact)、ansible_play_hosts(本 play 尚未失败、将继续执行的主机列表)。
Guided Exercise 要点(lab: inventory-variables)
lab inventory-variables start → git clone http://git.lab.example.com:8081/git/inventory-variables.git → 建 group_vars/lb_servers、group_vars/web_servers 子目录 → 把 deploy_haproxy.yml/site.yml 里的防火墙、haproxy 等变量从 play 移到对应组目录的变量文件 → 用 ansible_host 给 lb/web 主机配可读别名(loadbalancer_N、a_web_servers→backend_aN、b_web_servers→backend_bN)→ ansible-playbook site.yml 验证输出用新别名 → commit + push → lab inventory-variables finish。
Lab 要点(Managing Inventories / inventory-review)
- 目标:INI→YAML 转格式、为新组配组变量目录、给远程主机配任意可读别名(A/B 两组各部署独立版本 webapp,可做 A/B 测试)。
- 流程:
lab inventory-review start→ clone inventory-review.git → 审阅 inventory(lb_servers 含 servera;web_servers:children = a_web_servers(serverb) + b_web_servers(serverc))→ 执行 site.yml、多次访问 servera 验证 A/B 版本一致 → 完成 YAML 清单与变量重组、提交推送 →lab inventory-review grade评分 →lab inventory-review finish。
命令速查表
| 场景 | 命令/写法 |
|---|---|
| 指定清单跑 | ansible -i inventory.yml all_servers -m ping、ansible-playbook -i inventory.yml site.yml |
| 插件开关 | ansible.cfg 的 [inventory] enable_plugins = host_list, script, auto, yaml, ini, toml |
| 组变量文件 | group_vars/组名.yml 或目录 group_vars/组名/*.yml |
| 主机变量文件 | host_vars/主机名.yml 或目录 |
| 连接别名 | 组/主机下:ansible_host: server100.example.com、ansible_port、ansible_user |
| 最高优先级覆盖 | ansible-playbook site.yml -e "变量=值" |
| 引用当前主机 | inventory_hostname、ansible_facts['fqdn']、ansible_play_hosts |
核心词汇表
| 英文 | 中文速记 |
|---|---|
| inventory plugin | 清单插件(yaml/ini/script/toml…) |
| static inventory | 静态清单(INI 或 YAML 文件) |
| dynamic inventory script | 动态清单脚本(可执行文件) |
| alphabetical range | 字母范围 server[b:f] |
| precedence | 优先级(-e 最高,role defaults 最低) |
| group_vars / host_vars | 组变量 / 主机变量目录(inventory 侧与 playbook 侧) |
| include_vars vs vars_files | 高优先级外部变量加载 vs 普通外部变量文件 |
| set_fact / register | 主机级高优先级设值 / 注册任务结果 |
| extra variables (-e) | 命令行额外变量(最高优先级) |
| special inventory variables | 特殊连接变量(ansible_host/port/user/…) |
| inventory_hostname | 清单中的主机名(输出用它) |
| human-readable host names | 可读主机别名(配 ansible_host) |
| A/B testing | A/B 测试部署(本 Lab 两组 webapp) |
本章自测
- INI 与 YAML 清单如何表达:组、主机、children、范围主机?
- enable_plugins 的默认顺序是什么?为什么用内置插件优于自定义动态脚本?
- 变量优先级从低到高列举 6 大类?-e 与 role defaults 各在哪端?
- group_vars 相对 inventory 目录与相对 playbook 目录冲突时谁赢?
- 为什么不要把变量直接写进 inventory 文件?大项目变量文件怎么组织?
- ansible_host/ansible_port/ansible_user/ansible_connection 各自作用?什么叫可读主机别名?
- inventory_hostname、ansible_host、ansible_facts['fqdn'] 三者区别?
- YAML 里冒号、{、布尔值什么时候必须加引号?
