Ansible
请结合作者xike__的专栏Ansible食用# 一、ansible 的配置文件
1. Ansible 配置文件的作用是什么?
简单来说,配置文件的作用是 “定义规则” 和 “简化命令”。
Ansible 在执行时需要知道很多信息,比如:
-
去哪里找主机清单(Inventory)?
-
用哪个用户身份去登录远程机器?
-
是否需要询问密码?
-
报错时要不要显示更详细的信息?
如果没有配置文件,你每次运行命令可能都要带上一长串参数(比如 ansible-playbook -i ./inventory -u root ...)。有了配置文件,Ansible 会自动读取预设的参数,让你只需输入 ansible-playbook site.yml 即可。
2. ansible配置文件的匹配机制?
Ansible 的配置文件查找遵循一个 “就近原则” (Priority Hierarchy)。当你运行 Ansible 命令时,它会按照以下顺序寻找配置文件,一旦找到第一个,就不再往下找了:
-
环境变量:
ANSIBLE_CONFIG(指向某个具体文件)。 -
当前目录:当前执行命令的目录下是否有
ansible.cfg。 -
用户家目录:
~/.ansible.cfg。 -
默认系统路径:
/etc/ansible/ansible.cfg。
3. 示例代码?
[defaults]
inventory = ./inventory
这是配置文件中最基础、最常用的两行代码:
-
[defaults]:这是一个“节”(Section)的标题。它告诉Ansible,下面的设置是全局默认参数。 -
inventory = ./inventory:-
含义:指定主机清单文件的路径。
-
作用:它告诉
Ansible:“默认情况下,去当前目录(./)下找一个叫inventory的文件作为我的服务器名单。”,这意味着命令执行的路径中必须有一个叫做inventory的主机清单文件。 -
好处:设置了这一行后,你执行命令时就不需要再加
-i ./inventory参数了。Ansible会变聪明,自动去关联那个名单。
-
进阶提示:如何查看当
前生效的配置?
小三,如果你不确定当前 Ansible 到底在用哪个配置文件,或者哪个配置生效了,你可以在每次运行命令后,再运行这个命令:
Bash
ansible --version
在输出的内容中,有一行会明确显示 config file = /xxx/xxx/ansible.cfg。这能帮你快速判断你写的配置是否真的被 Ansible 认领了。
除了指定清单路径,你还想了解如何在这个配置文件里实现“免密登录”或者“自动切换 sudo 用户”的配置吗?
二、inventory 主机文件
1、Inventory 是干嘛的?
Inventory(主机清单)本质就是:
📒 告诉
Ansible:
“我有哪些机器?它们分成哪些组?用什么方式连接?”
它是 Ansible 的基础数据源。
没有 Inventory,Ansible 就不知道要去哪里执行任务。
默认位置:/etc/ansible/hosts(全局),但推荐在项目目录下自定义。
2、Inventory 的核心结构
1️⃣ 主机(Host)
最基本单位:
192.168.1.10
web01.example.com
每一行就是一个受控主机。
2️⃣ 组(Group)
用来对主机分类:
[web]
192.168.1.10
192.168.1.11
[db]
192.168.1.20
组的作用:
-
在 playbook 里用
hosts: web -
给某一类机器统一定义变量
-
逻辑分层管理
3️⃣父子嵌套组
组内嵌套组
[server]
192.168.122.18
[db]
192.168.122.101
[web:children]
server
db
组中包含其他组,让主机文件的书写更加的灵活。解决我们对不同运维场景的需求。
4️⃣ all 组(默认顶层组)
重点来了 👇
-
all是自动存在的顶层组 -
包含 inventory 里的所有主机
-
不需要手动创建
-
常用于:
hosts: all
或:
[all:vars]
ansible_user=root
它是整个 Inventory 的根。
5 ungrouped 组(自动生成)
结构逻辑是:
all
├── web
├── db
└── ungrouped
ungrouped 里放:
👉 没有属于任何自定义组的主机。
3、Inventory 的两种常见格式
1️⃣ INI 格式(最常用)
[web]
192.168.1.10
192.168.1.11
[db]
192.168.1.20
[all:vars]
ansible_user=root
优点:
-
简单
-
直观
-
小项目很方便
2️⃣ YAML 格式(结构更清晰)
all:
children:
web:
hosts:
192.168.1.10:
192.168.1.11:
db:
hosts:
192.168.1.20:
YAML 更清楚地表达了层级关系:
all
└── children
├── web
└── db
适合大型项目。
4、Inventory 的变量系统
Inventory 不只是列主机,它还能定义变量。
1️⃣ 主机变量
192.168.1.10 ansible_user=admin ansible_port=2222
只对这一台机器生效。
2️⃣ 组变量
[web:vars]
ansible_user=nginx
对 web 组所有主机生效。
3️⃣ 全局变量(all)
[all:vars]
ansible_user=root
对所有主机生效。
4️⃣ 常用关键变量
在 Inventory 中,你不仅可以写名字,还可以直接塞入连接参数:
-
ansible_host: 实际连接的 IP 地址(如果用了别名)。 -
ansible_user: 登录的用户名(如root或admin)。 -
ansible_port: SSH 端口(非 22 端口时必填)。 -
[group:vars]: 为整个组统一定义变量。
⚠ 变量优先级
优先级从低到高:
all 组变量
↓
父组变量
↓
子组变量
↓
主机变量
越具体,优先级越高。
5、Inventory 的逻辑树(完整认知)
真正的内部结构其实是:
all
├── children
│ ├── web
│ ├── db
│ └── 其他组
└── ungrouped
理解这个结构之后:
-
hosts: all→ 全部机器 -
hosts: web→ web 组机器 -
未分组主机 → 自动进 ungrouped
6、Inventory 本质总结(面试版)
如果要一句话讲清楚:
Inventory 是 Ansible 的主机和分组数据库,
用于定义受控节点、分组结构以及变量继承关系。
所有主机属于默认的all组,未分组主机属于ungrouped。
7、常用验证命令
🛠️ 常用验证命令
写完 Inventory 后,养成先验证再执行的习惯:
-
列出所有主机:
ansible all --list-hosts -
查看某个组的主机:
ansible web --list-hosts -
连通性测试:
ansible all -m ping -
查看主机清单文件:
ansible-inventory --list
8、常见认知误区
-
❌ 以为必须手写
[all]
→ 不需要,它自动存在 -
❌ 以为 Inventory 只是主机列表
→ 它其实是层级化的数据模型 -
❌ 变量优先级搞混
→ 记住:越具体优先级越高
三、ansible中模块及其使用方法
ansible中的模块
如果说 Inventory 是你的“通讯录”,那么 Modules(模块) 就是 Ansible 的“工具箱”。Ansible 本身其实不具备配置系统的功能,它只是一个调用器。真正的活儿(比如装软件、改文件、启服务)都是由一个个具体的模块去完成的。
1. 模块的核心逻辑:幂等性 (Idempotency)
这是学习模块时必须理解的第一个金句:“不管执行多少次,结果都是一样的。”
-
普通脚本:你写一个
mkdir /data,第二次运行会报错“文件夹已存在”。 -
Ansible 模块:你调用
file模块创建目录,如果目录已存在,它会直接返回ok,什么都不做;如果不存在,它才会创建。这保证了系统的状态始终符合你的预期。
2. 模块的调用结构
在 Playbook(剧本)中,一个模块的调用通常长这样:
YAML
- 模块名:
参数1: 值
参数2: 值
3. 如何“自学”模块?(必杀技)
小三,Ansible 有数千个模块,没人能全记住。在 RHEL 终端里,有两个命令是你必须掌握的“活字典”:
-
ansible-doc -l:列出所有已安装的模块(多得让你头晕)。 -
ansible-doc <模块名>:这是最重要的。- 比如
ansible-doc dnf,它会告诉你这个模块有哪些参数,最下面还有 EXAMPLES(例子),直接复制粘贴就能用!
- 比如
4. 模块的返回状态
当你运行一个模块后,Ansible 会给你三种颜色的反馈:
| 颜色 | 状态 | 含义 |
|---|---|---|
| 绿色 | SUCCESS / OK |
任务成功,但系统状态没有变化(已经是你想要的样子了)。 |
| 黄色 | CHANGED |
任务成功,且修改了系统状态(比如新装了软件)。 |
| 红色 | FAILED |
任务失败,会给出具体的错误原因。 |
💡 总结
模块就是 Ansible 里的“动作”。 你想对服务器做什么,就找对应的模块。
怎么解读ansible-doc [模块]输出的信息
我们以dnf模块为例子
结合你提供的这份文档,我教你如何快速抓取 ansible-doc 的重点:
第一步:看“自我介绍” (Synopsis)
文档开头就会告诉你它是干什么的:
作用:使用
dnf包管理器安装、升级、删除和列出软件包及组 。 平台限制:专门针对 RHEL 等使用dnf的系统 。+1
第二步:识别“必填项” (Mandatory Options)
在文档中,参数前面带 = 号的,或者描述里写了 required 的就是必填项。
-
name:这是唯一的必填参数 。-
强大之处:它不仅支持包名(如
httpd),还支持版本号对比(如httpd >= 2.4)、URL 远程包、本地 RPM 路径,甚至是某个命令的绝对路径(如/usr/bin/cowsay) 。+3
-
第三步:理解“状态机” (State)
Ansible 是描述性的,所以 state 参数决定了你的最终目标 :
+1
-
present/installed:确保包在系统里,不在就装一个 。+1
-
latest:不但要装上,还得是最新版 。+1
-
absent/removed:确保系统里没有这个包,有就删掉 。+1
第四步:寻找“进阶开关” (Advanced Options)
当你有一些特殊需求时,去 OPTIONS 列表里搜关键字:
-
想更新缓存? 找
update_cache。 -
想清理没用的依赖? 找
autoremove。 -
想跳过 GPG 检查(比如装个非官方包)? 找
disable_gpg_check。 -
担心锁竞争?
lock_timeout可以帮你设置等待 dnf 锁的时间,默认是 30 秒 。
第五步:【核心】直接看 EXAMPLES (实战模版)
小鑫,其实高手最常用的就是直接翻到最后的 EXAMPLES,那里的场景非常全:
-
批量安装:不要用循环(loop),直接给
name传一个列表,效率更高 。+1
YAML
name: - httpd - mariadb-server -
安装组:名字前面加个
@符号(例如@Development tools) 。 -
只更新不安装:设置
update_only: yes,这样如果包没装,Ansible 就不会自作聪明帮你装上 。+1
⚠️ 文档里隐藏的“避坑指南” (Notes)
文档中还有一些非常宝贵的提示,是老师可能都没讲到的:
-
幂等性警告:如果你设置了
allow_downgrade=True(允许降级),这个模块可能就不再具备幂等性了,因为它可能会在不同版本间反复横跳 。 -
组删除问题:文档提到
Group removal可能不生效,因为上游 dnf 的 API 有时无法检测到组是否已安装 。
💡 小鑫的总结练习
你看,通过这份 dnf 文档,我们知道:
-
必填:
name。 -
默认行为:如果你不写
state,默认就是present。 -
性能建议:给
name传列表比用loop快得多 。
[[在被控节点创建文件]]
更多推荐
所有评论(0)