6924 字
35 分钟
Ansible 自动化运维(1):核心概念、环境部署与常用模块全解析

Ansible 自动化运维入门(一):核心概念、环境部署与常用模块全解析#

在云计算与微服务大行其道的今天,手动管理成百上千台服务器已成为过去式。作为自动化运维领域的“当红炸子鸡”,Ansible 以其极其简单的入门门槛和强大的功能,成为了运维工程师的必备技能。本文将带你从零开始,揭开 Ansible 的神秘面纱。

一、开篇:为什么运维一定要学 Ansible#

1.1 传统批量运维的痛点#

在没有自动化工具的年代,运维工作往往伴随着以下噩梦:

  • 人工逐台登录:效率极低,且在重复劳动中极易产生人为失误。
  • 脚本散乱:虽然可以使用 Shell 脚本批量执行,但缺乏标准化,逻辑复杂且排错成本极高。
  • 状态难统一:很难保证集群中所有服务器的配置完全一致。

1.2 Ansible 核心优势与定位#

Ansible 的出现完美解决了上述问题,其核心优势体现在:

  • 无 Agent 架构:这是它最大的特点。被控端无需安装任何额外服务,只需开启 SSH 并安装 Python 即可。
  • 声明式语法:你只需描述“目标状态”,Ansible 会自动判断是否需要执行操作。
  • 天然幂等性:无论执行多少次,最终结果都是一致的,不会对已完成的状态重复操作。
  • YAML 剧本化:使用人类易读的 YAML 语言编写剧本,配置即代码,易于版本管理。
幂等性(Idempotency)

幂等性是 Ansible 的灵魂。通俗地说,就是“做一次和做一百次的结果是一样的”。例如:创建一个已存在的目录,Ansible 会识别到该状态已达成,从而跳过操作(返回 OK 而非 Changed),这保证了生产环境的安全性。

1.3 本系列文章规划#

本系列将分为四个阶段带领大家掌握 Ansible:

  1. 入门基础:核心概念、环境部署与 Ad-Hoc 常用模块(本文)。
  2. 剧本核心:Playbook 语法、变量、任务编排与模板技术。
  3. 进阶能力:Role 角色化管理、Vault 加密与性能优化。
  4. 企业实践:实战案例分享、CI/CD 集成与最佳实践。

二、Ansible 核心基础与架构#

Ansible 之所以能在众多自动化工具中脱颖而出,很大程度上归功于其极其精简且高效的架构设计。理解其底层架构和执行原理,是我们编写高质量自动化代码的基石。

2.1 Ansible 管理架构全景解析#

Ansible 的架构主要由以下几个核心组件构成,它们各司其职,共同完成了复杂的自动化编排:

  • 控制节点(Control Node): 这是安装了 Ansible 引擎的机器,也是所有自动化指令的发起源头。它可以是你个人的笔记本(如 macOS/Linux),也可以是一台专门的堡垒机或 CI/CD 构建服务器(如 Jenkins/Drone CI 节点)。注意:Ansible 控制节点目前官方不支持原生 Windows,但可以在 WSL(Windows Subsystem for Linux)中运行。

  • 被控节点(Managed Nodes): 接受 Ansible 管理的目标服务器集群。被控节点不需要安装任何 Ansible 客户端程序(Agentless),只要具备 SSH 访问权限且安装了 Python 解释器(Python 2.7 或 Python 3.5+)即可。

  • 主机清单(Inventory): 这是 Ansible 知道“对谁进行操作”的来源。Inventory 相当于服务器的通讯录,记录了被控节点的 IP 地址、主机名、分组信息以及连接时需要的特殊参数(如特定端口、私钥路径等)。

  • 核心模块(Core Modules)与自定义模块(Custom Modules): 模块是 Ansible 真正干活的“底层工人”。Ansible 默认自带了上千个核心模块(涵盖操作系统管理、网络设备、云平台等),例如负责文件的 copy、负责服务的 systemd 等。如果自带模块无法满足需求,你甚至可以使用 Python 编写自己的自定义模块。

  • 插件系统(Plugins): 插件是 Ansible 架构中灵活扩展的灵魂。常见的插件包括:

    • 连接插件(Connection Plugins):决定如何与远端通信(默认是 smart,底层基于 OpenSSH 或 paramiko;也可以是 docker、local、winrm 等)。
    • 清单插件(Inventory Plugins):允许你从云厂商(如 AWS、阿里云)的 API 动态拉取服务器列表,而非手动维护静态文件。
    • 回调插件(Callback Plugins):用于拦截并处理执行结果,例如将执行日志推送到 Elasticsearch 或钉钉报警。
  • 剧本(Playbook): 将多个模块的调用组合在一起的 YAML 格式文件。如果说模块是“砖块”,那么 Playbook 就是“建筑图纸”,它定义了任务的执行顺序、并发控制和错误处理逻辑。

2.2 深度剖析:Ansible 工作执行流程#

当我们在控制端敲下 ansible 或 ansible-playbook 命令时,底层到底发生了什么?了解这个流程对后期排错至关重要:

  1. 环境初始化与读取配置: Ansible 首先会按照优先级(环境变量 > 当前目录 > 用户家目录 > /etc/ansible)加载 ansible.cfg 配置文件,确定默认的主机清单路径、并发数(forks)、提权方式等全局设置。

  2. 解析主机清单(Inventory Parsing): Ansible 会读取指定的 Inventory 文件或执行动态清单脚本,过滤出本次命令需要操作的目标主机集合,并加载这些主机及其所属组关联的变量。

  3. 建立安全连接(Connection Setup): 控制节点通过连接插件(默认 SSH)与被控节点建立网络连接。在此阶段,Ansible 会进行身份验证(密码或密钥)。如果配置了多并发(如 forks=5),Ansible 会并行建立连接。

  4. 生成与推送代码(Code Generation & Transfer): 这是 Ansible 的核心魔法!Ansible 会将你在命令中调用的模块,与传递的参数结合,动态生成一段极简的 Python 脚本。然后,通过 SFTP 或 SCP 将这段 Python 脚本推送到远端服务器的临时目录(通常是 ~/.ansible/tmp/)。

  5. 远端执行与状态回收(Execution & Return): 被控节点上的 Python 解释器执行推送过来的脚本。脚本执行完毕后,会将结果序列化为 JSON 格式,通过标准输出(stdout)返回给控制节点。

  6. 无痕清理(Cleanup): 为了保持被控节点的干净,控制节点会发送指令,自动删除远端临时目录中生成的 Python 脚本。整个过程就像特工执行任务一样,“事了拂衣去,深藏功与名”。


三、Ansible 部署与基础配置全攻略#

Ansible 的部署极其轻量。由于其无 Agent 架构,我们通常只需要在管理机(控制端)上花费几分钟进行安装和配置,被控端几乎处于“零准备”状态。

3.1 环境前置要求与兼容性#

在动手安装之前,我们需要明确控制端和被控端的基础要求:

  • 控制端(Control Node):
    • 操作系统:支持绝大多数类 Unix 系统,如 Ubuntu、Debian、CentOS、RHEL、macOS 等。
    • 软件环境:必须安装 Python 3.8 或更高版本。
    • 特别注意:Windows 不能直接作为控制端。如果你使用的是 Windows 电脑,强烈建议开启 WSL(Windows Subsystem for Linux)并安装 Ubuntu 子系统来运行 Ansible。
  • 被控端(Managed Node):
    • 操作系统:Linux、Unix、Windows(通过 WinRM 管理,非本系列重点)、网络设备(如 Cisco、华为交换机)。
    • 软件环境:绝大多数 Linux 模块要求被控端安装有 Python 2.7 或 Python 3.5+。同时,必须确保 SSH 服务(sshd)已启动且防火墙允许控制端 IP 访问 22 端口。

3.2 多平台 Ansible 安装指南#

Ansible 提供了多种安装方式,推荐使用系统包管理器或 Python 的 pip 工具。

方式一:使用系统包管理器(适合全局安装)#

CentOS/RHEL 系统安装
# Ansible 通常在 EPEL 仓库中,需要先安装 epel-release
sudo yum install -y epel-release
# 更新缓存并安装 Ansible
sudo yum makecache
sudo yum install -y ansible
Ubuntu/Debian 系统安装
sudo apt update
sudo apt install -y software-properties-common
# 添加 Ansible 官方 PPA 源以获取最新版本
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible
macOS 环境安装
# macOS 用户可以通过 Homebrew 轻松安装
brew install ansible

方式二:使用 Python PIP 安装(推荐给开发者,适合多版本隔离)#

如果你希望在虚拟环境中使用特定版本的 Ansible,或者你的系统包管理器提供的版本太老,pip 是最佳选择:

基于 Python pip 的隔离安装
# 创建并激活 Python 虚拟环境
python3 -m venv ansible-env
source ansible-env/bin/activate
# 使用 pip 安装 ansible 核心包
pip install --upgrade pip
pip install ansible

无论采用哪种方式,安装完成后,请通过以下命令验证是否成功,并查看当前加载的配置文件和 Python 版本:

验证安装及运行环境
ansible --version

3.3 核心配置文件 ansible.cfg 深度解析#

Ansible 的行为高度可定制,这一切都由 ansible.cfg 掌控。Ansible 查找配置文件的优先级为(从高到低):

  1. ANSIBLE_CONFIG 环境变量指定的路径
  2. 当前执行命令目录下的 ansible.cfg(推荐:做到项目级隔离)
  3. 用户家目录下的 ~/.ansible.cfg
  4. 全局默认路径 /etc/ansible/ansible.cfg
最佳实践:项目级隔离

强烈建议在你的每一个自动化项目根目录下创建一个独立的 ansible.cfg,并将基础配置和代码一起提交到 Git 仓库中。这样无论谁拉取了代码,执行环境的参数都是一致的。

以下是一个适用于大多数中小型项目的企业级 ansible.cfg 示例,包含了并发优化和排错配置:

[defaults]
# 基础配置
inventory = ./inventory ; 指定当前项目默认的主机清单路径,省去 -i 参数
remote_user = root ; 默认使用远端什么用户登录(推荐使用普通用户,此处为演示方便设为 root)
host_key_checking = False ; 关闭 SSH 的严格主机密钥检查(新手避坑必配置,避免首次连接卡在确认 known_hosts)
timeout = 30 ; SSH 连接的超时时间(秒),网络差的环境可适当调大
# 性能与执行优化
forks = 20 ; 并发执行的主机数量,默认是 5。集群较大时调大此值可成倍提升执行速度
gathering = smart ; Facts 信息收集策略。smart 表示收集过的主机不再重复收集
fact_caching = jsonfile ; 将收集到的主机信息缓存到本地文件
fact_caching_connection = /tmp/ansible_facts_cache ; 缓存文件存放路径
# 日志与排错
log_path = ./ansible.log ; 开启本地日志记录,方便事后审计和排错
display_skipped_hosts = False; 终端输出中隐藏被 skipped 的任务,让执行面板更清爽
[privilege_escalation]
# 提权配置(当 remote_user 为普通用户时,需要配置提权到 root 执行操作)
become = True ; 开启提权
become_method = sudo ; 提权方式为 sudo
become_user = root ; 提权后的目标用户
become_ask_pass = False ; 执行 sudo 时是否需要密码(前提是远端配置了免密 sudo)

3.4 彻底打通控制通道:SSH 免密登录配置#

在自动化运维中,如果每次执行命令都需要输入密码,那将是一场灾难。虽然 Ansible 提供了 --ask-pass 参数,但基于 SSH 密钥对的免密认证才是行业标准。

下面是打通控制端到被控端免密通道的标准流程:

全自动免密通道构建
# 1. 在控制端生成 SSH 密钥对(如果已经有 ~/.ssh/id_rsa 则跳过)
# -t 指定加密算法,-b 指定密钥长度,-N "" 表示私钥本身不设置密码保护
ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa
# 2. 将公钥分发到被控节点(此处以 192.168.1.10 为例)
# 执行该命令时,系统会要求你输入一次远端服务器的 root 密码
ssh-copy-id root@192.168.1.10
# 3. 验证免密登录(此时应该直接进入远端服务器,无需输入密码)
ssh root@192.168.1.10
SSH-Agent 的妙用

如果你的私钥设置了密码保护,或者你有多个不同的私钥文件对应不同的项目,频繁指定私钥路径会很繁琐。此时可以启动 ssh-agent 来接管私钥管理: eval $(ssh-agent -s) ssh-add ~/.ssh/id_rsa_custom Ansible 底层默认会利用 ssh-agent 的能力,自动匹配正确的密钥。


四、Inventory 主机清单高阶详解 ⭐⭐⭐⭐⭐#

如果说 Ansible 是一支军队,那么 Inventory(主机清单)就是指挥官手中的战略地图。它不仅仅是一个包含 IP 地址的文本文件,更是一个强大的业务逻辑组织工具。通过合理的清单设计,我们可以轻松实现复杂业务架构的映射。

4.1 清单的基础格式:INI 与 YAML 的抉择#

Ansible 同时支持多种格式的清单文件,最主流的是传统的 INI 格式和现代的 YAML 格式。

1. INI 格式(经典、直观)#

INI 格式是 Ansible 最古老也最常用的格式,语法简单,适合层级不深的场景。

# 游离主机(不属于任何自定义组,默认属于 'all' 和 'ungrouped' 组)
web1.example.com
192.168.1.20
# 定义业务分组
[web_servers]
192.168.1.21
192.168.1.22
# 利用范围通配符实现连续主机的简写(非常适合规模化集群)
[db_servers]
db-[a:c].example.com # 自动展开为 db-a, db-b, db-c
192.168.1.[10:15] # 自动展开为 192.168.1.10 到 192.168.1.15

2. YAML 格式(推荐、结构化强)#

随着 Playbook 强制使用 YAML,越来越多的企业选择将 Inventory 也写成 YAML 格式,以保持整个项目语言栈的统一。YAML 在表达深层级嵌套时更具可读性。

all:
hosts:
web1.example.com:
192.168.1.20:
children:
web_servers:
hosts:
192.168.1.21:
192.168.1.22:
db_servers:
hosts:
db-[a:c].example.com:
192.168.1.[10:15]:

4.2 主机组嵌套(逻辑聚合)#

在大型微服务架构中,服务器往往具有多重属性(例如:按地域分、按业务分、按环境分)。Ansible 允许你通过子组嵌套的方式,构建出符合业务维度的多维矩阵。

在 INI 格式中,使用 [大组名:children] 语法将多个小编组合并;在 YAML 格式中则使用 children 关键字。

# 地域维度
[shanghai_nodes]
192.168.10.1
192.168.10.2
[beijing_nodes]
192.168.20.1
192.168.20.2
# 汇总地域节点到全国大组
[china_nodes:children]
shanghai_nodes
beijing_nodes
# 环境维度(可以复用相同的节点,Ansible 会自动去重)
[prod_env:children]
shanghai_nodes
[test_env:children]
beijing_nodes

通过这种设计,你可以灵活地下发指令:比如“只对上海节点的机器更新配置”(针对 shanghai_nodes),或者“对全国的生产环境发布新版本”(针对 china_nodes 和 prod_env 的交集)。

4.3 行为参数与变量内置配置#

由于集群中可能存在历史遗留机器,它们的 SSH 端口、登录用户甚至 Python 路径都不一致。Ansible 提供了丰富的内置“行为参数(Behavioral Inventory Parameters)”,允许我们在清单中直接为单台主机或整个组进行特殊化配置。

为单台主机定义特殊连接参数#

假设你有一台通过跳板机映射出来的特殊服务器,端口不是 22,你可以直接在主机名后跟上变量:

[special_nodes]
# 实际连接时会使用 192.168.1.30 的 2222 端口,并使用 admin 用户和特定的私钥登录
web-special ansible_host=192.168.1.30 ansible_port=2222 ansible_user=admin ansible_ssh_private_key_file=~/.ssh/id_rsa_special

为整个主机组定义公共变量#

使用 [组名:vars] 可以为该组下的所有主机统一定义变量。不仅是连接参数,甚至可以定义业务相关的自定义变量供后续 Playbook 使用。

[db_servers]
192.168.1.50
192.168.1.51
[db_servers:vars]
# 指定远端 Python 解释器路径(解决 CentOS 7 和 Ubuntu 混合环境下的 Python 版本兼容问题)
ansible_python_interpreter=/usr/bin/python3
# 开启该组主机的 sudo 提权
ansible_become=yes
ansible_become_method=sudo
# 自定义业务变量
mysql_port=3306
max_connections=2000
变量优先级与剥离规范

虽然在 Inventory 中直接写变量很方便,但当变量变多时会导致清单文件极其臃肿且难以维护。企业级最佳实践建议:将变量从 Inventory 文件中剥离出来。 Ansible 会自动在 Inventory 同级目录下寻找 group_vars/ 和 host_vars/ 目录,并加载与主机组名或主机名同名的 YAML 变量文件。这将在下一篇文章中详细讲解。

4.4 动态主机清单(Dynamic Inventory)简介#

在云原生时代(如 AWS、阿里云、Kubernetes),服务器的 IP 随时在自动伸缩,静态的 Inventory 文件显然无法满足需求。 Ansible 支持动态主机清单,你可以配置一个 Python 脚本或使用官方提供的 Inventory 插件。当你执行命令时,Ansible 会实时调用云厂商的 API,拉取当前最新的服务器实例列表和标签,自动构建出主机组。这为构建全自动化的 CI/CD 流程提供了无限可能。


五、必知必会核心模块(Ad-Hoc 模式)#

Ad-Hoc 命令用于执行简单的临时任务,格式为:ansible <主机模式> -m <模块名> -a <参数>。 在 Ansible 中,模块是真正执行工作的核心。下面我们将按照功能分类,详细拆解最常用的十几个核心模块。每个模块都会包含核心参数解析与实战场景。

5.1 基础连通性与信息收集模块(必懂)#

1. ping 模块#

  • 核心作用:用于测试控制端与被控端的连通性。注意,这不是 ICMP 的 ping,而是通过 SSH 连接并尝试在远端执行一个极简的 Python 脚本。如果成功,返回 pong。
  • 实操示例:
    连通性测试
    ansible all -m ping
    排错技巧

    如果返回 UNREACHABLE,通常是因为 SSH 免密未配置成功、SSH 端口错误,或者远端机器未安装 Python 环境。

2. setup 模块#

  • 核心作用:收集远端主机的系统信息(在 Ansible 中称为 Facts),如操作系统版本、IP 地址、CPU 核数、内存大小等。这些变量在后续编写 Playbook 进行条件判断时非常关键。
  • 核心参数:
    • filter:使用通配符过滤所需的信息,避免输出过多无关数据。
  • 实操示例:
    收集系统信息
    # 获取全量系统信息(输出内容极多)
    ansible web_servers -m setup
    # 仅过滤获取 IPv4 地址信息
    ansible web_servers -m setup -a "filter=ansible_all_ipv4_addresses"
    # 仅获取系统内存信息
    ansible web_servers -m setup -a "filter=ansible_memtotal_mb"

5.2 命令与脚本类模块#

1. command 模块#

  • 核心作用:Ansible 的默认模块,用于在远端节点执行系统命令。它不经过 shell 解析,因此不支持管道符(|)、重定向(>、<)和环境变量(如 $HOME)。
  • 常用参数:
    • chdir:执行命令前,先切换到指定目录。
    • creates:如果指定的文件或目录已存在,则不执行该命令(用于实现简单的幂等性)。
    • removes:如果指定的文件或目录不存在,则不执行该命令。
  • 实操示例:
    按条件执行命令
    # 查看磁盘使用情况
    ansible all -m command -a "df -h"
    # 如果 /data 目录存在,则打包备份;执行前先进入 / 目录
    ansible web_servers -m command -a "tar -czvf data_backup.tar.gz data/ chdir=/ creates=/data_backup.tar.gz"

2. shell 模块#

  • 核心作用:在远端节点的 shell 环境(默认 /bin/sh -c)中执行命令,支持管道、重定向和通配符。
  • 与 command 的区别:虽然强大,但容易产生安全风险(如注入攻击),且多数情况下是非幂等的。每次执行都会显示 CHANGED 状态。
  • 实操示例:
    复杂管道命令
    # 批量查看 Java 进程并过滤
    ansible all -m shell -a "ps -ef | grep java | grep -v grep"
    # 将内容重定向写入文件(command 模块做不到)
    ansible all -m shell -a "echo 'export PATH=$PATH:/opt/bin' >> /etc/profile"
  • 使用建议:尽量使用 Ansible 的专用模块(如 lineinfile)替代 shell,只有在没有对应模块时才使用 shell。

3. script 模块#

  • 核心作用:自动化运维的利器。它会将控制端本地的脚本自动传输到被控端并执行,执行完成后自动删除远端临时文件,全程无感。
  • 实操示例:
    批量执行本地脚本
    # 将本地的 init_env.sh 脚本推送到远端执行
    ansible all -m script -a "/opt/scripts/init_env.sh"

5.3 文件与目录管理模块#

1. file 模块#

  • 核心作用:管理文件、目录、软硬链接的状态及权限属性。
  • 核心参数:
    • path:目标路径(必须)。
    • state:状态设定。directory(创建目录)、touch(创建空文件)、link(软链接)、absent(彻底删除)。
    • mode、owner、group:设置权限、属主和属组。
  • 实操示例:
    多场景文件管理
    # 批量创建目录并设置 755 权限
    ansible all -m file -a "path=/app/logs state=directory mode=0755 owner=www group=www"
    # 批量创建软链接
    ansible all -m file -a "src=/opt/nginx/sbin/nginx dest=/usr/bin/nginx state=link"
    # 安全清理无用目录(相当于 rm -rf,慎用)
    ansible all -m file -a "path=/tmp/old_cache state=absent"

2. copy 模块#

  • 核心作用:将控制端的文件或目录分发传输到被控端。
  • 核心参数:
    • src:控制端源文件路径。如果是目录,以 / 结尾表示仅拷贝内容,不以 / 结尾表示连同目录一起拷贝。
    • dest:被控端目标路径。
    • backup:设为 yes,当远端文件被覆盖前,会自动创建一个带时间戳的备份。
    • content:直接将指定文本内容写入远端文件(替代 src)。
  • 实操示例:
    安全分发配置
    # 分发 Nginx 配置,覆盖前自动备份
    ansible web_servers -m copy -a "src=./nginx.conf dest=/etc/nginx/nginx.conf backup=yes mode=0644"
    # 直接写入文本生成文件
    ansible all -m copy -a "content='Hello Ansible\n' dest=/tmp/test.txt"

3. fetch 模块#

  • 核心作用:与 copy 模块的作用刚好相反,用于将远端节点的文件**拉取(下载)**到控制端本地。常用于批量收集日志或备份配置文件。
  • 核心参数:
    • src:远端被控端的文件路径(注意:必须是文件,不能是目录)。
    • dest:控制端本地的保存目录。Ansible 会自动按照 dest/主机名/src 的目录结构存放,避免文件覆盖。
  • 实操示例:
    批量收集日志
    # 将所有 Web 节点的错误日志拉取到本地 /backup/logs 目录下
    ansible web_servers -m fetch -a "src=/var/log/nginx/error.log dest=/backup/logs/"

4. lineinfile 模块#

  • 核心作用:行级文本编辑器,常用于精确修改配置文件的某一行(如 /etc/ssh/sshd_config 或 hosts)。
  • 核心参数:
    • regexp:使用正则表达式匹配要修改的行。
    • line:替换成的新内容,或要追加的内容。
    • state:present(存在,默认)或 absent(删除匹配行)。
  • 实操示例:
    精准修改配置
    # 批量关闭 SSH 密码登录(匹配 PasswordAuthentication 并替换)
    ansible all -m lineinfile -a "path=/etc/ssh/sshd_config regexp='^#?PasswordAuthentication' line='PasswordAuthentication no'"

5. blockinfile 模块#

  • 核心作用:用于在文件中插入一段多行的文本块,并且会自动添加标记(Marker,如 # BEGIN ANSIBLE MANAGED BLOCK),方便后续的幂等性管理(更新或删除该块)。
  • 实操示例:
    插入多行配置
    # 在 Nginx 配置文件中插入一段完整的 server 块
    ansible web_servers -m blockinfile -a "path=/etc/nginx/conf.d/custom.conf block='server {\n listen 8080;\n server_name localhost;\n}'"

6. unarchive 模块#

  • 核心作用:处理压缩包。它可以将控制端的压缩包直接传输到远端并解压,或者解压远端机器上已存在的压缩包。
  • 核心参数:
    • src:压缩包路径。
    • dest:解压到的远端目标目录。
    • remote_src:如果设为 yes,表示 src 指向的是远端机器上的路径,不需要从控制端传输。
  • 实操示例:
    分发并解压源码包
    # 将本地的 JDK 压缩包传输到所有节点并解压到 /usr/local
    ansible all -m unarchive -a "src=/opt/packages/jdk-11.tar.gz dest=/usr/local/"

5.4 服务与软件包管理#

1. systemd 模块 (兼容 service 模块)#

  • 核心作用:管理系统服务(守护进程)的启停与自启配置。
  • 核心参数:
    • name:服务名称(如 nginx、sshd)。
    • state:started(启动)、stopped(停止)、restarted(重启)、reloaded(平滑重载)。
    • enabled:设为 yes 表示开机自启。
    • daemon_reload:如果修改了 unit 配置文件,必须设为 yes 重新加载 systemd。
  • 实操示例:
    服务状态管理
    # 批量启动 Nginx 并设置开机自启
    ansible web_servers -m systemd -a "name=nginx state=started enabled=yes"
    # 修改配置后重载 systemd 并重启服务
    ansible web_servers -m systemd -a "name=myapp state=restarted daemon_reload=yes"

2. yum 模块 (Debian 系使用 apt 模块)#

  • 核心作用:在 RedHat/CentOS 系列系统上管理 RPM 软件包。
  • 核心参数:
    • name:软件包名称(支持多包逗号分隔,或指定具体版本 nginx-1.18.0)。
    • state:present(安装,默认)、latest(升级到最新版)、absent(卸载)。
  • 实操示例:
    批量包管理
    # 批量安装多个运维工具
    ansible all -m yum -a "name=htop,iotop,curl state=present"

5.5 用户与权限管理模块#

1. group 模块#

  • 核心作用:创建、删除系统用户组。
  • 实操示例:
    业务组管理
    ansible all -m group -a "name=opsgroup gid=2000 state=present"

2. user 模块#

  • 核心作用:系统用户的全生命周期管理。
  • 核心参数:
    • name:用户名。
    • shell:登录 Shell 路径(如 /sbin/nologin 限制登录)。
    • password:密码(必须是哈希加密后的密文,不能是明文)。
  • 实操示例:
    标准化用户创建
    # 创建程序运行专属用户(不允许登录系统)
    ansible all -m user -a "name=www uid=1001 group=www shell=/sbin/nologin create_home=no"
    密码哈希生成技巧

    你可以使用 Python 快速生成符合要求的密码密文,例如: python3 -c "import crypt; print(crypt.crypt('YourPassword', crypt.mksalt(crypt.METHOD_SHA512)))"

5.6 高频实用扩展模块#

1. mount 模块#

  • 核心作用:管理文件系统的挂载,并可自动配置 /etc/fstab 实现开机自动挂载。
  • 核心参数:
    • path:挂载点目录。
    • src:要挂载的设备路径或 NFS 地址。
    • fstype:文件系统类型(如 ext4, xfs, nfs)。
    • state:mounted(挂载并写入 fstab,最常用)、absent(卸载并删除 fstab 记录)。
  • 实操示例:
    批量挂载数据盘
    ansible db_servers -m mount -a "path=/data src=/dev/sdb1 fstype=xfs state=mounted"

2. cron 模块#

  • 核心作用:管理系统的 Crontab 定时任务。
  • 核心参数:
    • name:任务的描述名称(Ansible 依靠此标识判断幂等性)。
    • minute/hour/day/month/weekday:时间表达式,未指定的默认为 *。
    • job:具体执行的命令。
  • 实操示例:
    配置时间同步
    # 每天凌晨 2 点执行日志清理
    ansible all -m cron -a "name='clean old logs' hour=2 job='/opt/scripts/clean.sh >/dev/null 2>&1'"

六、Ad-Hoc 执行结果输出解析与排错指南#

在使用 Ansible 执行模块时,看懂输出结果是排错的第一步。Ansible 会通过不同颜色和状态码来直观展示执行结果。

6.1 状态颜色含义#

  • 绿色 (SUCCESS / OK)
    • 含义:探测成功,或者目标节点的状态已经符合预期,Ansible 未对系统做出任何更改。这正是“幂等性”的最佳体现。
  • 黄色 (CHANGED)
    • 含义:任务执行成功,并且 Ansible 对远端系统做出了实质性的修改(例如:新建了文件、修改了配置、重启了服务)。
  • 红色 (FAILED / UNREACHABLE)
    • 含义:任务执行失败,或者主机根本无法连接。输出中通常会附带详细的 msg(报错提示)或 stderr(标准错误输出)。
  • 紫色 (WARNING)
    • 含义:警告信息。通常提示模块即将废弃,或者建议你使用更规范的模块(例如:你用 shell 执行了 curl 命令,Ansible 会警告你推荐使用 get_url 模块)。

6.2 常见报错与排查思路#

  1. UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh..."}
    • 原因:SSH 连接失败。
    • 排查思路:检查目标机器 IP 是否正确、SSH 端口是否开放、防火墙策略,以及最常见的——控制端的公钥是否已成功分发到被控端。
  2. FAILED! => {"changed": false, "msg": "Missing sudo password"}
    • 原因:权限不足,普通用户执行了需要 Root 权限的模块。
    • 排查思路:在命令后加上 -b(become,即提权),或者检查 /etc/sudoers 是否配置了免密 sudo。
  3. MODULE FAILURE 或 Interpreter discovery failed
    • 原因:远端机器未安装 Python,或者 Python 路径不正确。
    • 排查思路:通过 yum install python3 补全环境,或者在 Inventory 中通过 ansible_python_interpreter 强制指定 Python 路径。

七、本篇总结#

7.1 核心知识点回顾#

  • 无 Agent:基于 SSH,轻量级,被控端仅需 Python。
  • 幂等性:确保多次执行结果一致,是生产安全的保障。
  • Inventory:灵活的分组与变量管理是自动化运维的核心。
  • Ad-Hoc 与核心模块:虽然方便,但只适合临时、简单的任务。
Ansible 自动化运维(1):核心概念、环境部署与常用模块全解析
https://www.6ixblog.site/posts/ansible-1/
作者
Licwic
发布于
2026-08-09
许可协议
CC BY-NC-SA 4.0