第 7 章 · 03 Ansible配置管理与最佳实践


文档摘要

第 7 章 · 03 Ansible配置管理与最佳实践 Terraform 把资源"造"出来,Ansible 把机器"配"好——两者分工不同、哲学相反:Terraform 声明式管理期望状态,Ansible 过程式描述执行步骤;Terraform 无代理但跟踪 state,Ansible 无代理且不保存状态。本节讲透 Ansible 的六大组件、playbook 写法、幂等性、变量优先级与执行控制。

第 7 章 · 03 Ansible配置管理与最佳实践

Terraform 把资源"造"出来,Ansible 把机器"配"好——两者分工不同、哲学相反:Terraform 声明式管理期望状态,Ansible 过程式描述执行步骤;Terraform 无代理但跟踪 state,Ansible 无代理且不保存状态。本节讲透 Ansible 的六大组件、playbook 写法、幂等性、变量优先级与执行控制。

学习目标

  • 理解 Ansible 无代理架构与"过程式 + 可变基础设施"的定位
  • 说出 task/module/inventory/play/playbook/role 六组件的关系
  • 会写条件、循环、模板的 playbook
  • 理解幂等性并掌握实现手段
  • 掌握变量优先级与 forks/serial/throttle 的执行控制

一、无代理架构与定位

Ansible 的核心特性是 Agentless(无代理):目标机器上不需要安装任何代理,运行要求极简——Python + SSH。默认是 push 模式(控制端推送到目标机),也支持 pull 模式(ansible-pull 从 Git 拉取后本地执行)。

定位上 Ansible 是配置管理工具而非供给工具,遵循可变基础设施(mutable)范式——直接修改组件配置,缺点是"配置漂移"(各组件因不同原因到达不同状态)。风格是过程式(procedural)——描述执行步骤而非期望终态。与 Terraform 的差异要点:

Ansible 默认不保存状态——任务创建 5 台实例再执行会再建 5 台(除非额外检查或显式命名);Terraform 会对照 state 只补齐差额。因此供给类需求倾向 Terraform,Ansible 负责其上的配置。

二、六大组件

组件 定义
Task 对某个特定模块的一次调用
Module Ansible 执行的最小代码单元(按 database/file/network 等分类)
Inventory 定义任务执行的主机/主机组(INI 或 YAML 格式)
Play 在给定主机上执行的一个或多个任务
Playbook 一个或多个 play(可针对相同或不同主机)
Role 按功能分组 variables/defaults/files/templates/handlers/tasks/meta 以便复用

Inventory 示例

192.168.1.2 192.168.1.3 [web_servers] 190.40.2.20 190.40.2.21

动态 Inventory:从云厂商/CMDB 等外部源追踪主机——当主机被自动创建/销毁、无法手动跟踪时必须使用。

典型 playbook(所有主机上若存在某文件则安装两个包):

--- - hosts: all vars: mario_file: /tmp/mario package_list: - 'zlib' - 'vim' tasks: - name: Check for mario file stat: path: "{{ mario_file }}" register: mario_f - name: Install zlib and vim if mario file exists become: "yes" package: name: "{{ item }}" state: present with_items: "{{ package_list }}" when: mario_f.stat.exists

这个例子同时示范了四个高频模式:stat + register 检查状态、when 条件、with_items 循环、become 提权。

三、常用模块

模块 用途 要点
package 跨发行版包管理 state: present/absent/latest;优先于直接调 apt/yum
command/shell 执行命令 通用但不可幂等;能用专用模块就别用
copy 复制文件 源/目标
template 渲染 Jinja2 模板 {{ ansible_hostname }} 等变量
service/systemd 服务管理 state: started + enabled: yes
file 文件/目录/链接 权限、目录创建、软链
stat 获取文件状态 常配 register + when
assert 断言 that: 条件校验
debug 打印信息 msg:
lineinfile 按行编辑 regexp: + line:,配 with_items 批量替换

template 示例(向非 controllers 主机部署系统信息文件):

- name: Deploy /tmp/system_info file hosts: all:!controllers tasks: - name: Deploy /tmp/system_info template: src: system_info.j2 dest: /tmp/system_info

模板内容:I'm {{ ansible_hostname }} and my operating system is {{ ansible_distribution }}。注意 hosts: all:!controllers 的含义是"除 controllers 组外的所有主机"。

四、幂等性:重复执行结果一致

幂等性:同一 playbook 重复执行结果一致,不会重复执行已生效的操作(如 package state: present 已安装则跳过)。Ansible 默认不保存状态,幂等靠任务写法保证:

  • 用专用模块而非 shell/command(专用模块自带状态判断);
  • 用 state 参数(present/absent/latest)声明期望;
  • 用 when 条件 + register 先检查再执行。

Molecule 测试中的 "idempotence test failed" 即第二次运行仍有 changed——说明任务写法不幂等(如无条件重启服务),必须排查。幂等性是配置管理工具可靠性的生命线:没有它,CI 无法安全地反复运行同一剧本。

五、变量优先级

变量优先级(从低到高,后者胜出)是高频考点,记住两头即可:

role defaults 最弱,extra vars(-e 参数)永远最高。中间链条大致是:inventory 组变量 → host vars/host_vars → host facts → play vars → vars_prompt → vars_files → role vars → task vars → set_facts/registered → role params → include params → extra vars。

经典考题:role defaults(mario) / extra vars(toad) / host facts(luigi) / inventory(browser) 同时定义同一变量 → 结果是 extra vars 的 toad。

常用变量技巧:默认值 {{ package_name|default('zlib') }};可选参数 {{ use_var|default(omit) }}(omit 让参数不传给模块);三目 {{ (x == 1) | ternary("one", "two") }};类型转换 | bool;调试 | type_debug

一个高频坑:gather_facts: 'no' 时使用 {{ ansible_hostname }} 会失败——facts 是 gather 阶段采集的主机信息,关掉就没有。

六、执行策略:forks、serial、throttle

三个控制并行度的概念经常混淆:

forks:全局并行 worker 数(默认 5),即同一任务最多同时在多少台主机上执行。

serial:按 N 台一批跑完整个 play 再下一批(8 台主机 serial: 4 分两批)——滚动更新场景(先更 1 台验证再继续)。

throttle:限制单个任务的并发数(≤ forks/serial),适合 CPU 密集或限流 API 的任务(如 throttle: 1 逐个执行)。

- hosts: webservers serial: 1 tasks: - name: ...

执行策略(Strategy):默认 Linear——每个任务在所有主机上跑完才进入下一个任务;Free——每台主机尽快跑完整个 play;Debug——交互式。

七、测试与最佳实践

测试手段:ansible-playbook --syntax-check(语法)、--check(演练模式,不实际执行)、Molecule(完整的测试框架:收敛 + 幂等 + 验证,支持多平台矩阵)。

最佳实践清单:能用专用模块就不用 shell/command;playbook 命名可读的 name;vars 与 playbook 分离(group_vars/host_vars);敏感数据用 Ansible Vault 加密;优先 roles 组织复用;关注幂等性测试结果。

Collections(集合):打包分发模块、角色、插件与文档的结构化方式——模块化可复用、简化第三方模块管理、利于版本控制与依赖管理。

小结

本章完成了"基础设施即代码"的双工具闭环:Terraform 以 state 为中心管理资源供给,Ansible 以任务为中心管理机器配置;一个声明式、一个过程式,一个管"造"、一个管"配"。生产实践的标准组合是 Terraform 管云资源 + Ansible 管实例配置 + Git 管两者的代码。但代码本身如何从提交走到生产?——这正是下一章 CI/CD 与 GitOps 要回答的。

下一节预告

第 8 章《CI/CD 与 GitOps》将讲解持续集成/持续交付/持续部署的三级阶梯、Jenkins 与 GitHub Actions 的流水线要素,以及 ArgoCD 的 GitOps 拉取式部署模型。


发布者: 作者: 灏天文库 转发
评论区 (0)
U