版】Linux教程,ansible自动化运维从入门到精通
博客园:https://www.bilibili.com/video/BV1iBG1zMEK2/?spm_id_from=333.337.search-card.all.click&vd_source=98f3349ab95218044e2c42b526a191ca


这张图里的内容非常经典,把传统的手动操作(Shell)和自动化运维工具(Ansible)的区别讲得很透彻。红笔圈出来的部分正好强调了 Ansible 最核心的两个特点:模块化和无代理架构。
我来帮你拆解一下这几个关键点:
1. “基于模块化设计”是什么意思?
图里红圈旁的文字写得很明白:“Ansible 本身仅提供框架,真正的批量操作由模块实现”。
这就好比乐高积木,Ansible 是底板,而那些成千上万的模块就是积木块。你想干什么事(比如装软件、改配置、启服务),不需要自己从头写复杂的代码,直接调用对应的模块拼起来就行。
-
好处:这也就是为什么它说“可解决大部分场景”。因为有现成的模块,你不需要懂底层代码,拿来就能用,极大地降低了自动化的门槛。
2. 右侧红框的“无代理架构”
图里特意圈出了 SSH,这是关键。
-
传统 Shell (左侧手写):可能需要你先登录每一台服务器,敲命令、装环境,费时费力。
-
Ansible (右侧红框):它是通过 SSH 直接连到目标机器上干活,就像图里写的“无需安装额外的客户端”。这意味着被管理的机器不需要装任何特殊的软件,只要能连上 SSH 就能管,非常轻便。
总的来说,这张笔记抓住了 Ansible 的灵魂:用现成的模块(积木),通过 SSH(电话线),指挥一大堆机器干活,而且机器上什么都不用装。 这是一种非常高效且优雅的运维方式。

这张图展示的是 Ansible 的执行流程,它非常直观地描绘了从你输入命令到 Ansible 实际在服务器上干活的完整过程。
我们可以顺着箭头,把这个流程拆解为五个关键步骤来理解:
第一步:用户发出命令(起点)
流程始于“用户”。你作为使用者,会输入 Ansible 的命令。这里图中提到了两种模式:
-
Ad-Hoc 模式:适合临时、快速的单个任务(比如只想查一下某台机器的内存)。
-
Playbook 模式:适合复杂、需要编排的重复性任务(比如一键部署整个网站)。
第二步:进入处理流程,交给 Ansible 主程序
命令发出后,会进入“处理流程”,最终抵达核心的 Ansible 主程序。你可以把主程序想象成 Ansible 的“大脑”,它负责接收你的指令并统筹调度。
第三步:读取主机清单(Inventory)
这是自动化管理的前提。主程序紧接着会去读取 主机清单(图中标注的路径是 /etc/ansible/hosts)。
-
这一步是为了知道“我要管谁”。
-
图中特别展示了清单里定义了不同的组,比如 Web机器组 和 Database机器组。这意味着 Ansible 支持分组管理,你可以针对某一组机器统一下发命令。
第四步和第五步:连接目标主机并调用模块(核心动作)
这是实际干活的部分:
-
Ansible 主程序通过 SSH(无代理架构)连接到目标机器。
-
接着,它会调用模块来执行具体的操作。
-
图中列举了几个最常用的核心模块,比如:
-
file/copy:用来管理文件和目录。 -
yum:用来安装软件包。 -
systemd:用来管理系统服务。 -
cron:用来管理定时任务。
-
这完美呼应了你上一张笔记里提到的“基于模块化设计”——Ansible 本身只是个框架(大脑),真正让服务器发生变化的,就是这些具体的模块(手脚)。
总的来说,这个流程图清晰地展示了 Ansible 的工作逻辑:你在主控端发号施令 -> Ansible 读取清单找到目标 -> 通过 SSH 连接过去 -> 调用相应的模块把活干完。

这张图片紧接着你之前上传的内容,进一步讲解了 Ansible 的执行原理(背后干了什么) 以及 如何安装和验证 Ansible。
我帮你把图片里的核心信息梳理成三个关键点:
1. Ansible 的核心工作原理(Ad-Hoc 模式)
图片上半部分的列表详细描述了当你执行一条临时命令时,Ansible 背后的“动作分解”:
-
加载配置:首先读取全局配置文件
/etc/ansible/ansible.cfg,确定运行参数。 -
读取清单:去
/etc/ansible/hosts找到你要操作的目标机器(IP或域名)。 -
生成脚本(关键步):这是很多人容易忽略的。Ansible 并不是直接把模块扔过去,而是根据模块参数,在本地生成一段临时的 Python 脚本。
-
传输与执行:把这段临时脚本传到目标服务器的
~/.ansible/tmp/目录下,赋予执行权限,运行它,然后把结果返回给你。
💡 理解这一点很重要:这体现了 Ansible 的“无代理”特性。因为目标机器只要有 Python 环境和 SSH,就能运行这段代码,不需要安装任何额外的 Agent 软件。
2. 动手实践:安装与验证
图片下半部分展示了在 Linux(看提示符是 openEuler 或 CentOS 系)下的安装过程:
-
安装命令:使用
yum install -y ansible一键安装。 -
验证命令:使用
ansible --version查看版本信息。
3. 终端输出信息解读
最后那个代码块里的输出信息其实非常有料,它告诉你当前 Ansible 的运行环境状态:
-
版本:你安装的是
ansible 2.9.27(这是一个比较稳定的较老版本,目前最新版已到 9.x,但 2.9 依然是很多企业常用的版本)。 -
配置文件路径:
config file = /etc/ansible/ansible.cfg(说明使用的是默认配置)。 -
Python 环境:
python version = 3.9.9(说明 Ansible 是基于 Python 3.9 运行的,这是比较新的版本,兼容性很好)。


这张图的核心内容是 Ansible 的快速入门命令:Ad-Hoc 模式。
简单来说,Ad-Hoc 就是 Ansible 提供的一个“临时命令行工具”。它不需要你写复杂的脚本文件,直接敲一条命令就能让服务器执行操作,非常适合测试、查问题或者做简单的单次任务。
我帮你把图里的重点拆解一下,方便你理解和实操:
1. 什么是 Ad-Hoc?
图里第一句话解释得很到位:它是用来快速执行简单任务的工具。
-
打个比方:如果说 Playbook(剧本)是写一本操作手册,那 Ad-Hoc 就是随手写的便签条。虽然不能做复杂的事情,但胜在方便快捷,立马就能执行。
2. 核心语法公式
图中间那个灰色底板的代码块就是核心公式,记住这个结构就能上手了:
ansible <目标主机> -m <模块名> -a "<参数>"
-
<host-pattern>(找谁):指定你要操作哪台机器。比如all(所有机器)、webservers(某个组),或者直接写 IP192.168.1.1。 -
-m <module-name>(用什么):指定要执行的动作(模块)。比如shell(执行 shell 命令)、copy(传文件)、yum(装软件)。如果不写-m,默认是用command模块。 -
-a "<module-arguments>"(做什么):传给模块的具体参数。比如你想执行ls -l,这里就写"ls -l"。
3. 最常用的两个选项
图右下角的表格列出了常用选项,其中这两个最常用:
-
-i:用来指定“通讯录”(Inventory 文件)。如果你不想用默认的/etc/ansible/hosts,就得用这个参数指定你自己的文件。 -
-m:指定模块。这是 Ad-Hoc 的灵魂,前面提到的command、shell、copy都是靠它调用的。
💡 举个实战小例子
假设你想看看所有 Web 服务器能不能连通,你可以敲这样一条 Ad-Hoc 命令:
ansible webservers -m ping
或者你想在远程机器上查看当前时间:
ansible all -m shell -a "date"
总的来说,这一页就是你开始玩 Ansible 的第一步,学会了这几个参数,你就可以开始批量操控服务器了。
这张图是上一页内容的延伸,详细列出了 Ansible Ad-Hoc 命令的常用选项(参数)。
这些选项就像是“遥控器”上的各种按钮,用来控制 Ansible 的行为。我帮你把这些选项按照使用频率和功能场景整理了一下,挑出最关键的几个重点说明:
1. 必学核心三件套(最常用)
这三个是你敲命令时最离不开的:
-
-i(Inventory):指定目标机器列表。如果你不想用默认的/etc/ansible/hosts,就必须用它来指定你自己的文件。 -
-m(Module):指定要执行的模块。比如shell、copy、yum。如果不写,默认是command模块。 -
-a(Args):给模块传递参数。比如你想执行ls -l,这里就填"ls -l";想传文件,这里就填"src=/tmp/a dest=/opt/b"。
2. 提权与认证(做运维必用)
Linux 服务器通常需要 root 权限才能干活,这两个参数就是用来解决权限问题的:
-
-b(Become):表示“我要提权”。相当于告诉 Ansible 去执行sudo命令,获取 root 权限。 -
-k(Ask-pass):询问 SSH 密码。如果你的服务器没配 SSH 密钥登录(Key),就需要加这个参数,它会弹窗让你输入服务器密码。 -
-K(Ask-become-pass):询问提权密码。配合-b使用,当你提权到 root 时,如果 root 也需要密码,就加这个。
3. 进阶实用功能
-
-f(Forks):控制并发数。默认是同时操作 5 台机器。如果你有 100 台机器,想快点跑完,可以设为-f 20(同时操作 20 台)。 -
--check(Dry Run):模拟执行。这是一个非常安全的参数!它会告诉你哪些文件会被修改、哪些服务会被重启,但实际上什么都不会动。建议在大批量操作前先用这个参数检查一遍。 -
--diff:显示差异。配合copy或template模块使用时,能看出远程文件到底改了哪些内容。
💡 组合起来举个例子
假设你有一份自定义的机器清单 my_hosts.ini,你想让里面的所有机器(all)执行一个需要 root 权限的命令(比如重启 nginx),但你没配免密登录,需要手动输密码。
你的命令应该是这样的:
ansible all -i my_hosts.ini -b -K -m shell -a "systemctl restart nginx"
解释:在所有机器上,用 sudo 提权,询问 sudo 密码,执行重启命令。
掌握这几个选项,你就能覆盖日常 90% 的运维场景了。

这张图继续深入讲解了 Ad-Hoc 命令的高级参数,并通过一个具体的 yum模块 示例,帮你理解 Ansible 是如何将复杂的 Shell 命令转化为结构化参数的。
我帮你把图中的重点拆解为两部分:
一、 新增的高级控制选项
这部分是对上一页常用选项的补充,主要解决“特殊场景”下的控制需求:
-
-o(--one-line):简化输出-
作用:把原本可能多行的返回结果压缩成一行显示。
-
场景:当你一次性操作几十台机器时,屏幕会非常乱。加上
-o参数能让输出瞬间清爽,方便你快速扫一眼看结果。
-
-
-B(--background):后台异步执行-
作用:Ansible 默认是同步的(一台台执行,等上一台完了才执行下一台)。加上这个参数,它会把任务扔到后台执行。
-
场景:如果你要给 100 台机器升级内核,每台都要跑很久,你肯定不想干等。用
-B 3600让它在后台慢慢跑,配合-P 60每 60 秒检查一下进度。
-
-
-t(--tree):保存日志-
作用:把每一台主机的执行结果分别保存成文件,存到你指定的目录(按主机名分类)。
-
场景:批量执行完任务后,你想复盘“到底哪台机器报错了?报错是什么?”。有了这个参数,你就不用在一大坨混杂的输出里去翻找了,直接去看对应的日志文件即可。
-
二、 深度解析:Ansible 如何实现“幂等性”
图中下半部分的蓝色代码块通过一个 yum安装命令,揭示了 Ansible 最核心的设计理念——幂等性(Idempotency)。
它做了一个非常直观的类比:
-
Shell 命令:
yum install -y vim-
痛点:不管你电脑里有没有装 vim,只要你敲这个命令,它都会重新执行一遍安装流程(下载包、解压、配置)。虽然结果一样,但过程是冗余的。
-
-
Ansible 命令:
ansible all -m yum -a "name=vim-enhanced state=present"-
亮点:它使用了
state=present参数。 -
原理:Ansible 在执行前,会先去目标机器上“探路”。如果发现 vim-enhanced 已经安装了,它就会直接跳过,什么都不做;如果没装,它才会去执行安装。
-
💡 总结来说:
图中的类比意在说明,Ansible 不仅仅是帮你执行命令,它通过模块化的参数(如 state=present),把“动作指令”转化为了“期望状态”。你只需要告诉 Ansible“我要的状态是什么样”,它自己会判断需不需要干活。这就是为什么 Ansible 被称为“基础设施即代码”(IaC)的基石。


这张图解答了一个初学者通常会感到疑惑的问题:为什么 Ansible 的主配置文件(ansible.cfg)里全是带 #号的注释?
图片底部给出的结论非常棒,它道出了 Ansible 配置设计的核心哲学。我帮你把图中的关键点拆解一下:
1. 核心原因:一切皆有默认值
图里第一点说得很清楚:“Ansible 的所有配置参数都有内置的默认值”。
这就好比你买了一台新手机,出厂时它的屏幕亮度、音量大小都是厂商预设好的,你可以直接用,不需要每次开机都去设置一遍。Ansible 也是这样,它自带了一套经过官方精心调校的默认配置,能保证 90% 的场景下都能顺利跑通。
2. 设计哲学:按需覆盖(KISS 原则)
图里第三点提到“避免了配置文件的冗余”。
Ansible 的开发者希望配置文件保持干净。只有当默认配置不符合你的实际需求时(比如你想改一下 SSH 的连接超时时间,或者指定一个新的 Galaxy 服务器地址),你才需要把那一行的注释去掉,并修改成你想要的值。
💡 举个例子:
就像图中第 68 行关于 Galaxy 服务器地址的配置:
# server = https://galaxy.ansible.com
除非你处于内网环境,或者有私有的组件仓库,否则你根本不需要改动它,保持注释状态,Ansible 就会自动乖乖地去连接官方的默认地址下载组件。
总的来说,这种设计大大降低了新手的门槛。你不需要去死记硬背那些复杂的参数,只需要关注你想要改变的那几个配置项就可以了。
这张图展示的是 Ansible 的主配置文件(通常是 /etc/ansible/ansible.cfg) 中的核心部分 [defaults]。
结合你之前上传的几张图,这张图其实是在回答一个很关键的问题:“我之前敲的那些 Ad-Hoc 命令,到底是从哪里读取默认设置的?”
这里列出的每一项,都对应着你之前学过的某个命令行为或环境变量。我帮你把图里最关键的几个配置项挑出来,做个“连连看”:
1. 连接与认证相关(最常用)
-
inventory = /etc/ansible/hosts-
含义:默认的主机清单文件路径。
-
关联:这就是你之前学的
-i参数的默认值。如果你不指定-i,Ansible 就会来这个文件里找机器列表。
-
-
remote_user = root-
含义:默认连接过去使用的用户名。
-
关联:这就是你之前学的
-u参数的默认值。如果你不写-u root,它默认就用 root 登录。
-
-
ask_pass = False-
含义:是否询问 SSH 密码。
-
关联:默认是
False,意味着它希望你配置 SSH 密钥(免密登录)。如果你想用密码登录,就得在命令里加-k,或者把这里改成True(不推荐,因为每次都要输密码)。
-
-
host_key_checking = False-
含义:是否检查目标主机的 SSH 指纹(Host Key)。
-
关联:默认是
False。如果是True,第一次连接新服务器时会弹出一个安全警告让你确认指纹,这在自动化脚本里会卡住,所以通常保持默认不检查。
-
2. 执行行为相关
-
forks = 5-
含义:默认并发数。
-
关联:这就是你之前学的
-f参数的默认值。意味着默认同时操作 5 台机器。
-
-
timeout = 10-
含义:连接超时时间(秒)。
-
关联:如果服务器 10 秒内没反应,Ansible 就认为连不上了。
-
-
module_name = command-
含义:默认模块。
-
关联:如果你直接敲
ansible all -a "ls",没写-m,Ansible 默认就会调用command模块。
-
3. 日志与调试
-
log_path = /var/log/ansible.log-
含义:默认日志文件路径。
-
关联:如果你之前学了
--verbose或者任务报错了,详细的执行记录会写进这个文件里,方便事后查案。
-
💡 总结
这张图其实就是一张 “默认值对照表”。
Ansible 的设计理念是“约定优于配置”。它在代码里写死了一套 defaults(如图所示),所以你之前只需要敲最简单的命令就能跑起来。当你觉得默认设置不顺手时(比如你想改默认用户,或者想改并发数),你有两种选择:
-
在命令行加参数(比如
-u admin,-f 20)。 -
修改这个配置文件,把对应的
#号去掉并把值改了。

这张图展示了 Ansible 主配置文件中更深层的几个配置区块,主要涉及底层连接优化、生态组件获取以及视觉反馈的设置。
它补全了之前配置拼图的最后几块关键碎片,我帮你把这三个区块的核心要点拆解一下:
1. 底层连接优化:[persistent_connection]
位于图片上半部分,这是 Ansible 用来提升性能的关键设置。
-
痛点背景:默认情况下,Ansible 每执行一条命令(Task)都可能要重新建立一次 SSH 连接,销毁再重建,这在大规模操作时非常耗时。
-
timeout = 30:持久连接的超时时间。开启了这个功能后,Ansible 会尝试在同一个 SSH 会话里连续执行多个任务,而不是用完就扔。这能大幅减少连接建立的握手时间,显著提升执行速度。 -
scp_if_ssh = True:这是一个非常实用的“兼容性”开关。意思是如果 SSH 连接建立起来了,但发现目标机器不支持 SFTP(传文件协议),Ansible 会自动降级使用 SCP 协议来传文件。这能解决很多老旧系统或非标准环境导致的“传文件失败”问题。
2. 生态组件获取:[galaxy]
位于图片中间部分,这是 Ansible 的“应用商店”配置。
-
server = ...:指定去哪里下载别人写好的 Roles(角色)。默认是官方的galaxy.ansible.com。如果你在公司内网,通常会把这里改成私有仓库的地址。 -
api_key = xxxxx:这是你的“会员卡”。很多高级功能或私有组件需要登录账号并填入 API Key 才能下载。
3. 视觉反馈增强:[colors]
位于图片下半部分,纯粹为了让你的眼睛更舒服。
-
作用:自定义命令行输出的颜色。
-
场景:在满屏的黑白滚动代码中,颜色能帮你瞬间定位状态。
-
error = red:看到红色,心里一紧,知道出错了。 -
changed = yellow:看到黄色,知道这台机器被修改了(符合 Ansible 的幂等性检查)。 -
ok = green:看到绿色,放心,这台机器一切正常,什么都没发生。
-
💡 总结
结合你之前上传的几张图,我们现在看到了 Ansible 配置的完整面貌:
-
[defaults](之前学过):管的是“怎么连、谁来连、连几个”。 -
[persistent_connection](本图):管的是“连上之后怎么跑得更快”。 -
[galaxy]:管的是“去哪找扩展插件”。
这套配置体系的设计依然贯彻了 Ansible 的宗旨:默认配置开箱即用,高级配置按需开启。


这张图开始介绍 Ansible 的核心概念之一:主机清单(Inventory),也就是你管理的主机名单。
如果说 Ansible 是遥控器,那么 Inventory 就是你要遥控的那些设备的“通讯录”。这里详细讲解了静态 Inventory 的定义规则和默认分组逻辑。
我帮你把图里的核心规则提炼成三个关键点:
1. 两种“默认”路径
图里提到了两个容易混淆的“默认”,需要区分开:
-
默认的主机清单文件:通常是
/etc/ansible/hosts。这是 Ansible 启动时会去“默认找”的文件。 -
由配置文件定义:这个默认路径其实是可以改的。正如上一节课讲的,你可以在
ansible.cfg里的inventory参数修改它,或者在敲命令时用-i参数临时指定。
2. 核心规则:分组与归属
Inventory 的灵魂在于“分组”。
-
方括号
[]:这是定义一个组的标志。比如[webservers]下面列出的机器,就属于这个组。 -
未分组主机:如果你直接在文件开头写 IP 或域名,没有包在任何
[]里,它们就属于“独行侠”。
3. 两个隐形的“默认组”
这是图中最下方的重点,哪怕你的文件里什么都不写,Ansible 也会自动给你创建两个虚拟组:
-
all:包含所有机器。无论你把机器分到哪个组,或者没分组,它都在all里。平时最常用的命令ansible all -m ping就是 ping 这个组里的所有机器。 -
ungrouped:包含所有未分组的机器。专门用来抓那些漏网的“独行侠”。
💡 实战理解
看图中最下面的代码示例:
mail.example.com # 这是一个没分组的机器
[webservers] # 这是一个名为 webservers 的组
foo.example.com
bar.example.com
在这个场景下:
-
mail.example.com属于all组,也属于ungrouped组。 -
foo和bar属于all组,也属于webservers组。 -
如果你执行
ansible webservers -m shell -a "uptime",只有foo和bar会执行,而mail不会。
这张图展示的是 Ansible 默认的静态主机清单文件(/etc/ansible/hosts)的内容。
如果说上一张图是“设计图纸”,这张图就是一份“实际填写的样例”。它非常直观地演示了如何按照规则把一堆机器归类管理。
我帮你把图里最有用的三个实战技巧提炼出来:
1. 语法规则的“活字典”
图的上半部分用英文描述了核心语法,最关键的几点如下:
-
注释与空行:以
#开头的行或者空行都会被忽略,这意味着你可以随便留白或写备注,不用担心报错。 -
分组标识:用
[组名]来划分类别,比如[webservers]。 -
主机成员:下面缩进或换行列出的 IP 或域名,都属于这个组。
2. 必学的“数字简写”技巧(最省事)
看图中间 Ex 2下面的这行代码:
## www[001:006].example.com
这是一个非常强大的范围匹配语法,在实际工作中能帮你少敲无数键盘:
-
含义:自动生成从
www001.example.com到www006.example.com的连续主机列表。 -
场景:假设你有 100 台服务器,编号从 1 到 100。你完全不需要手动敲 100 行 IP,只需要写一行
192.168.1.[1:100].xip.io,Ansible 会自动把它们全部识别为独立的主机。
3. 混合使用示例(All in One)
结合图里的 Ex 1、Ex 2和 Ex 3,一个成熟的 hosts文件通常是这样组合的:
# 第一部分:未分组的“杂鱼”放最上面 (对应 Ex 1)
mail.server.com
db.backup.com
# 第二部分:正式的分组 (对应 Ex 2 & Ex 3)
[webservers]
alpha.example.org
beta.example.org
192.168.1.100
192.168.1.110
[dbservers]
mysql01.internal
mysql02.internal
# 第三部分:使用简写生成大批机器
[testing_env]
test-srv[01:20].lab.local
💡 总结:
这张图不仅是说明书,其实也是一份“填空题模板”。当你需要管理的新机器越来越多时,只要照着这个格式往 /etc/ansible/hosts里添加,就能让 Ansible 精准识别出你的资产。


这两张图完整地展示了 Ansible 入门时最经典的一个“拦路虎”:SSH 首次连接时的指纹确认问题,以及如何通过配置来解决它。
我把这两张图的内容串联起来,帮你梳理成一个完整的实战解决指南:
1. 问题的根源(图1的现象)
当你第一次用 Ansible 连接一台新机器时,底层的 SSH 协议为了安全,会检查目标服务器的“指纹”(类似人的指纹,用于确认身份)。
-
现象:屏幕上会卡住,提示
Are you sure you want to continue connecting (yes/no/[fingerprint])?。 -
原因:这是为了防止中间人攻击。Ansible 默认是全自动的,遇到这种需要人工输入
yes确认的提示,它就会一直等待,直到超时失败。
2. 三种解决思路(图2的解法)
图2 非常贴心地给出了从“笨办法”到“聪明办法”的三种解决方案,我按推荐程度给你排个序:
方法一:手动“破冰”(最稳妥,推荐新手)
-
操作:在控制节点(你的电脑)终端里,直接敲命令
ssh root@192.168.x.x,挨个连一下目标机器。 -
原理:手动输入
yes并回车。这样系统会把目标机器的指纹存到~/.ssh/known_hosts文件里。下次 Ansible 再去连的时候,发现“诶,这机器我认识”,就不会再卡住了。 -
优点:最安全,符合 SSH 的标准安全流程。
方法二:全局关闭检查(最省事,测试环境专用)
-
操作:修改 Ansible 的配置文件
ansible.cfg。 -
配置:在
[defaults]下面加一行host_key_checking = False。 -
原理:告诉 Ansible,“以后连任何机器都别问指纹了,直接连”。
-
⚠️ 注意:正如图片里标注的,仅限测试环境使用。在生产环境千万别这么干,否则有人冒充服务器 IP 你都不知道,会有安全风险。
方法三:仅针对特定主机关闭(进阶玩法)
-
操作:修改主机清单文件
hosts。 -
配置:在具体的 IP 后面加上一串变量,比如
ansible_ssh_common_args='-o StrictHostKeyChecking=no'。 -
原理:这相当于给这几台机器发了“免检通行证”,只对它们生效,不影响其他机器。
3. 进阶避坑指南
图2 最下方还指出了一个常见误区:“因为我们并没有指定用户名和密码,所以 SSH 无法正常连接。”
-
解释:解决了指纹问题后,如果你没配 SSH 密钥,Ansible 还是会卡住要密码。
-
对策:
-
配密钥(正道):在控制节点生成密钥
ssh-keygen,然后用ssh-copy-id把公钥推送到目标机器。这样 Ansible 就能免密登录了。 -
强制提密码(临时):运行 Ansible 命令时加上
--ask-pass参数(缩写-k),它就会弹窗让你输入密码。
-
💡 总结:
学 Ansible 的第一道坎就是这个问题。如果你是初学者,建议先用方法一(手动 SSH 连一下),养成良好的安全习惯;如果想图省事快速看到效果,就用方法二(改配置文件关掉检查)。

这张图承接了上一张的内容,继续解决 SSH 连接时的另一个核心问题:“免密登录”配置。
当你解决了指纹确认(Host Key Checking)的问题后,如果目标机器没有配置 SSH 密钥,Ansible 依然无法登录。这张图展示了两种让 Ansible “知道”密码的方法,以及一个成功后出现的“假报警”。
我帮你把图里的核心要点拆解如下:
1. 解决认证失败的两种方式
图的上半部分演示了如何让 Ansible 获取登录密码:
-
方法一:命令行交互式输入(
-k参数)-
操作:
ansible all -m ping -k -
解释:这是最基础的测试方式。加上
-k后,Ansible 不会直接连,而是会在终端弹窗让你输入 root 密码。适合临时测试一次。
-
-
方法二:在清单文件中明文配置(
ansible_password)-
操作:在
/etc/ansible/hosts文件的 IP 后面加上ansible_password=你的密码和ansible_user=root。 -
解释:这是图里重点展示的写法。这样做的好处是一劳永逸,以后执行任何命令都不用再加
-k了,Ansible 会自动读取这里的密码去连接。 -
⚠️ 安全提示:这种方式虽然方便,但密码是明文写在文件里的,非常不安全。只适合在自己电脑上的测试环境玩玩,千万不要把带密码的 hosts 文件上传到 Git 等代码仓库!
-
2. 成功后的“假报警”(WARNING)
图的下半部分提到,当密码问题解决,终于看到 pong(成功)的反馈后,你可能会发现屏幕上方多了一行黄色的字:
[WARNING]: Platform linux on host ... is using the discovered Python interpreter ...
-
这是什么意思?
这其实是一个温馨提示,不是报错,你可以放心。它的意思是:Ansible 连上这台机器后,自动在
/usr/bin/python3找到了 Python 环境,并准备用这个环境来运行后续的模块。 -
为什么要警告?
Ansible 是靠 Python 脚本在远程机器上干活的。它担心万一这台机器以后升级了系统,或者 Python 版本变了,导致这个路径失效了,那 Ansible 下次可能就会执行失败。
-
需要做什么吗?
不需要。 在绝大多数 Linux(如 openEuler, CentOS, Ubuntu)默认安装的情况下,这个路径都是稳定的。看到这个提示,说明 Ansible 已经完全打通了任督二脉,准备就绪了!

这张图解决的是 Ansible 运行时的最后一个常见问题:Python 解释器路径的自动探测警告。
在用 ping模块测试连通性成功后,如果目标机器上有多个 Python 版本,或者 Ansible 自动找到的路径不够稳定,就会出现图中的 WARNING提示。这个提示虽然不影响当前的测试(已经看到 pong了),但为了后续写复杂剧本(Playbook)不报错,最好把它消灭掉。
这里有三种处理方式,按推荐程度排序如下:
1. 局部指定(方法一:最稳妥,推荐)
如果你只想让特定的某几台机器用指定的 Python 路径,就在 hosts文件里单独配置。
-
做法:在 IP 后面加上
ansible_python_interpreter=/usr/bin/python3。 -
好处:不影响其他机器,哪台机器有问题修哪台,互不干扰。
2. 全局默认(方法二:最省事)
如果你想一劳永逸,让所有机器都用这个路径,就去改全局配置文件。
-
做法:编辑
/etc/ansible/ansible.cfg,在[defaults]下添加interpreter_python = /usr/bin/python3。 -
好处:以后新建的主机不用再单独配置了,适合统一管理一批环境一致的机器。
3. 闭嘴模式(方法三:最简单粗暴)
如果你觉得这个黄字看着烦,不想改任何配置,只想让它消失。
-
做法:同样是在
ansible.cfg里,把配置改成interpreter_python = auto_legacy_silent。 -
好处:眼不见心不烦。
💡 最终胜利
当你按照方法一或方法二配置好,再次执行 ansible all -m ping时,屏幕上就不会再出现那个黄色的 [WARNING]了,取而代之的是干净清爽的 SUCCESS和 "ping": "pong"。这时候,你的 Ansible 环境就算是完全打通,准备就绪,可以开始学习写剧本(Playbook)了!

这张图讲的是 Ansible 最推荐的认证方式:SSH 公钥认证(免密登录)。
这也是企业级运维的标准做法,比之前讲的输密码或者用明文存密码要安全、优雅得多。整个配置过程就像是在给控制节点发“通行证”。
我帮你把图里的步骤拆解成通俗易懂的“三步走”:
第一步:在控制节点生成密钥对
-
命令:
ssh-keygen -t rsa -
解释:这会在你的控制节点(也就是你操作的这台电脑)上生成一对钥匙。
-
一把是私钥(留在本地,锁在保险柜里,千万别发给别人)。
-
一把是公钥(可以大胆地复制给任何人)。
-
-
注意:执行命令后,如果问你 "Enter passphrase",可以直接回车留空,这样以后用起来最方便。
第二步:把公钥推送给目标主机
-
命令:
ssh-copy-id root@192.168.100.10 -
解释:这就是发“通行证”的过程。这个命令会把刚才生成的公钥,自动添加到目标主机的
~/.ssh/authorized_keys文件里。 -
现象:第一次执行这个命令时,因为还没有配置免密,所以需要输入一次目标主机的密码。输入正确后,以后就再也不需要输密码了。
第三步:测试免密连接
-
验证:先自己
ssh root@192.168.100.10试试,看看是不是直接就进去了(不需要输密码)。 -
终局:回到 Ansible 目录,执行
ansible all -m ping。 -
结果:如果一切顺利,你会看到一堆绿色的
"pong"。这说明 Ansible 已经完全掌握了“隔空操控”的技能,以后再执行任何复杂的自动化任务,都不会被密码卡住了。
💡 总结:
这套流程走完,你的 Ansible 环境就彻底“毕业”了。从此告别繁琐的密码输入,正式进入自动化运维的大门!

恭喜你!看到这个界面,说明你的 Ansible 环境已经彻底打通,完全毕业了! 🎉
这张截图很有纪念意义,因为它展示了你经过前面一系列配置后,最终达成的完美状态。我们可以对着图里的两部分内容来做个“毕业总结”:
1. 上半部分:成功的“回响”
你看那段绿色的 JSON 输出:
{
"changed": false,
"ping": "pong"
}
-
"ping": "pong":这就是 Ansible 界的“Hello World”。它意味着管理节点已经成功通过 SSH 登录到了目标机器,并且在目标机器上成功执行了 Python 代码。这说明你的网络是通的,认证是成功的,Python 环境也是没问题的。 -
"changed": false:这个细节也很重要,它表示这次执行只是去“探路”,没有对目标机器做任何修改(比如安装软件、修改文件等),这符合ping模块的只读特性。
2. 下半部分:背后的功臣
你特意执行了 cat .ssh/known_hosts,这非常棒!这让你亲眼看到了之前我们讨论过的“指纹确认”问题是怎么解决的。
-
列表里整整齐齐地记录了
192.168.100.10到.13这四台机器的 SSH 指纹(包括ssh-ed25519和ssh-rsa两种算法)。 -
正是因为刚才你手动
ssh连过去,或者在配置里关掉了严格检查,这些机器的“身份信息”才会被记录在这里。Ansible 下次再连的时候,发现“诶,这机器我认识”,就不会再卡在那一步了。
💡 下一步建议:
既然基础的“打招呼”已经没问题了,接下来你就可以尝试写真正的剧本(Playbook)了。比如写一个最简单的 YML 文件,让 Ansible 帮你把这四台机器的时间同步一下,或者安装个 Nginx。
大胆往下走吧,自动化运维的大门已经为你敞开!
这张图介绍了一个 Ansible 中非常实用且高级的功能:嵌套组(Children Groups),也就是常说的“父子组”或“分组套娃”。
这是一个管理多台服务器时的“偷懒神器”,它能帮你实现批量管理和变量继承。我帮你把图里的核心逻辑拆解一下:
1. 什么是“父子组”?
简单来说,就是把几个平级的组(子组),归拢到一个更大的组(父组)下面。
-
图中的例子:
-
子组:
web_servers(Web服务器组)和db_servers(数据库服务器组)。 -
父组:
production(生产环境组)。 -
关系:
production包含了web_servers和db_servers。
-
2. 这里的“:children”是什么意思?
在 /etc/ansible/hosts文件里,定义父组时后面加个冒号 :,然后跟上 children关键字,意思就是告诉 Ansible:“别把后面这些名字当成具体的 IP 地址,它们其实是别的组的名字,请把它们包含进来。”
3. 核心玩法:变量继承(重点!)
图里特别提到:“父组的变量会自动传递给子组,而子组可以覆盖父组的变量。”
这是企业运维中最常用的技巧,举个例子你就懂了:
-
场景:你们公司的所有服务器(不管 Web 还是 DB)都有一个统一的 SSH 端口(比如 22)和一个统一的环境变量。
-
操作:
-
你在
production这个父组下面定义一个变量,比如ansible_ssh_port=22。 -
web_servers和db_servers下的所有机器,自动就拥有了 22 端口的配置,不需要每台机器都写一遍。 -
如果某个特殊的 Web 服务器想用自己的端口(比如 2222),只需要在那台机器后面单独写上
ansible_ssh_port=2222,它就会覆盖父组传下来的默认值。
-
4. 命令行的变化(实战效果)
看代码的第 12 行:
-
以前:你要测试所有机器,得敲
ansible all -m ping(查所有)。 -
现在:你可以直接敲
ansible production -m ping。 -
结果:Ansible 会自动找到
production下面的web_servers和db_servers里的所有 IP(也就是全部的 10, 11, 12, 13),一次性全部 Ping 一遍。
💡 总结:
学会用 :children组织你的主机清单,能让你的 Ansible 配置变得非常整洁。以后再买了一批新服务器,只需要把它们加到对应的子组里,所有针对父组的统一配置(比如账号、密码、基础环境)都能瞬间自动生效,这才是真正的自动化!
这张图展示了一个非常实用的 Ansible 命令:ansible-inventory --graph,它用来可视化你当前的主机清单结构。
结合你上一轮学习的“父子组(嵌套组)”知识,这张图其实是把你写在 /etc/ansible/hosts文件里的分组关系,转化成了一棵清晰的“树”。
我帮你拆解一下图里各个部分的含义:

1. 树状结构的读法
-
|--@all:这是最顶层,代表你所有的主机集合。 -
| |--db_web::这是你定义的一个父组(虽然图里没展开它的children,但能看出它是一个分组节点)。 -
| |--@db_servers::这是一个子组,注意前面的@符号,代表这是一个“组”。-
| | |--192.168.100.12:这是具体的 IP 地址,它是db_servers组的成员。 -
| | |--192.168.100.13:同上。
-
-
| |--@web_servers::这是另一个子组。-
里面包含了
192.168.100.10和11。
-
-
| |--@ungrouped::未分组。-
这是一个特殊的分支。如果你有一台机器写了 IP,但是没有放在任何
[组名]里,它就会默认出现在这里。图里它是空的,说明你现在的机器都乖乖地放在组里了。
-
2. 为什么要用这个命令?
当你管理的机器越来越多,分组越来越复杂(比如有生产环境、测试环境、开发环境,每个环境下又有 Web、DB、Cache),光看 /etc/ansible/hosts文件里的纯文本可能会眼花缭乱。
执行 ansible-inventory --graph,就像给你的清单拍了一张 X 光片,让你一眼就能看清:
-
谁是谁的儿子(变量继承自谁)。
-
谁包含了谁(执行命令时的范围)。
3. 结合之前的实战
你现在可以尝试在终端输入这个命令,看看输出的树是不是和图上一样。
理解了这棵树的结构后,以后你再执行命令,比如 ansible db_servers -m ping,心里就更有底了:Ansible 会顺着这棵树,精准地找到 db_servers下面的那两个 IP(12 和 13),而不会去动 Web 服务器。

这张图讲的是 Ansible 清单文件中非常实用的“批量定义主机”技巧。
当你的服务器数量达到几十上百台时,如果还像写诗一样一行行敲 IP,不仅累,而且不好维护。Ansible 允许你用范围、通配符来“偷懒”,高效管理主机。
我把图里的三个核心技巧拆解给你:
1. 数字范围(最常用,适合 IP 段)
这是运维中最常见的场景,比如你有 10 台 Web 服务器,IP 是连续的。
-
写法:
[组名] 前缀.[开始:结束:步长] -
例子:
192.168.100.[10:11:1]-
表示从 10 开始,到 11 结束,每隔 1 个取一个。
-
结果就是:
192.168.100.10和192.168.100.11。
-
-
进阶:如果你想生成 1 到 9(单数),可以写成
[01:09:2],结果就是 01, 03, 05, 07, 09。
2. 字母范围(适合有序命名)
如果你的服务器不是用 IP,而是用主机名命名的,且名字有规律,也可以用字母范围。
-
写法:
前缀-[起始字母:结束字母] -
例子:
log-[a:d]-
结果就是:
log-a,log-b,log-c,log-d。
-
-
应用场景:比如你有
web-01,web-02...web-50,你可以简写成web-[01:50],非常省事。
3. 通配符匹配(模糊查找)
当你不需要列出具体的 IP,只想按规则抓一把主机时用。
-
星号
*:代表任意字符。-
*.example.com:抓取所有以.example.com结尾的域名。 -
server-*.mydomain.org:抓取所有以server-开头的机器。
-
-
问号
?:代表单个字符。-
虽然图上没写,但你可以记一下,比如
web-?就能匹配web-1到web-9,但不会匹配web-10。
-
💡 避坑小贴士:
在使用数字范围 [x:y]时,如果步长(第三个数字)省略了,默认是 1。但如果你的数字是两位数(比如 01 到 10),强烈建议补零对齐(即写成 [01:10]),否则 Ansible 可能会按字符串排序,导致顺序错乱。
掌握这三个技巧,以后面对成百上千台服务器,你的 hosts文件也能保持清爽整洁!

这张图讲的是 Ansible 中管理主机清单的“分治策略”——把清单文件拆分成多个文件存放在目录中。
当你的服务器规模变大(比如几百台),或者团队协作时,把所有机器的 IP 都塞进一个 /etc/ansible/hosts文件里,会变得非常臃肿且难以维护。
图里展示的解决方案就是:建个文件夹,把不同用途的清单拆成不同的文件。
1. 核心操作逻辑
你可以看到图中演示了三个步骤:
-
建目录:
mkdir /opt/inventory(创建一个专门的清单库)。 -
搬文件:把原本独立的
db_servers和web_servers文件移进去。-
注意:这里有个拼写小彩蛋,命令里写的是
inventroy,少了一个r,实际操作时记得写对哦。
-
-
指定目录:在执行命令时加上
-i /opt/inventory。
2. 为什么要这么做?(好处)
-
模块化(好维护):Web 团队只管改
web_servers文件,DB 团队只管改db_servers文件,互不干扰。 -
灵活性(易扩展):以后如果有新项目,直接新建一个文件扔进这个目录就行,不用去动老文件。
-
Ansible 的智能合并:你不需要在命令行里把所有文件名都列出来,只要告诉 Ansible “去这个目录里找”,它会自动把目录下所有合法的清单文件合并在一起使用。
3. 关键知识点
-
-i参数的妙用:通常-i是用来指定单个 inventory 文件的,但它同样支持指定一个包含多个文件的目录。 -
自动加载:Ansible 默认会读取该目录下的所有文件(除了以
.ini或.yml等特定后缀结尾的,或者隐藏文件),并将它们视为同一个全局清单的一部分。
💡 实战建议:
这种目录式的清单管理方式是企业级应用的标配。你甚至可以在目录下再建子目录(比如按环境分 prod/和 test/),Ansible 依然能递归读取,结构非常清晰!


这张图讲解了 Ansible 中两个非常关键的进阶知识点:如何永久配置清单路径以及清单文件的加载机制。
这里揭示了三个容易踩坑但非常重要的细节:
1. 配置“全局”清单路径
之前我们执行命令时都要加个 -i /opt/inventory来临时指定清单文件。
图片中间部分演示了一个“一劳永逸”的方法:修改配置文件。
-
编辑
/etc/ansible/ansible.cfg。 -
找到
[defaults]段落,把inventory这一行改成你的目录路径。 -
生效后:以后你再执行
ansible all -m ping,它就不再去读默认路径,而是直接去读你指定的这个新目录了。
2. 核心坑点:ASCII 码顺序加载
这是这张图里最重要的一个知识点。
Ansible 在读取一个目录下的多个清单文件时,是按照文件名的 ASCII 码顺序(也就是字典序,0-9 排在最前,然后是 a-z)来加载的。
3. 致命的“父子组”顺序问题
图中下半部分通过一个未完全显示的代码示例,警告了一个特定的报错场景:
-
场景:假设你有两个文件,一个定义了父组(比如叫
a),里面引用了子组;另一个定义了子组(比如叫b)。 -
冲突:如果你的文件名是
a和b,按照 ASCII 顺序,a排在b前面。 -
后果:Ansible 先读到
a文件,发现里面有个子组叫web_servers,但它此时还没读到b文件,根本不知道web_servers是谁,于是就会直接报错!
💡 实战建议:
为了避免这种报错,在给清单文件命名时,一定要让“父组”的文件名排在“子组”之后。
比如,你可以把文件命名为 10_base.ini(放基础变量)、20_web.ini(放 Web 组)、30_full.ini(放包含子组的父组)。这样按数字顺序加载,就能确保子组先被定义,父组后被关联,永远不会报错。

这张图开始介绍 Ansible 中非常核心的概念——变量。
虽然标题是“变量”,但表格里列出的其实是一组专门用于“连接控制”的特殊变量。在 Ansible 中,这类变量通常以 ansible_开头,它们主要用来定义如何连接到目标主机以及连接后的权限操作。
我把图里这几个最常用的变量给你拆解一下,这些都是日常运维打交道最多的:
1. 连接参数(告诉 Ansible 怎么连)
-
ansible_host:连接目标。-
通常 SSH 连的是 IP,但如果你给机器起了个别名(比如在 hosts 文件里写
web01 ansible_host=192.168.1.10),Ansible 就会用这个名字去解析对应的 IP。
-
-
ansible_port:非标准端口。-
默认 SSH 是 22 端口。如果你的服务器为了安全改成了 2222,就必须在这里声明,否则 Ansible 会连不上。
-
-
ansible_user:登录用户。-
指定用哪个账号去登录。比如你本地是 root,但服务器要求用普通用户
ubuntu登录,就写这个。
-
-
ansible_ssh_private_key_file:指定密钥。-
如果你有多个密钥对应不同的服务器,可以在这里指定私钥文件的路径(比如
~/.ssh/deploy.key),Ansible 就会用这个特定的钥匙去开门。
-
2. 权限提权(Privilege Escalation,俗称 sudo)
这是运维中最常用的功能,也就是“变身”。
-
ansible_become:是否提权。-
设为
true表示允许 Ansible 在连上机器后,执行类似sudo的命令,把自己变成管理员。
-
-
ansible_become_user:变成谁。-
提权后变成哪个用户?通常是
root,也可以是其他有特定权限的用户。
-
💡 实战小提示:
图里特别标注了 ansible_password不推荐明文。
在实际工作中,我们几乎不会把密码直接写在文件里(太不安全,且容易被版本控制泄露)。通常的做法是:
-
配置 SSH 免密登录(配合公私钥)。
-
或者使用 Ansible Vault(密码保险箱)来加密敏感变量。
掌握了这些连接变量,你就可以轻松应对各种复杂的服务器环境(比如混合了不同端口、不同密钥、不同用户的集群),而不用去修改底层的 Playbook 代码了。


这两张图接续了之前的内容,进一步介绍了 Ansible 中“变量”的更高级用法,特别是如何在清单文件中定义特定于主机或组的业务变量。
这里有三个核心知识点需要掌握:
1. 基础设施变量(业务配置)
之前讲的都是连接用的变量,而这里表格列出的是应用层面的变量。
-
作用:用来定义应用程序的配置参数。
-
例子:
-
http_port=8080:告诉 Nginx 监听哪个端口。 -
db_host=db01.example.com:告诉 Web 服务器数据库在哪里。 -
data_dir=/opt/data:定义数据存储的路径。
-
-
优势:这样做可以让同一份 Playbook 在不同环境下复用。比如测试环境连测试库,生产环境连生产库,只需要改清单文件里的这个变量,不用改代码。
2. 命名规范
图中强调了小写+下划线(snake_case)的命名方式。
-
这是 Ansible 社区的标准规范,建议遵守,这样代码看起来更专业,也避免一些因大小写敏感导致的莫名其妙错误。
3. 变量作用域的定义方法(:vars)
图中最下方的代码块展示了最佳实践:如何为特定的组定义变量。
-
语法:
[组名:vars]-
例如
[web_servers:vars]
-
-
含义:这行下面的所有键值对(
key=value),都仅仅属于web_servers这个组里的机器。 -
好处:
-
归类清晰:一看就知道这些变量是给 Web 服务器用的。
-
避免污染:不会不小心把数据库密码写到 Web 组里。
-
注释友好:你可以在变量上面加注释(如
# 生产环境Nginx配置),说明这组变量的用途。
-
💡 实战小技巧:
如果你有一个变量(比如 nginx_worker_processes),希望所有的机器都拥有,你可以把它定义在 [all:vars]下面,这样就不用在每个组里重复写了。

这张图展示了 Ansible 清单文件中变量赋值和分组继承的实际应用,特别是演示了如何针对特定主机设置连接参数。
我帮你把图里的三个关键知识点拆解一下:
1. 针对单个主机的变量赋值(图中最核心的一行)
请看图中 db_servers组下的这一行:
192.168.100.12 ansible_port=2222
-
含义:这行代码的意思是,对于 IP 为
192.168.100.12这台机器,单独将 SSH 连接端口设置为2222。 -
作用:这是一种“就近原则”。虽然整个
db_servers组可能都使用默认端口 22,但只要在这台机器后面加上ansible_port=2222,Ansible 在连接它时就会自动使用 2222 端口,而不会影响组里的其他机器(如 100.13)。这在处理“特立独行”的服务器时非常有用。
2. 连续数字范围简写
图中上方注释掉的那行代码:
db-[99:101]-node.example.com
-
含义:这是之前提到的数字范围语法的实际应用。
-
结果:Ansible 会自动展开为
db-99-node.example.com、db-100-node.example.com和db-101-node.example.com。 -
细节:注意这里 没有补零(没有写成
099),Ansible 会按字符串处理,这在大多数情况下是符合预期的。
3. 组的层级嵌套(:children)
看图中最下方的 all_db_web组:
[all_db_web:children]
web_servers
db_servers
-
含义:冒号加
children表示这是一个父组。 -
作用:它本身不包含具体的 IP 地址,而是把
web_servers和db_servers这两个子组“拉进来”组成一个大团队。 -
好处:当你想对整个架构(Web+DB)进行统一操作时(比如重启所有服务),只需要针对
all_db_web这个组执行命令即可,不需要分别指定两个组。


这张图通过一个具体的实验,演示了 Ansible 中一个非常核心的概念:变量优先级(Variable Precedence),也就是“当有冲突时,到底听谁的”。
1. 实验目的
图中的文字说明了意图:
“将 192.168.100.12 的 root 密码修改为 123,指定 host 密码变量为 123,组的密码变量为 Huawei@123,查看最终以哪个为准。”
这里就是在制造冲突:
-
组变量(较低优先级):在
[db_servers:vars]里定义了ansible_password=Huawei@123。 -
主机变量(较高优先级):在
192.168.100.12这一行直接定义了ansible_password=123。
2. 核心结论:主机变量 > 组变量
虽然图中底部的测试结果被截断了,但根据 Ansible 的规则,结果已经注定:
最终 192.168.100.12 会使用 123这个密码。
原理解析(就近原则):
-
组变量就像是“部门规定”,适用于整个团队(db_servers 组里的 12 和 13 都应该遵守)。
-
主机变量就像是“个人特批”,专门针对某台机器。
-
当“个人”和“集体”的规定冲突时,Ansible 遵循“精准打击”原则,以主机变量为准。因为它离目标主机最近,最具体。
3. 避坑指南与安全警示 ⚠️
这个实验虽然简单,但揭示了一个运维大忌:
-
不要这么写! 图中的写法是为了演示优先级,在实际生产环境中是极其危险的。
-
原因:Ansible 的
ping模块(以及底层的 SSH 连接)在验证失败时,给出的报错通常是“Authentication failed”(认证失败)。如果你遇到这个问题,你很难第一时间反应过来是哪一层的密码错了。是组密码没改对?还是这台主机的专属密码输错了? -
最佳实践:
-
统一使用 SSH Key:彻底放弃在清单文件里写密码(
ansible_password)。 -
如果必须用密码:建议使用
--ask-pass交互式输入,或者使用更加安全的 Ansible Vault 对变量文件进行加密,而不是明文写在hosts文件里。
-
总结来说,记住这张图的结论:清单文件里,写在同一行(主机变量)的优先级永远高于写在组下面(组变量)的。
这张图非常直观地演示了 Ansible 中变量优先级(叠加/覆盖)的规则,特别是展示了当多个层级都定义了同一个变量时,Ansible 是如何处理的。
我们可以把这个例子看作一个“套娃”结构,从里到外分别是:主机 -> 子组 -> 父组。
1. 场景梳理
图中定义了一个名为 all_db_web的大组,它包含了 web_servers和 db_servers两个子组。现在,针对同一个变量 ansible_password,有三层定义:
-
第一层(最底层):主机变量
-
在
db_servers组内的192.168.100.12这一行,定义了ansible_password=123。 -
含义:这台机器想用自己的专属密码
123。
-
-
第二层:子组变量
-
在
[db_servers:vars]下面,定义了ansible_password=Huawei@123。 -
含义:db_servers 这个组希望用统一的密码
Huawei@123。
-
-
第三层(最顶层):父组变量
-
在
[all_db_web:vars]下面,定义了ansible_password=1234。 -
含义:整个大团队(Web+DB)都想用超级统一的密码
1234。
-
2. 核心规则:子组覆盖父组,主机覆盖一切
当 Ansible 执行命令去连接 192.168.100.12这台机器时,它会把这三级变量收集起来,按照以下逻辑决定最终用哪个:
-
子组 vs 父组:Ansible 规定,子组的变量优先级高于父组。所以,
db_servers组的Huawei@123会覆盖掉all_db_web组的1234。此时暂定密码为Huawei@123。 -
主机 vs 组:Ansible 规定,主机自身的变量优先级最高。所以,
192.168.100.12主机的123会覆盖掉db_servers组的Huawei@123。
3. 最终结论
当执行 ansible all -m ping时,Ansible 尝试连接 192.168.100.12,最终使用的密码绝对是 123。
4. 避坑指南
从这个例子可以看出,如果在大型项目中对变量优先级不熟悉,很容易写出“逻辑陷阱”。比如在这个例子中,虽然管理员可能在父组统一设置了密码 1234,但因为底层的子组和主机层层覆盖,导致实际连接时并没有使用这个统一密码。建议在定义变量时保持逻辑清晰,尽量遵循“就近原则”,避免在过多层级中对同一变量进行反复覆盖。

这张图开始进入 Ansible 进阶 部分,核心内容是介绍运维中最常用的 file模块。
简单来说,file模块就是 Ansible 用来管理文件和目录的工具,相当于 Linux 下的 touch、mkdir、rm、chmod、chown等命令的集合体。
我把图里提到的几个关键参数(也是日常使用频率最高的)给你拆解一下:
1. 核心参数解析
-
path(路径)-
含义:你要操作的文件或目录在哪里。
-
注意:这是必选项。它有几个别名(
dest,name),但在新版本中官方推荐使用path。
-
-
state(状态) —— 最重要的参数-
这个参数决定了 Ansible 要对文件做什么动作。
-
directory:创建目录。如果目标不存在,就新建一个文件夹;如果存在,就确保其属性正确。 -
file:确保是普通文件。如果不存在,通常会报错(除非配合touch)。 -
touch:创建空文件。类似于 Linux 的touch命令,没有就建一个,有就更新时间戳。 -
link/hard:创建软链接/硬链接。类似于ln -s或ln。 -
absent:删除。不管原来是什么,统统删掉,确保目标不存在。
-
-
mode(权限)-
含义:设置文件或目录的读写权限。
-
写法:支持八进制(如
0644)或符号模式(如u+rwx)。 -
注意:如果给目录设置权限,通常需要配合递归参数(虽然图中没写,但实际常用)才能把里面的文件也改了。
-
-
owner/group(属主/属组)-
含义:把文件或目录的拥有者改成指定的用户和用户组。
-
2. 常见的实战场景举例
为了让你更直观地理解,我模拟几个日常会用到的 file模块任务写法:
场景 A:创建一个 Web 服务器的日志目录
- name: 创建 /var/log/nginx 目录
file:
path: /var/log/nginx
state: directory # 确保它是一个目录
mode: '0755' # 赋予读写执行权限
owner: nginx # 属主是 nginx 用户
group: nginx # 属组是 nginx 组
场景 B:删除一个废弃的临时目录
- name: 删除旧的备份目录
file:
path: /tmp/old_backup
state: absent # 确保它不存在(即删除)
场景 C:创建一个空文件作为标记
- name: 创建初始化完成标志文件
file:
path: /opt/.initialized
state: touch # 创建一个空文件
mode: '0644'
掌握了 file模块,你就拥有了自动化管理服务器文件系统的基础能力,这也是自动化运维的第一步。

这张图详细解释了 Ansible file模块中最核心、也是最容易混淆的参数 —— state。
简单来说,state参数决定了 Ansible 在执行任务时,期望目标达到什么状态。不同的取值对应了不同的 Linux 命令操作。
我把图中提到的几种常见状态翻译成通俗易懂的“人话”和操作对照:
1. state: directory(创建目录)
-
含义:确保目标路径是一个目录。
-
操作:如果不存在,就创建它(包括中间缺少的父目录);如果存在,就检查并更新它的权限等属性。
-
Linux 命令类比:
mkdir -p /path/to/dir
2. state: touch(创建空文件)
-
含义:如果文件不存在,就创建一个空文件;如果文件已存在,就更新它的访问时间和修改时间(类似于
touch命令本身的行为)。 -
操作:常用于初始化标记文件。
-
Linux 命令类比:
touch /path/to/file
3. state: link(创建软链接)
-
含义:创建一个软链接(Symbolic Link),类似于 Windows 的快捷方式。
-
操作:
src是源文件,path(或dest) 是生成的链接文件路径。 -
Linux 命令类比:
ln -s /path/to/src /path/to/dest
4. state: hard(创建硬链接)
-
含义:创建一个硬链接。
-
区别:硬链接直接指向文件的 inode(索引节点),而不是像软链接那样指向路径。这意味着如果源文件被删除了,硬链接依然可以访问数据。
-
Linux 命令类比:
ln /path/to/src /path/to/dest
5. state: absent(删除)
-
含义:确保目标不存在。
-
操作:如果目标是一个文件、目录或链接,统统删掉。如果是目录,会递归删除里面的所有内容。
-
Linux 命令类比:
rm -rf /path/to/target -
注意:如果目标本来就不存在,这个操作算作“成功”,不会报错(Idempotency,幂等性)。
6. state: file(确保是普通文件)
-
含义:确保目标是一个普通文件。
-
操作:如果这个文件不存在,它不会自动创建(除非配合其他模块如
copy或template)。它主要用于修改已存在文件的属性(如权限、属主)。 -
陷阱提示:很多新手会误以为
state: file可以创建文件,其实是不行的。
实战小例子
假设你要在目标服务器上管理 Nginx 的默认页面:
- name: 确保 /var/www/html 目录存在
file:
path: /var/www/html
state: directory
mode: '0755'
- name: 创建一个软链接指向自定义首页
file:
src: /opt/myapp/custom_index.html
dest: /var/www/html/index.html
state: link
- name: 删除默认的 404 页面
file:
path: /var/www/html/404.html
state: absent
理解了 state的这几种状态,你就掌握了 file模块 90% 的用法。

这张图展示了 Ansible 命令行执行后的标准输出(JSON 格式),正好印证了我们刚才聊到的 state=touch的实际效果。
我们可以从这段输出中拆解出几个关键运维信息:
1. 执行概览
-
命令:
ansible all -m file -a "path=/opt/file.1.txt state=touch" -
目标:对
all(所有)定义的主机(192.168.100.11,13,12)执行操作。 -
结果:每台机器后面都显示
CHANGED => { ... },说明 Ansible 成功在目标机器上执行了创建或修改动作。如果是第二次执行同样的命令,这里通常会变成OK,这体现了 Ansible 的幂等性。
2. 返回的 JSON 数据详解
大括号里的 JSON 是模块执行后的详细报告,这里有几个核心字段非常有用:
-
"state": "file"-
这表示 Ansible 确认目标路径现在的实际状态是一个普通文件。这正是
touch指令期望达到的效果。
-
-
"mode": "0644"-
这是 Linux 文件权限的数字表示法。
-
含义:
6(110) 代表所有者(root)可读可写;后面的44(100, 100) 代表组和其他用户只读。这是新建文件最常见的默认安全权限。
-
-
"owner": "root", "group": "root"-
显示文件的所有者和所属组。说明新创建的文件归 root 用户管理。
-
-
"size": 0-
文件大小为 0 字节。这完全符合
touch命令的特性——它只更新时间戳,不写入任何实际内容。
-
3. 实战意义
在实际工作中,如果你写了一个 Playbook 来执行这个任务,这段输出就是你判断“部署是否成功”的直接依据。看到全是绿色的 CHANGED,你就知道三台服务器的 /opt/目录下现在已经齐刷刷地躺着一个空的 file.1.txt了。

这张图是上一轮的补充,重点在于展示了 file模块在命令行(Ad-hoc)中的具体用法,并且引入了三个处理“特殊情况”的高级参数:recurse、src和 force。
这里整理了图片中的核心命令,并结合实战场景为你解析:
1. 核心参数解析
-
recurse: yes(递归)-
场景:当你创建一个多级目录(如
/opt/app/logs)时,通常需要一层层手动创建。加上这个参数,Ansible 会自动帮你把中间缺失的父目录全部建好。 -
类比 Linux 命令:相当于
mkdir -p /opt/app/logs。
-
-
src和force(链接相关)-
场景:这两个参数通常配合使用,专门用于
state=link(软链接)或state=hard(硬链接)。 -
src:告诉 Ansible 链接的“源文件”在哪里。 -
force:强制覆盖。如果目标位置已经存在一个同名文件,通常创建链接会失败。加上force: yes,Ansible 会先把它删掉,再建立链接。
-
2. 四种实战场景对照
图片下半部分的示例代码非常实用,涵盖了日常运维 80% 的文件操作:
场景一:创建目录(支持递归)
# 命令行执行
ansible all -m file -a "path=/opt/dir state=directory"
# 对应的 Playbook 写法
- name: 确保目录存在
file:
path: /opt/dir
state: directory
recurse: yes # 如果没有这一行,/opt/dir 不存在时也会报错,或者需要手动逐级创建
场景二:创建文件(更新时间戳)
# 命令行执行
ansible all -m file -a "path=/opt/dir/file1.txt state=touch"
# 对应的 Playbook 写法
- name: 创建一个空文件或更新时间
file:
path: /opt/dir/file1.txt
state: touch
场景三:创建符号链接(软链接)
# 命令行执行:把 /etc/hosts 链接到 /opt/dir/hosts_link
ansible all -m file -a "src=/etc/hosts dest=/opt/dir/hosts_link state=link"
# 对应的 Playbook 写法
- name: 创建软链接
file:
src: /etc/hosts
dest: /opt/dir/hosts_link
state: link
force: yes # 如果 /opt/dir/hosts_link 已存在,强制覆盖
场景四:删除文件或目录(清理战场)
# 1. 删除目录(递归删除,类似 rm -rf)
ansible all -m file -a "path=/opt/dir state=absent"
# 2. 删除单个文件
ansible all -m file -a "path=/opt/dir/file1.txt state=absent"
# 对应的 Playbook 写法
- name: 清理无用文件
file:
path: /opt/dir
state: absent
💡 学习建议
如果你刚开始学 Ansible,建议先从命令行(Ad-hoc)入手。像图片里那样,直接在终端敲命令测试效果,能让你直观地感受到模块的作用。等熟练了,再把这些命令“翻译”成 YAML 格式的 Playbook 脚本,这样学起来最快!


这张图详细列出了 Ansible user模块的常用参数,这是进行 Linux 系统用户管理的基础。我将这些参数按功能分类,并结合实际运维场景为你解读:
1. 核心身份与状态
-
name(用户名):-
必填项。指定要操作的用户名称,例如
admin。
-
-
state(状态):-
present:确保用户存在(默认)。如果用户不存在则创建,存在则检查属性是否需要修改。 -
absent:确保用户不存在。通常用于删除用户(执行时会移除用户及关联的家目录等)。
-
2. 权限与分组管理(重点)
-
group(主组):-
指定用户的主要组(GID)。通常建议创建用户时同时指定一个同名组(如
name: test, group: test)。
-
-
groups(附加组):-
指定用户的附加组(Supplementary Groups)。多个组用逗号分隔。
-
场景:例如把用户加入
docker组以实现免密运行容器,或者加入wheel组获得 sudo 权限。 -
注意:如果该用户已存在,Ansible 默认不会自动将其从原有附加组中移除,除非配合专门的模块逻辑。
-
-
uid(用户ID):-
指定固定的 UID。在集群环境中保持 UID 一致非常重要,避免因 ID 冲突导致文件权限混乱。
-
3. 环境与登录配置
-
home(家目录):-
指定用户主目录路径。默认通常是
/home/用户名。 -
如果设置为
state: absent,配合remove: yes参数可以连带删除该目录。
-
-
shell(默认 Shell):-
指定用户登录后使用的命令解释器。
-
常见值:
/bin/bash(交互式登录),/sbin/nologin(禁止登录,常用于系统服务账号)。
-
-
comment(描述信息):-
通常填写用户的真实姓名、电话或用途说明,对应 Linux 中的 GECOS 字段。
-
4. 高级功能
-
password(密码):-
注意:这里不能直接写明文密码!必须传入经过加密的字符串(通常是 SHA512 哈希值)。
-
获取方式:可以通过
openssl passwd -6命令生成。
-
-
generate_ssh_key(生成 SSH 密钥):-
设为
yes会自动为用户生成一对 SSH 密钥(用于无密码登录或 API 认证)。 -
常用于自动化创建部署账号,省去手动下发公钥的麻烦。
-
💡 实战小例子:创建一个带权限的运维账号
假设你需要创建一个名为 deploy的用户,要求:
-
UID 固定为
1500。 -
加入
developers组。 -
家目录在
/home/deploy。 -
设置密码(假设已加密为
123456的哈希值)。
对应的 Ansible 命令如下:
ansible all -m user -a "name=deploy uid=1500 group=developers home=/home/deploy password='\$6\$saltsalt\$hashvalue' state=present"
(注:实际使用时请将 $6$saltsalt$hashvalue替换为真实的加密密码字符串)

这张图继续深入讲解了 user模块的高级参数以及 group模块的基础用法,这是进行系统账号精细化管理的核心。
我将图中的知识点拆解为通俗易懂的“人话”版本,方便你记忆:
一、 user模块:高级账号管控
图的上半部分补充了两个平时不太起眼但非常关键的参数,以及一个删除用户的实战命令。
1. 新增关键参数
-
system: yes(设为系统用户)-
含义:创建一个系统后台账号(如 Nginx、MySQL 等服务使用的账号)。
-
特点:这类账号通常没有家目录(或者家目录在
/var/lib下),且 UID 通常小于 1000。最重要的是,它们禁止登录 SSH,安全性极高。
-
-
create_home: no(不创建家目录)-
含义:默认情况下,创建普通用户会自动生成
/home/用户名。如果你设为no,Ansible 就不会建这个文件夹。 -
适用场景:比如你要建一个专门跑定时任务的系统账号,不需要写代码或存文件,就可以省掉这个目录。
-
2. 删除用户的“核弹”选项
图中高亮的删除命令里包含了一个灵魂参数:
bash
ansible all -m user -a "name=testuser state=absent remove=yes"
-
state=absent:表示我要把这个用户删掉。 -
remove=yes:这是重点!-
如果写成
no,Ansible 只会把/etc/passwd里的账号删掉,但/home/testuser这个家目录还会留在硬盘上(变成孤儿文件)。 -
如果写成
yes(默认通常是 no),Ansible 会像userdel -r一样,连锅端,把家目录和个人邮件池一起彻底删干净。这在清理离职员工数据时非常重要。
-
二、 group模块:批量管人神器
图的下方引出了 group模块。在实际运维中,给每个人单独配权限太累,我们通常通过“拉群”来管理权限。
-
为什么要用组?
比如你想让 10 个运维都能使用
sudo命令。你不需要一个个改他们的账号,只需要把这 10 个人都加到wheel组里即可。 -
核心参数速览:
-
name:群名(比如叫developers)。 -
gid:群的 ID 号。在大规模集群或挂载共享存储时,固定 GID 可以防止不同服务器间出现权限错乱。 -
system:同样,设为yes就是创建系统内部使用的组(如docker组)。
-
💡 场景串联:搭一个安全的 Web 运行环境
假设你要搭建一个 Nginx 服务,要求最精简的安全配置,你可以把上面学的串起来:
-
建个系统组:
ansible all -m group -a "name=nginx gid=1010 system=yes"
-
建个系统账号(不许登录,没有家目录):
ansible all -m user -a "name=nginx uid=1010 group=nginx system=yes create_home=no shell=/sbin/nologin"
-
最后如果不用了,彻底销毁:
ansible all -m user -a "name=nginx state=absent remove=yes"
这样一套组合拳下来,账号干干净净,不会留下垃圾文件。

这张图展示了 group模块的具体用法,这是管理 Linux 权限的基石。结合之前的 user模块内容,这里进一步讲解了如何对“用户组”进行精细控制。
我将图中的 5 个示例提炼为三大实战场景,方便你理解和记忆:
场景一:基础建群与管理(增删改)
-
建群(默认模式)
-
命令:
ansible all -m group -a "name=developers" -
解读:最简单的操作,创建一个名为
developers的普通用户组。
-
-
解散群组
-
命令:
ansible old_servers -m group -a "name=legacy state=absent" -
解读:对应之前的
user模块,state=absent就是确保这个组不存在,如果存在就删掉。
-
场景二:严格管控模式(企业级规范)
在企业环境中,为了保证多台服务器之间的权限一致,我们通常要求 UID 和 GID 必须是固定的数字。
-
指定 GID 建群
-
命令:
ansible webservers -m group -a "name=deploy gid=1042" -
解读:强制规定这个组的 ID 必须是
1042。如果不指定,Linux 通常会自动分配一个随机的大数字(如 1005)。这会导致如果你把文件传到另一台服务器,可能因为组 ID 不同而无法访问。
-
-
修改现有群的 GID
-
命令:
ansible app_servers -m group -a "name=appusers gid=1500" -
解读:这是一个修改操作。如果
appusers组原本的 GID 是 1000,执行这条命令后,Ansible 会将其 GID 修改为 1500。
-
场景三:创建系统内部组
-
命令:
ansible db_servers -m group -a "name=dbadmin system=yes" -
解读:
-
system=yes表示创建的是系统后台组(通常用于数据库、Nginx 等服务)。 -
这类组的 GID 通常比较小(小于 1000),且一般不分配给普通人类用户使用。
-
💡 串联实战:从“建组”到“拉人”
结合你之前学的 user模块,一个完整的权限配置流程通常是这样的:
-
第一步:建组(定权限容器)
ansible all -m group -a "name=devops gid=2000" -
第二步:建人并加入组(分配身份)
ansible all -m user -a "name=alice group=devops groups=devops"(这里假设 alice 是主组是 devops,同时也属于 devops 附加组)
这样,alice这个用户就成功加入了 devops这个权限圈子里了。

这张图介绍了 Ansible 中极其常用的 copy模块,它是实现“将本地配置文件推送到远程服务器”的核心工具。
这里整理了图片中的核心参数,并结合实战场景为你解析其强大之处:
1. 核心参数解析
-
src(源) vsdest(目标)-
src:你在 Ansible 控制机上(也就是你操作的电脑)的本地文件路径。 -
dest:文件要拷贝到远程服务器上的目标路径。 -
场景:比如你想把本地的 Nginx 配置文件推送到服务器。
-
src=/home/admin/nginx.conf -
dest=/etc/nginx/nginx.conf
-
-
-
content(直接写入内容)-
亮点功能:不需要先在本地建一个文件,可以直接把一段文本“塞”进远程文件里。
-
场景:快速修改某个配置文件的一行参数,或者生成一个简单的脚本。
-
示例:
content="Hello World\n"会把这两行字直接写入到dest指定的文件里。
-
-
owner/group/mode(权限三件套)-
文件传过去后,默认权限可能是 root 读写,其他人不许看。
-
你可以通过这三个参数瞬间修改:
-
owner=www-data:把所有者改成 Web 服务账号。 -
group=www-data:把所属组改成 Web 组。 -
mode=0644:设置标准读写权限(rw-r--r--)。
-
-
-
backup=yes(贴心备份)-
运维救星:如果你要覆盖一个正在运行的配置文件(比如改 Nginx 配置),直接覆盖风险很大。
-
加上这个参数,Ansible 会在覆盖前,自动把旧文件重命名备份(通常是加个时间戳),万一新配置导致服务挂了,你可以随时回滚。
-
-
validate(更新前验证)-
高级防坑:在真正覆盖文件前,先用这个命令检查一下新文件语法对不对。
-
场景:配置 Apache 或 Nginx 时,语法写错了会导致服务重启失败。
-
示例:图中的
"/usr/sbin/apachectl -t %s"。%s是占位符,代表即将写入的新文件路径。Ansible 会先运行这个检查命令,通过了才真正写入。
-
2. 实战小例子:推送 Nginx 配置并重启
假设你写了一个 Nginx 配置,想推送到服务器,但如果写错了就不让生效:
对应的 Ansible 命令如下:
ansible webservers -m copy -a "src=/local/path/nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644 validate='/usr/sbin/nginx -t %s' backup=yes"
这条命令做了四件事:
-
把本地的
nginx.conf发过去。 -
设置好 root 权限。
-
先检查语法,错了就不覆盖。
-
如果对了,覆盖原文件,并把旧文件自动备份。
这张图继续深入讲解了 copy模块的进阶用法,特别是解决了“文件来源”和“安全校验”这两个运维痛点。
我将图中的 7 个示例提炼为三大实战场景,帮你理解它们在实际工作中的应用:
场景一:灵活掌控“文件来源”
以前你可能觉得 copy只能从本地电脑往服务器传文件,其实它更灵活:
-
1. 常规推送(本地 -> 远程)
-
命令:
src=/tmp/app.conf dest=/etc/app.conf -
解读:最基础的用法,把控制机上的文件推过去。
-
-
5 & 6. 远程主机内部“搬运”(远程 -> 远程)
-
命令:
ansible hostA -m copy -a "src=/path/on/hostA/... dest=... remote_src=yes" -
核心参数:
remote_src=yes -
解读:这招非常实用。它告诉 Ansible,源文件(src)已经在目标主机上了。
-
应用场景:比如你想把服务器 A 上的一个日志文件复制到服务器 B 上。或者在一台机器上,把配置文件从
/tmp备份到/opt。这就实现了跨主机复制或在单台主机内移动文件,而不需要经过你的本地电脑中转。
-
场景二:安全部署与回滚(运维必杀技)
配置文件推错了可能导致服务崩溃,所以这两个参数至关重要:
-
4. 历史留痕(备份机制)
-
命令:
backup=yes -
解读:在覆盖任何文件之前,Ansible 会自动把旧文件重命名(加上时间戳)保存下来。如果新配置导致服务挂了,你可以秒速找回旧版本。
-
-
7. 防呆校验(语法检查)
-
命令:
validate="/usr/sbin/nginx -t %s" -
核心参数:
validate -
解读:这是高级运维的“安全带”。
-
原理:
%s是一个占位符,代表即将写入的新文件路径。在执行覆盖操作前,Ansible 会先运行nginx -t命令来检查这个新配置文件的语法是否正确。 -
结果:只有当验证通过时,才会真正写入文件;如果报错,Ansible 会停止操作并报错,从而避免了因配置错误导致的服务宕机。
-
场景三:极简配置(内容直写)
-
3. 直接生成配置
-
命令:
content='DB_HOST=127.0.0.1' dest=/etc/db.conf -
解读:不需要在本地新建一个文件,直接在命令行里把文本“打印”到远程服务器的文件里。非常适合写入一些简单的环境变量或动态生成的配置片段。
-
💡 特别关注:易错点提醒
在图中间的“范例(2)”中:
ansible all -m copy -a "src=/tmp/script.sh dest=/usr/local/bin/script.sh owner=root group=r..."
注意看图中小灰条遮挡的部分,大概率是 group=root。
因为 Linux 文件权限讲究“属主(owner)”和“属组(group)”配套,通常写权限时都会把这两者一起设定,以确保脚本能以正确的身份运行。

这张图介绍了 Ansible 中用于管理软件包的 yum模块(在 CentOS/RHEL 系统中),它是自动化安装和更新软件的核心工具。
我将图中的参数和示例转化为通俗易懂的“软件管家”视角,帮你快速掌握其用法:
1. 核心参数速览(“管软件”的指令)
-
name(包名):-
含义:你要操作的软件名字。
-
扩展用法:除了单个包名(如
httpd),还可以是@开头的软件组(如@development表示开发工具组),甚至是具体的 URL(直接从网上下载安装)。
-
-
state(状态控制):-
present:确保软件已安装(如果没装就装上,如果已装就不做操作)。 -
latest:确保软件是最新版(如果没装就装,如果装了但旧,就升级到最新)。 -
absent:确保软件未安装(卸载)。
-
-
enablerepo/disablerepo(仓库开关):-
含义:临时启用或禁用某个软件源仓库。
-
场景:有些包在默认仓库里没有,但在 EPEL 仓库里有。你就可以临时开启 EPEL 来装,装完再关掉,不影响系统全局配置。
-
-
update_cache(更新缓存):-
含义:相当于执行
yum makecache。 -
建议:如果你刚修改了仓库配置,或者很久没更新源了,把这个设为
yes,否则 Ansible 可能找不到最新的包。
-
-
list(查询模式):-
含义:这是一个“只读”操作。Ansible 会去查这个包的信息(比如看看是不是已经安装了),但绝对不会去安装或卸载它。常用于判断或调试。
-
-
security(安全更新):-
含义:设为
yes时,Ansible 会专门只打带有“安全标记”的补丁,忽略那些仅仅是增加功能(非安全修复)的普通更新。这在生产环境中非常重要,避免非必要更新引入新 Bug。
-
-
download_only(仅下载):-
含义:包只下载到本地缓存,不执行安装。常用于准备离线环境的机器,先把包下好备用。
-
2. 实战命令解析
图中给出了两个最基础的用法:
-
示例 (1):安装指定软件
bash
ansible webservers -m yum -a "name=httpd state=present"
-
解读:在
webservers这群机器上,检查httpd(Apache 网页服务器)有没有。如果没有,就自动安装上;如果有了,就保持原样不动。
-
-
示例 (2):安装最新版并刷新源
bash
ansible all -m yum -a "name=nginx state=latest"
-
解读:在所有机器上,把
nginx升级到官方仓库里的绝对最新版本。 -
小贴士:虽然图中省略了
update_cache=yes,但在实际生产环境中,为了保险起见,通常建议加上这个参数,以确保能获取到最新的软件列表。
-
💡 举一反三:进阶场景
假设你需要给生产服务器打安全补丁,但不能乱升级其他东西,最稳妥的命令应该是这样的:
bash
ansible production -m yum -a "name=* state=latest update_cache=yes security=yes"
这条命令的意思是:“在 production 组机器上,刷新软件源,并且只把所有带有安全漏洞的包升级到最新,其他的保持不动。”

这张图继续深入讲解了 yum模块的高级用法,覆盖了从批量操作到特定场景(如离线安装、安全更新)的各种需求。
我将图中的 10 个示例提炼为 五大实战场景,帮你把这些命令转化为实际的运维能力:
场景一:批量操作与“乾坤大挪移”
-
1. 批量安装多个软件(开发环境标配)
-
命令:
name=['vim-enhanced','git','tmux'] -
解读:以前你可能要写三行命令,现在一行搞定。这非常适合配置开发环境,一键装好程序员需要的各种效率工具。
-
-
10. 从 URL 安装 RPM(公网隔离场景)
-
命令:
name=https://example.com/packages/custom.rpm -
解读:这是运维救急的“核武器”。当服务器在内网(无法连接外网),但急需安装某个特定版本的软件时,你可以先用本地下载好的
.rpm包,或者把包放在内网 HTTP 服务器上,直接通过 URL 让 Ansible 拉取并安装。
-
场景二:精细化的仓库控制
-
5. 临时借用仓库(特定包安装)
-
命令:
name=htop enablerepo=epel -
解读:
htop通常不在默认的 CentOS 源里,而在 EPEL (Extra Packages for Enterprise Linux) 源里。 -
这个参数的妙处在于临时性。它告诉 Ansible:“这次安装 htop 的时候,暂时把 EPEL 源打开,装完之后系统还是保持原来的源配置,不会永久修改系统级的 repo 文件。”这保证了配置的纯净。
-
场景三:系统更新策略(生产环境必看)
-
6. 全量更新 (
state=latest)-
命令:
name=* state=latest -
解读:
*是通配符,代表所有已安装的包。这通常用于大版本升级或者周度例行维护。
-
-
7. 仅安全更新 (
security=yes)-
命令:
security=yes state=latest -
解读:这是生产环境的黄金法则。内核或 OpenSSL 爆出高危漏洞时,你不需要把所有组件都升级(可能会引入不兼容的 Bug),只需打安全补丁。这个参数能让 Ansible 精准定位并升级带有安全标记的包。
-
场景四:高级特性与特殊需求
-
8. 安装“包组” (
@符号)-
命令:
name='@development' -
解读:Linux 有些软件是成双成对出现的(比如 Web 服务器需要 httpd + mod_ssl)。系统预定义了一个“开发工具组”。
-
加上
@符号,相当于执行yum groupinstall "Development Tools",一次性装好几十个相关的包。
-
-
9. 仅下载不安装 (
download_only=yes)-
命令:
name=ansible download_only=yes -
解读:用于离线环境的准备。Ansible 会去仓库把
ansible这个包及其依赖全部下载到本地缓存目录(通常是/var/cache/yum/...),但不会执行安装动作。随后你可以把这些 rpm 包拷贝到 U 盘,去内网服务器上手动安装。
-
场景五:清理与回滚
-
4. 卸载软件 (
state=absent)-
命令:
name=telnet state=absent -
解读:安全加固的第一步。Telnet 是不加密的明文传输协议,非常危险。在配置好 SSH 后,通常用这个命令把 Telnet 彻底踢出服务器。
-
💡 实战模拟:打造一台“标准开发机”
假设你要把一台新申请的 CentOS 服务器配置成标准的开发测试机,你可以组合使用上面的命令:
-
第一步:装基础工具箱
ansible new_dev -m yum -a "name=['vim','git','curl','wget'] state=present" -
第二步:装开发组套件(编译器、make 等)
ansible new_dev -m yum -a "name='@development' state=present" -
第三步:装 EPEL 源里的监控工具 htop
ansible new_dev -m yum -a "name=htop enablerepo=epel state=present" -
第四步:卸载危险的 Telnet
ansible new_dev -m yum -a "name=telnet state=absent"
这一套组合拳打下来,服务器的初始安全基线和开发环境就搭建好了。
posted on 2026-05-18 21:18 luzhouxiaoshuai 阅读(88) 评论(0) 收藏 举报
浙公网安备 33010602011771号