在当今 DevOps 和 IT 自动化这个瞬息万变的领域,Ansible 作为配置管理、应用部署和任务编排的巨头,一直是我们不可或缺的得力助手。如果你是一名经验丰富的系统管理员,或者正在探索基础设施即代码的奥秘,你一定对 Ansible 的强大功能深有体会。然而,随着 RHEL 10 等企业级 Linux 发行版的演进,Ansible 的打包方式和分发策略发生了重大转变。
这不仅是一个简单的版本更新,更是一场关于如何构建、部署和维护自动化工作流的根本性变革。以前,我们可能习惯于直接 yum install ansible 就能获得所有功能,但在 RHEL 10 的世界里,情况变得稍微复杂了一些。在这篇文章中,我们将以第一人称的视角,像老朋友交流一样,深入探讨 Ansible 和 Ansible Core 之间的核心区别,解析这一变化背后的技术逻辑,并通过大量的实战代码示例,帮助你平稳过渡到新的自动化范式。
目录
核心术语全景:构建我们的自动化词汇表
在深入细节之前,让我们先花点时间统一一下术语。理解这些概念是掌握后续内容的基础,毕竟,精准的术语是高效沟通的桥梁。
1. 什么是 Ansible?
当我们谈论 Ansible 时,我们通常指的是那个庞大的、功能齐全的自动化平台。它是开源自动化的代名词,旨在简化云置备、配置管理、应用部署和 intra-service orchestration 等复杂的 IT 运维工作。Ansible 采用了一种极其优雅的基于 YAML 的声明式语言。这意味着你不需要成为一名硬核程序员,只需要描述你希望系统处于什么样的状态,Ansible 就会像一位尽职的管家,帮你搞定剩下的“怎么做”。
它的核心杀手锏在于 无代理架构。这一点怎么强调都不为过——你不需要在每一台被管理的服务器上安装繁琐的客户端软件。Ansible 通过 SSH(针对类 Unix 系统)或 WinRM(针对 Windows)推送到目标节点,这种设计不仅极大地降低了安全风险,还赋予了它无与伦比的可扩展性。
2. 什么是 Ansible Core?
Ansible Core 则是 Ansible 这台庞大机器的心脏和引擎。它是一个更加精简、专注于执行核心逻辑的软件包。它包含了运行 Playbook、管理清单以及执行自动化任务所需的最小化组件。
过去,当你安装“Ansible”时,你得到的是 Core 加上一大堆预装的社区集合和模块。而现在,尤其是随着 Red Hat 策略的调整,Ansible Core 更多地被剥离出来,作为纯粹的执行环境存在。当我们现在提到“Ansible Core”,我们通常指的是通过 RHEL AppStream 仓库安装的那个 ansible-core 软件包,它不包含那些花哨的额外扩展,只有赤裸裸的、强大的执行能力。
3. 构建块:Modules(模块)
模块是 Ansible 任务的原子单位。它们是独立的代码片段,真正地在目标节点上执行“脏活累累”。无论是安装软件包(yum/apt)、管理 systemd 服务、操作文件,还是处理复杂的云资源供应,都是模块在工作。
4. 指挥官:Playbook(剧本)
Playbook 是我们的指挥乐谱。它是一个或多个 Play 的集合,用 YAML 格式编写。在 Playbook 中,我们定义了一系列的任务,Ansible 会按照顺序在指定的目标主机上执行这些任务。它通过一种即插即用的方法,让我们能够把复杂的运维流程抽象成可复用的代码。
5. 目标清单:Inventory(清单)
Inventory 本质上是一个数据库,告诉 Ansible 它需要管理哪些机器。这可以是一个简单的 INI 文本文件,也可以是动态生成的脚本,甚至是指向云资源的动态列表。它是 Playbook 执行任务的作用域。
6. 扩展利器:Plugins(插件)
如果说模块是干活的工人,插件就是给他们提供工具和后勤保障的队伍。插件扩展了 Ansible 的核心功能,比如改变日志输出方式、处理变量注入、或者通过 Callback 插件在控制台以彩色方式显示执行结果。
7. 企业大脑:Ansible Tower (AWP)
虽然今天的主角是 Core,但不能不提 Tower(现在的 Red Hat Ansible Automation Platform)。它是构建在 Ansible Core 之上的企业级解决方案。如果你只是在个人电脑上跑脚本,Core 足够了;但如果你在一个拥有数千台服务器的大型团队中工作,Tower 提供的基于 Web 的 UI、RBAC(基于角色的访问控制)、CI/CD 集成和集中式日志记录则是必须的。
—
RHEL 10 及相关发行版的剧变
现在,让我们把目光投向引发这次讨论的导火索:RHEL 10(以及 RHEL 9 的某些更新)。
在过去(比如 RHEL 7 或 8 早期),我们可以轻松地从 EPEL 仓库或者默认的 AppStream 中直接安装 ansible 软件包。这个包包含了成千上万个模块和集合,开箱即用,非常方便。我们把它称为“通用安装包”。
但是,在 RHEL 10 中,情况发生了根本性的逆转:
- INLINECODEf77a4c6b 包的消失:那个包含了所有社区扩展的庞大 INLINECODEa44b8698 软件包,不再包含在默认仓库中,EPEL 也可能不再提供它。
- INLINECODE847e1944 的崛起:现在,AppStream 仓库中仅提供了 INLINECODE3db6b551。
这意味着什么?这意味着如果你只是简单地执行 INLINECODEc503d25e,你只会得到核心引擎。如果你试图运行一个使用了 INLINECODE2c178d60 或 amazon.aws 扩展模块的旧 Playbook,它会直接报错,提示找不到模块。
这一变化导致那些以前依赖于完整 ansible 软件包可用性的自动化管道和 Kickstart 脚本出现了问题。现在,我们需要改变思维模式:安装 Core,然后手动构建我们的 Collection 层。
—
深度对比:Ansible vs Ansible Core
为了让我们在视觉上更直观地理解,让我们通过下面的表格来看看“旧时代的完全体 Ansible”和“新时代的 Ansible Core”之间的主要差异。这不仅仅是功能上的对比,更是运维策略的对比。
Ansible (传统完整包)
:—
完整的自动化生态系统,旨在开箱即用
包含 Core、Tower(部分组件)、Galaxy CLI 以及 大量 预装的社区集合和插件
EPEL 或第三方仓库
默认支持几乎所有你能想到的模块
ansible-galaxy 安装特定的集合 快速上手、学习、小规模混合环境
较慢,跟随大版本发布
为什么会有这种分歧?
你可能会问,Red Hat 为什么要搞这么复杂?其实这是一种解耦的智慧。
将 Core 和 Collections 分离,使得核心引擎可以保持极其稳定,不受成千上万个社区模块频繁变更的影响。对于我们开发者来说,这意味着我们可以像搭积木一样,只安装项目真正需要的集合,从而构建出更轻量、更安全的自动化镜像——这在容器化部署(如 OpenShift/Kubernetes)中尤为重要。
—
实战演练:代码示例与最佳实践
光说不练假把式。让我们通过几个实际的代码示例来看看这如何影响我们的日常工作。
场景 1:安装与初始化(从 Ansible Core 开始)
在 RHEL 10 上,我们的第一步不再是 yum install ansible。让我们来看看新的工作流。
首先,安装 Core:
# 在 RHEL 10 系统上,我们只需要核心引擎
sudo dnf install ansible-core -y
# 验证安装,注意版本号通常是 2.15+
ansible --version
你会看到输出显示 INLINECODEc5860f6e 的版本。这时候,如果你想尝试使用 INLINECODE4a0e9242 模块(这是内置的),它还能工作:
# test_core.yml
---
- name: 测试 Ansible Core 是否工作
hosts: localhost
connection: local
tasks:
- name: 打印一条消息
ansible.builtin.debug:
msg: "恭喜!Ansible Core 引擎运行正常。"
ansible-playbook test_core.yml
但是,假设你突然需要管理 Docker 容器,并且编写了如下任务:
- name: 启动一个 Nginx 容器
community.docker.docker_container:
name: my_nginx
image: nginx:latest
state: started
报错时刻! 运行这个 Playbook 时,你会遇到 INLINECODEa6704673。因为 INLINECODE48764d8a 没有自带 Docker 模块。
场景 2:构建你的集合环境
为了解决上述问题,我们需要引入 Ansible Builder 或手动管理集合。这是“新 Ansible”的核心工作流。
我们可以创建一个 requirements.yml 文件来明确声明依赖:
# collections/requirements.yml
---
# 指定我们需要从 Galaxy 下载的扩展集合
collections:
# 社区通用集合
- name: community.general
version: ">=5.0.0"
# Docker 相关集合
- name: community.docker
version: ">=3.0.0"
然后,我们可以安装这些依赖到用户的本地目录或全局目录:
# 安装依赖到当前目录下(推荐用于隔离环境)
ansible-galaxy collection install -r collections/requirements.yml -p ./collections
最佳实践提示:在生产环境中,我们强烈建议不要把集合安装到系统全局路径(INLINECODE92cfe7a1)。相反,你应该使用项目本地的 INLINECODE8e0602e2 文件夹,并配置 ansible.cfg 来指向它。
在项目根目录下创建一个 ansible.cfg:
# ansible.cfg
[defaults]
# 告诉 Ansible 在哪里寻找我们刚才下载的集合
collections_path = ./collections
# 或者禁用哈希检查以提高加载速度(仅限可信环境)
gathering = smart
现在,再次运行之前的 Docker Playbook,它就能完美工作了。这就是从“开箱即用”到“按需构建”的转变。
场景 3:使用 Execution Environment (EE) 的企业级方案
如果你在做大规模自动化,手动安装集合是很麻烦的。RHEL 10 和 Ansible Automation Platform 引入了 Execution Environment (EE) 的概念——本质上是打包了所有依赖的容器镜像。
虽然构建 EE 通常需要 INLINECODEe8462cc3,但我们可以简单理解为:我们在一个 Podman 容器里预先装好了 INLINECODE2d55e0a4 和所有需要的 collections,然后直接在这个容器里运行 Playbook。
# 这是一个简化的概念性命令,实际构建需要定义 execution-environment.yml
# podman run -v $(pwd):/workspace:Z registry.redhat.io/ansible-automation-platform-ee/ee-minimal-rhel8:latest ansible-playbook /workspace/site.yml
这确保了:开发者的环境能跑,生产环境也能跑,因为它们运行在同一个容器镜像中。
—
常见错误与解决方案
在这个迁移过程中,你肯定会遇到一些坑。让我们看看如何解决它们。
1. 模块名称冲突与 FQCN
在旧版 Ansible 中,我们习惯直接写 yum: name=vim state=present。在混合使用 Core 和不同版本集合时,这可能会导致歧义。
解决方案:始终使用 Fully Qualified Collection Name (FQCN)。
# 不推荐(依赖隐式路径)
- yum:
name: vim
state: present
# 推荐(RHEL 10 时代的最佳实践)
- ansible.builtin.yum:
name: vim
state: present
2. Python 解释器问题
RHEL 9 和 10 默认使用 Python 3.9 或更高版本。有时候,INLINECODE6a9d8431 可能会错误地尝试使用 INLINECODEdc34e817,导致“module not found”错误。
解决方案:在 Inventory 文件中显式指明解释器。
# inventory.ini
[webservers]
web1.example.com
web2.example.com
[webservers:vars]
# 强制使用系统默认的 Python 3
ansible_python_interpreter=/usr/bin/python3
3. 缺少 ansible-test 或开发工具
如果你习惯编写自己的模块,ansible-core 包里并不包含测试工具。
解决方案:你需要通过 pip 安装开发所需的包:pip install ansible-core ansible-dev。
—
性能优化与未来展望
使用 Ansible Core 并结合精简的集合,实际上能带来性能上的提升。
- 启动速度:由于不需要加载成千上万个用不到的模块,INLINECODE2f84c823 的启动速度比传统的 INLINECODE7a15a0a7 包要快得多。
- 内存占用:控制节点的内存占用显著降低,因为模块列表更短了。
- 安全性:因为我们可以严格控制哪些集合被安装进系统,减少了潜在恶意代码进入基础设施的机会。
结语:拥抱变化,构建未来
从单一的 INLINECODEba4b1dca 包向 INLINECODE0e26dffc + collections 的转变,不仅仅是 RHEL 10 的一个小插曲,而是自动化技术走向成熟的必经之路。它要求我们——作为架构师和开发者——从“消费者”转变为“构建者”。我们需要明确声明我们的依赖,构建我们的执行环境,并理解每一行代码背后的出处。
虽然短期内这增加了学习曲线,但长远来看,它赋予了我们更强的控制力、更清晰的依赖管理和更高效的 CI/CD 流程。当你下次在 RHEL 10 上初始化一个新的自动化项目时,请记住:从 Core 开始,按需添加,利用 FQCN,保持环境轻量。这才是通往现代 DevOps 的大道。
现在,打开你的终端,尝试安装 ansible-core,编写你的第一个基于集合的 Playbook 吧!