LabHub
学习 学习路径 课程

Ansible 基础

清单 — 自动化的通讯录

在 LabHub 中继续学习

一句话总结

Ansible 在问“做什么”之前,先问“对谁做”。答案就是 inventory。

概念图: 人开始记忆“在哪个节点做过什么” · group 可以形成层级 · 范围越窄优先级越高 · 怀疑 inventory 时,不要盯着文件看,而要用这条命令查看真实解析结果。

为什么需要它

三台服务器时,可以打开三个终端;七台时,就会发生选错窗口的事故。从 home lab 由 3 节点扩到 7 节点的记录可以看到,添加节点本身并不困难,错误从**人开始记忆“在哪个节点做过什么”**的瞬间出现。新加入的两个节点还残留旧集群内容(旧版 kubelet、旧证书),手工逐台清理时总会漏掉一台。

inventory 把问题反转为“把清单写进文件”。文件中没有的服务器不属于自动化对象,文件中列出的服务器全部接受相同处理。这条简单规则从结构上消除了“只有一台配置不同”的情况。

如何工作

inventory 包含三种内容。

元素 是什么 示例
host 一个连接目标 web1
group host 集合 [web][db]
variable 绑定到 host/group 的值 ansible_port=2222app_port=8080

关键是group 可以形成层级。在 [prod:children] 下放入 webdbprod 就包含两个 group 的所有 host;每个 host 还会自动属于 all group。变量从上向下传递,但范围越窄优先级越高——group 值覆盖 all,host 值再覆盖 group。

格式有 INI 与 YAML 两种。INI 简短,适合手写;YAML 适合嵌套结构与复杂变量。无论使用哪种,通过 ansible-inventory --list 输出后最终都是同一 JSON。怀疑 inventory 时,不要盯着文件看,而要用这条命令查看真实解析结果。 一个拼写错误让整个 group 变空,三秒内就能发现。

在实际项目中

第一,“为什么只有一台没执行”。 有人缩小目标时不用 --limit,而是暂时从 inventory 删除 host。结果该文件被直接提交,几天后只有这台服务器漏掉补丁。缩小目标应使用执行参数,而不是修改 inventory。

第二,连接信息也是变量。 ansible_hostansible_portansible_user 看似特殊,其实仍是普通变量。因此,可以在 inventory 中吸收跳板机、非标准端口等环境差异,无需修改代码。本实验的 sshd 运行在 127.0.0.1:2222,也通过 ansible_port 表达差异。

第三,动态 inventory。 云环境中的服务器清单每天变化,因此会由脚本生成,而不是写死在文件中。但概念相同——脚本只是在生成包含 group 与 variable 的 JSON。理解静态 inventory 后,动态 inventory 只是输出形式不同的同一种东西。

变量应该放在哪里

把大量变量写进 inventory 文件很快会难以阅读,所以实务中会把变量移到独立目录。在 inventory 旁放置 group_vars/host_vars/ 后,group_vars/web.yml 应用于整个 web group,host_vars/web1.yml 只应用于该 host。文件名就是作用范围,不必猜该改哪里。

优先级仍遵循范围越窄越强。完整规则很长,常见部分如下。

  1. 命令行 -e(最强)
  2. 直接写在 task 或 block 中的值
  3. host_vars/
  4. group_vars/(子 group 覆盖父 group)
  5. group_vars/all
  6. role 默认值(defaults/,最弱)

role 默认值最弱是刻意设计。role 只负责表达“没有提供这个值时,我使用这个默认值”,调用方应始终可以覆盖。 相反,role 内部 vars/ 优先级高、难以覆盖,只应用于确实不能变化的值。

再补充一条实务规则:不要在 inventory 中明文保存秘密。 一旦提交进存储库就无法真正撤回,删除后仍留在历史中。可以使用加密变量文件或外部秘密存储,但无论选择哪种,都应把秘密值与普通值拆分到不同文件。混在一起后,每改一个普通设置都要解密,久而久之大家会放弃加密。

下一实验要做什么

/root/ans/inventory/hosts.ini 中创建 web、db group 及上层 prod group,再用 YAML 表示相同结构。随后用 ad-hoc 命令一次连接三个 host,并通过 --limit 缩小目标。最后把 inventory 输出为 JSON,生成按 group 分类的 host 报告。