Ansible 核心要点总结
一、Ansible 核心定位与价值
1. 核心定义
- 开源自动化工具,采用人类可读的 YAML 格式描述 IT 基础架构,实现 "基础架构即代码"(Infrastructure as Code)
- 核心功能覆盖:配置管理、应用部署、工作流自动化、网络自动化、生命周期编排、安全合规管理
- 无代理(Agentless)架构:通过 SSH(Linux/Unix)或 WinRM(Windows)连接受管节点,无需在目标主机安装代理程序,部署简单、高效安全
2. 核心优势
- 易用性:Playbook 语法简洁,无需复杂编程技能,新手可快速上手
- 功能全面:支持多平台(Linux/Windows/ 网络设备)、多场景(从单机配置到集群部署)
- 幂等性:多次执行相同 Playbook 不会导致意外结果,确保系统始终处于预期状态
- 可扩展性:支持模块、插件扩展,可与 Jenkins、Puppet、Git 等 DevOps 工具无缝集成
- 版本可控:Playbook 及相关文件为纯文本,可通过 Git 等版本控制系统管理,支持变更追溯、回滚和团队协作
- 跨平台兼容:可管理 Linux、UNIX、Windows 系统及 Cisco IOS、Juniper Junos 等网络设备
3. 与 DevOps 的关系
- 打破开发(Dev)、运维(Ops)、QA 团队壁垒,通过自动化流程促进协作
- 自动化 "软件交付" 和 "架构变更" 全流程,实现快速、频繁、可靠的软件发布
- Playbook 作为协作载体,开发人员可定义配置,运维人员可执行部署,实现双向反馈
二、核心架构与关键概念
1. 架构组件
| 组件 |
作用 |
核心特性 |
| 控制节点(Control Node) |
安装 Ansible 软件,执行 Playbook 和 Ad-Hoc 命令 |
仅支持 Linux/Unix,不支持 Windows |
| 受管节点(Managed Nodes) |
被 Ansible 管理的目标主机 / 设备 |
无需安装 Ansible,需支持 SSH/WinRM 连接 |
| 清单(Inventory) |
定义受管节点集合及分组、变量配置 |
支持 INI/YAML 格式,支持静态 / 动态生成 |
| Playbook |
自动化核心脚本,包含一个或多个 Play |
按顺序执行任务,支持变量、条件、循环等逻辑 |
| 模块(Modules) |
执行具体任务的代码片段(如文件操作、软件安装) |
内置数百个核心模块,支持自定义模块 |
| 插件(Plugins) |
扩展 Ansible 功能 |
包括连接插件、回调插件、过滤插件等 |
| 变量(Variables) |
存储可复用数据,减少硬编码 |
支持多级别定义,支持数组、字典等结构 |
| 事实(Facts) |
自动收集的受管节点状态信息 |
如 IP 地址、内核版本、磁盘信息等,可直接作为变量使用 |
| Ansible Vault |
加密敏感变量(密码、API 密钥等) |
避免敏感数据明文存储,保障安全性 |
2. 核心概念详解
- Ad-Hoc 命令:一次性临时命令,适用于快速测试、简单操作(如批量执行命令、检查服务状态),无需保存
- Play :Playbook 的核心组成单元,定义 "在哪些主机上执行哪些任务",包含
hosts(目标主机)、tasks(任务列表)、vars(变量)等属性
- 任务(Task):Play 的最小执行单元,每个任务调用一个模块并传递参数,按顺序执行
- 角色(Role):将 Playbook 按功能拆分的目录结构(进阶功能),便于复用和维护复杂场景
- 幂等性:核心设计原则,无论执行多少次,结果一致(如 "确保服务启动" 而非 "启动服务")
- 魔术变量(Magic Variables) :Ansible 内置变量,用于获取集群拓扑信息(如
inventory_hostname、group_names)
三、环境部署与基础配置
1. 环境规划要求
| 节点类型 |
系统要求 |
核心依赖 |
| 控制节点 |
CentOS 7+ / RHEL 7+ |
Python 2.7+/3.5+、Ansible、SSH 客户端、sshpass(可选) |
| Linux 受管节点 |
支持 SSH 连接 |
Python 2.7+/3.5+(大部分模块依赖) |
| Windows 受管节点 |
支持 WinRM 连接 |
PowerShell 3.0+、.NET Framework 4.0+ |
| 网络设备 |
支持 SSH CLI/XML API |
无需 Python,通过专用模块通信 |
2. 基础环境部署步骤(完整流程)
2.1 所有节点基础配置
bash
复制代码
# 1. 配置主机名解析(确保节点间互通)
cat >> /etc/hosts <<EOF
192.168.108.10 controller.laogao.cloud controller
192.168.108.11 node1.laogao.cloud node1
192.168.108.12 node2.laogao.cloud node2
192.168.108.13 node3.laogao.cloud node3
192.168.108.14 node4.laogao.cloud node4
EOF
# 2. 创建统一管理用户(如 laogao)并设置密码
useradd laogao
echo huawei | passwd --stdin laogao
# 3. 配置免密 sudo 权限(避免执行特权操作时输入密码)
echo 'laogao ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/laogao
chmod 0440 /etc/sudoers.d/laogao # 必须设置为 0440,否则 sudo 报错
2.2 控制节点安装 Ansible
bash
复制代码
# 1. 安装 EPEL 源(CentOS/RHEL 系统)
yum install -y epel-release
# 2. 替换 EPEL 源为华为云镜像(加速安装)
sed -i "s/#baseurl/baseurl/g" /etc/yum.repos.d/epel.repo
sed -i "s/metalink/#metalink/g" /etc/yum.repos.d/epel.repo
sed -i "s@https\?://download.[a-z]*\.\?[a-z]*/pub@https://repo.huaweicloud.com@g" /etc/yum.repos.d/epel.repo
# 3. 安装 Ansible 及依赖工具
yum install -y ansible sshpass
# 4. 配置 laogao 用户免密登录所有受管节点
su - laogao
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N '' # 生成无密码密钥对
for host in controller node{1..4}; do
sshpass -p huawei ssh-copy-id -o StrictHostKeyChecking=no laogao@$host
done
# 5. 验证免密登录和 Ansible 安装
for host in controller node{1..4}; do ssh laogao@$host hostname; done
ansible --version # 验证安装成功
2.3 受管节点特殊配置
- Linux 节点 :确保 SSH 服务运行,安装 Python(
yum install -y python3)
- Windows 节点:启用 WinRM,配置 PowerShell 远程连接,安装 .NET Framework 4.0+
- 网络设备:启用 SSH 或 API 访问,配置登录凭据
3. 核心配置文件(ansible.cfg)
3.1 配置文件优先级(从高到低)
- 环境变量
ANSIBLE_CONFIG 指定的文件
- 当前项目目录下的
ansible.cfg(推荐,项目隔离)
- 用户主目录下的
~/.ansible.cfg
- 系统默认目录
/etc/ansible/ansible.cfg
3.2 核心配置项(常用)
ini
复制代码
[defaults]
remote_user = laogao # 默认远程连接用户
inventory = ./inventory # 清单文件路径
host_key_checking = False # 禁用 SSH 主机密钥检查(避免首次连接交互)
log_path = /var/log/ansible.log # Ansible 日志文件路径
module_name = command # 默认模块(未指定 -m 时使用)
roles_path = /etc/ansible/roles # 角色存放路径
error_on_undefined_vars = False # 未定义变量时不报错(可选)
command_warnings = False # 禁用 command 模块警告
[privilege_escalation]
become = True # 启用权限提升(默认切换到 root)
become_user = root # 提升后的目标用户
become_method = sudo # 权限提升方式(sudo/su/pbrun 等)
become_ask_pass = False # 提升权限时无需输入密码
3.3 配置验证命令
bash
复制代码
# 查看当前生效的配置文件
ansible --version | grep 'config file'
# 查看所有生效配置(含默认值)
ansible-config dump
# 查看当前配置文件内容
ansible-config view
# 查看特定配置项的说明
ansible-config list | grep -A 10 "DEFAULT_HOST_LIST"
四、清单(Inventory)配置详解
1. 清单核心功能
- 定义受管节点集合,支持主机分组、变量配置、组嵌套
- 支持静态清单(文本文件)和动态清单(脚本生成,适配 OpenStack/K8s 等动态环境)
2. 静态清单格式(INI 为主,推荐)
2.1 基础语法
ini
复制代码
# 1. 独立主机(不属于任何组)
controller # 主机名(需能解析)
# 2. 主机组定义([组名] 开头)
[webservers]
node1
node2
192.168.108.13 # 直接写 IP 地址
node3 ansible_port=2222 # 指定 SSH 端口(非默认 22)
[dbservers]
node4
192.168.108.15
# 3. 组嵌套(子组必须已定义)
[datacenter:children]
webservers
dbservers
# 4. 范围简写(简化大量主机配置)
[appservers]
app[01:10].example.com # 数字范围:app01 ~ app10
server[a:c].example.com # 字母范围:servera ~ serverc
192.168.[4:6].[10:20] # IP 范围:192.168.4.10~20、192.168.5.10~20、192.168.6.10~20
# 5. 组变量(应用于组内所有主机)
[webservers:vars]
web_package = httpd
listen_port = 80
admin_user = laogao
# 6. 全局变量(应用于所有主机)
[all:vars]
ansible_user = laogao
2.2 清单验证与管理命令
bash
复制代码
# 1. 列出指定组的主机
ansible --list-hosts -i inventory webservers
# 2. 树形结构展示清单(含组嵌套)
ansible-inventory -i inventory --graph
# 3. YAML 格式导出清单(便于查看结构)
ansible-inventory -i inventory --list -y
# 4. 查看特定主机的变量
ansible node1 -i inventory -m debug -a "var=hostvars['node1']"
3. 动态清单(简介)
- 通过脚本或程序自动生成清单(支持 Python/Shell 等)
- 适用于动态环境(如 OpenStack 云实例、K8s 集群),无需手动维护主机列表
- 脚本需满足:接受
--list 参数返回所有主机组,接受 --host <主机名> 返回该主机变量
五、Ad-Hoc 命令(临时命令)详解
1. 核心作用
- 快速执行单个任务,无需编写 Playbook,适用于测试、应急操作、简单批量任务
- 语法简洁,执行高效,是 Ansible 入门和日常运维的常用工具
2. 语法格式
bash
复制代码
ansible <主机模式> -m <模块> [-a <模块参数>] [-i <清单文件>] [-v <详细度>]
- 主机模式:清单中的主机名、组名、通配符(如
all、webservers、node*)
-m <模块>:指定使用的模块(默认 command 模块,可省略)
-a <参数>:模块的参数(字符串格式,键值对用空格分隔)
-i <清单>:指定清单文件(默认 /etc/ansible/hosts)
-v:详细度(-v/-vv/-vvv/-vvvv 递增,-vvvv 含 SSH 调试信息)
3. 常用模块与实战示例
| 模块 |
功能 |
核心参数 |
实战示例 |
|
| command |
执行简单命令(无 Shell 特性) |
命令字符串 |
ansible all -a "hostname"(查看所有主机名) |
|
| shell |
执行 Shell 命令(支持管道 / 重定向) |
命令字符串 |
`ansible webservers -m shell -a "ps aux |
grep httpd"`(查看 HTTPD 进程) |
| yum |
管理 RPM 包(CentOS/RHEL) |
name(包名)、state(present/latest/absent) |
ansible webservers -m yum -a "name=httpd state=latest"(安装最新 HTTPD) |
|
| apt |
管理 DEB 包(Ubuntu/Debian) |
name、state |
ansible dbservers -m apt -a "name=mariadb-server state=present" |
|
| copy |
复制文件 / 目录到受管节点 |
src(源路径)、dest(目标路径)、owner、mode、backup |
ansible all -m copy -a "src=/tmp/local.txt dest=/opt/remote.txt owner=root mode=0644 backup=yes"(复制并备份) |
|
| file |
管理文件 / 目录属性、创建 / 删除 |
path(路径)、state(directory/file/link/absent)、mode、owner |
ansible all -m file -a "path=/webapp state=directory mode=0755 owner=apache"(创建目录) |
|
| service |
管理系统服务 |
name(服务名)、state(started/stopped/restarted)、enabled(yes/no) |
ansible webservers -m service -a "name=httpd state=started enabled=yes"(启动并设置开机自启) |
|
| user |
管理用户账户 |
name(用户名)、uid、home、state(present/absent)、group |
ansible all -m user -a "name=newuser uid=1001 home=/home/newuser state=present"(创建用户) |
|
| group |
管理用户组 |
name(组名)、gid、state |
ansible all -m group -a "name=webgroup gid=1001 state=present"(创建组) |
|
| setup |
收集受管节点事实(Facts) |
filter(过滤事实) |
ansible node1 -m setup -a "filter=ansible_default_ipv4"(查看默认 IPv4 地址) |
|
| lineinfile |
编辑文件中的单行文本 |
path、line(文本行)、regexp(匹配正则)、insertbefore/insertafter |
ansible webservers -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen 80' line='Listen 8080'"(替换端口) |
|
| blockinfile |
编辑文件中的多行文本块 |
path、block(文本块)、create(是否创建文件) |
ansible all -m blockinfile -a "path=/etc/hosts block='192.168.108.10 controller' create=no"(添加主机解析) |
|
4. 命令执行结果颜色含义
- 绿色:目标主机已处于预期状态,无需任何变更
- 黄色:任务执行成功,目标主机状态已变更(如安装软件、修改配置)
- 红色:任务执行失败(如依赖缺失、权限不足),剩余任务中止
5. 模块文档查询命令
bash
复制代码
# 1. 列出所有可用模块
ansible-doc -l
# 2. 查看模块详细文档(含参数、示例)
ansible-doc yum
# 3. 查看模块使用示例(简洁版)
ansible-doc -s copy
# 4. 查看模块的返回值说明
ansible-doc -v user
六、Playbook 完整详解
1. 核心价值
- 将复杂、重复的运维任务转化为可复用、可维护的自动化脚本
- 支持多任务、多主机组、变量、条件判断、循环等复杂逻辑
- 是 Ansible 自动化的核心载体,适用于生产环境的规模化部署
2. YAML 语法规则(Playbook 基础)
- 首行建议添加
--- 标识文件开始(可选但推荐)
- 缩进:使用空格(不支持 Tab),同一级别缩进一致(推荐 2 空格)
- 键值对:用
: 分隔,: 后必须加空格(如 name: 部署 HTTPD)
- 列表项:以
- 开头,- 后加空格(如模块参数中的多值列表)
- 注释:以
# 开头,单行注释(# 这是注释)
- 字符串:可加引号(特殊字符如空格、
{} 必须加引号)
- 多行字符串:用
| 保留换行,用 > 折叠换行(替换为空格)
2.1 Vim 编辑优化(适配 YAML)
bash
复制代码
# 在 ~/.vimrc 中添加配置,自动适配 YAML 格式
echo 'autocmd FileType yaml set ai ts=2 sw=2 et' >> ~/.vimrc
source ~/.vimrc
ai:自动缩进
ts=2:Tab 键等效于 2 空格
sw=2:缩进宽度 2 空格
et:将 Tab 转换为空格
3. Playbook 核心结构
yaml
复制代码
---
# 第一个 Play:部署 Web 服务(目标:webservers 组)
- name: 部署 HTTPD 服务并配置防火墙 # Play 名称(描述功能)
hosts: webservers # 目标主机组(清单中定义)
gather_facts: yes # 是否收集受管节点事实(默认 yes)
remote_user: laogao # 远程连接用户(覆盖配置文件)
become: yes # 启用权限提升(覆盖配置文件)
vars: # Play 级变量(仅当前 Play 生效)
web_package: httpd
listen_port: 80
tasks: # 任务列表(按顺序执行)
# 任务 1:安装 HTTPD 和 firewalld 软件包
- name: 安装最新版 HTTPD 和 firewalld # 任务名称(描述具体操作)
yum: # 模块名
name: # 模块参数(列表格式)
- "{{ web_package }}" # 引用变量
- firewalld
state: latest # 确保软件包为最新版本
# 任务 2:创建测试首页
- name: 生成 Web 首页内容
copy:
content: "Welcome to {{ ansible_fqdn }}!\n" # 引用事实变量(主机名)
dest: /var/www/html/index.html # 目标文件路径
owner: apache # 文件属主
group: apache # 文件属组
mode: 0644 # 文件权限
# 任务 3:启动并启用 firewalld 服务
- name: 确保 firewalld 服务运行并开机自启
service:
name: firewalld
state: started # 服务状态(started/stopped/restarted)
enabled: yes # 是否开机自启(yes/no)
# 任务 4:防火墙放行 HTTP 服务
- name: 配置防火墙允许 HTTP 访问
firewalld:
service: http # 服务名(firewalld 预定义)
permanent: yes # 永久生效(重启防火墙不失效)
state: enabled # 启用规则
immediate: yes # 立即生效(无需重启防火墙)
# 任务 5:启动并启用 HTTPD 服务
- name: 确保 HTTPD 服务运行并开机自启
service:
name: "{{ web_package }}"
state: started
enabled: yes
# 第二个 Play:测试 Web 服务可用性(目标:localhost)
- name: 验证 Web 服务访问
hosts: localhost # 在控制节点执行
gather_facts: no # 无需收集事实(加快执行)
become: no # 无需权限提升
tasks:
- name: 访问 node1 的 Web 服务
uri:
url: http://node1
status_code: 200 # 期望返回 HTTP 200 状态码
return_content: yes # 返回页面内容
4. Playbook 运行与调试命令
| 命令 |
功能 |
示例 |
--syntax-check |
语法检查(不执行任务) |
ansible-playbook playbook.yaml --syntax-check |
-C/--check |
空运行(模拟执行,显示预期变更) |
ansible-playbook playbook.yaml -C |
| 无选项 |
正常执行 |
ansible-playbook playbook.yaml |
-v/-vv/-vvv |
详细输出(递增详细度) |
ansible-playbook playbook.yaml -vv |
-i <清单> |
指定清单文件 |
ansible-playbook -i inventory playbook.yaml |
-e <变量> |
传递额外变量(覆盖配置) |
ansible-playbook playbook.yaml -e "web_package=httpd24" |
--ask-vault-pass |
交互输入 Vault 密码(加密文件) |
ansible-playbook playbook.yaml --ask-vault-pass |
--vault-password-file <文件> |
从文件读取 Vault 密码 |
ansible-playbook -vault-password-file pass.txt playbook.yaml |
5. Playbook 核心特性
- 多 Play 支持:一个 Playbook 可包含多个 Play,按顺序执行(如先部署服务,再测试)
- 变量引用 :通过
{``{ 变量名 }} 引用,支持 Play 变量、主机变量、事实变量等
- 条件判断 :通过
when 关键字实现(如 when: ansible_os_family == "RedHat")
- 循环 :通过
with_items/loop 实现批量操作(如批量安装软件包)
- 注册变量 :通过
register 捕获任务输出,后续任务可引用(如捕获命令执行结果)
七、变量与事实(Facts)管理
1. 变量核心规则
1.1 命名规则
- 仅包含字母(a-z/A-Z)、数字(0-9)、下划线(_)
- 必须以字母开头(不能以数字或下划线开头)
- 不能包含空格、点号(.)、美元符号($)等特殊字符
1.2 变量优先级(从高到低,冲突时高优先级覆盖低优先级)
- 命令行传递的变量(
-e 选项)
- Playbook 中
vars 关键字定义的变量
- Playbook 中
vars_files 引用的变量文件
- 角色(Role)中的变量(进阶)
- 主机变量(
host_vars/ 目录)
- 组变量(
group_vars/ 目录)
- 清单文件中定义的变量(组变量 > 全局变量)
- 事实变量(Ansible 自动收集)
- 默认变量(Ansible 内置)
2. 变量定义方式(推荐实践)
2.1 按范围分类
| 定义方式 |
适用范围 |
示例 |
Play 内 vars |
仅当前 Play |
vars: { web_package: httpd, port: 80 } |
vars_files 引用 |
当前 Play |
vars_files: [ "./vars/web.yaml", "./vars/common.yaml" ] |
host_vars/ 目录 |
特定主机 |
host_vars/node1.yaml 中定义 node1 的专属变量 |
group_vars/ 目录 |
特定组 |
group_vars/webservers.yaml 中定义 webservers 组的变量 |
| 清单文件 |
组 / 主机 |
[webservers:vars] 中定义组变量 |
2.2 推荐目录结构(变量分离,便于维护)
plaintext
复制代码
project/
├── ansible.cfg # 项目配置文件
├── inventory # 清单文件
├── playbook.yaml # 主 Playbook
├── group_vars/ # 组变量目录
│ ├── webservers.yaml # webservers 组变量
│ └── dbservers.yaml # dbservers 组变量
├── host_vars/ # 主机变量目录
│ ├── node1.yaml # node1 主机变量
│ └── node2.yaml # node2 主机变量
└── vars/ # 通用变量文件
├── common.yaml # 所有 Play 共享变量
└── secret.yaml # 敏感变量(需 Vault 加密)
3. 特殊变量类型
3.1 魔术变量(Magic Variables)
inventory_hostname:清单中定义的主机名(不受 ansible_host 影响)
group_names:当前主机所属的所有组(列表)
groups:所有主机组及成员(字典,如 groups['webservers'] 取 webservers 组主机)
hostvars:其他主机的变量(如 hostvars['node1']['ansible_default_ipv4']['address'])
play_hosts:当前 Play 的目标主机列表
3.2 主机连接变量
ansible_host:目标主机 IP 地址(覆盖清单中的主机名)
ansible_port:SSH 端口(默认 22)
ansible_user:SSH 连接用户
ansible_ssh_private_key_file:私钥文件路径
ansible_become:是否启用权限提升
ansible_become_method:权限提升方式
4. 事实(Facts)管理
4.1 核心概念
- 事实是 Ansible 自动收集的受管节点状态信息,无需手动定义
- 包含主机名、IP 地址、内核版本、磁盘信息、操作系统版本等
- 可直接作为变量在 Playbook 中引用(如
{``{ ansible_default_ipv4.address }})
4.2 常用事实变量
| 事实变量 |
描述 |
ansible_fqdn |
完全限定域名 |
ansible_hostname |
短主机名 |
ansible_default_ipv4.address |
默认 IPv4 地址 |
ansible_kernel |
内核版本 |
ansible_memtotal_mb |
总内存(MB) |
ansible_disks |
磁盘信息(列表) |
ansible_os_family |
操作系统家族(如 RedHat、Debian) |
ansible_distribution |
操作系统名称(如 CentOS、Ubuntu) |
ansible_pkg_mgr |
包管理器(如 yum、apt) |
4.3 事实收集控制
yaml
复制代码
# 1. 关闭当前 Play 的事实收集(加快执行)
- name: 部署服务(无事实收集)
hosts: webservers
gather_facts: no # 禁用自动收集
tasks: ...
# 2. 手动收集特定事实
- name: 手动收集事实
hosts: webservers
gather_facts: no
tasks:
- name: 收集网络相关事实
setup:
filter: ansible_default_ipv4 # 仅收集默认 IPv4 信息
5. 敏感变量加密(Ansible Vault)
5.1 核心作用
- 加密密码、API 密钥、数据库凭据等敏感数据,避免明文存储在 Playbook 或变量文件中
- 支持加密单个文件、字符串,或整个变量目录
5.2 常用 Vault 命令
| 命令 |
功能 |
示例 |
create |
创建加密文件 |
ansible-vault create secret.yaml |
edit |
编辑加密文件 |
ansible-vault edit secret.yaml |
view |
查看加密文件内容 |
ansible-vault view secret.yaml |
encrypt |
加密现有明文文件 |
ansible-vault encrypt plain.yaml |
decrypt |
解密文件 |
ansible-vault decrypt secret.yaml |
rekey |
更改加密密码 |
ansible-vault rekey secret.yaml |
encrypt_string |
加密字符串 |
ansible-vault encrypt_string "Huawei12#$" |
5.3 加密文件使用示例
yaml
复制代码
# secret.yaml(加密前,YAML 格式)
db_user: root
db_password: Huawei12#$
db_host: localhost
# Playbook 中引用加密文件
- name: 配置数据库
hosts: dbservers
vars_files:
- ./vars/secret.yaml # 加密后的文件
tasks:
- name: 创建数据库用户
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
host: "{{ db_host }}"
priv: "*.*:ALL"
state: present
八、文件操作核心模块详解
文件操作是运维自动化的核心场景,Ansible 提供了丰富的文件模块,覆盖创建、复制、编辑、删除等全流程。
1. 核心文件模块对比
| 模块 |
核心功能 |
适用场景 |
关键参数 |
file |
管理文件 / 目录属性、创建 / 删除 |
权限修改、创建目录 / 文件、删除文件 |
path(路径)、state(directory/file/link/absent)、mode(权限)、owner(属主) |
copy |
复制文件 / 目录、直接写入内容 |
分发配置文件、生成简单文件 |
src(源)、dest(目标)、content(直接写入内容)、backup(覆盖前备份)、recursive(递归复制目录) |
lineinfile |
编辑文件中的单行文本 |
修改配置文件中的特定行、添加 / 删除行 |
path、line(文本行)、regexp(匹配正则)、insertbefore/insertafter(插入位置)、state(present/absent) |
blockinfile |
编辑文件中的多行文本块 |
添加 / 替换配置块、注释块 |
path、block(文本块)、regexp(匹配替换)、create(是否创建文件)、marker(标记注释) |
replace |
基于正则替换文件内容(多行支持) |
批量替换文件中的字符串 |
path、regexp(匹配正则)、replace(替换内容)、backup(备份) |
fetch |
从受管节点拉取文件到控制节点 |
收集日志、配置文件备份 |
src(远程路径)、dest(本地存储路径)、flat(是否保留目录结构) |
synchronize |
基于 rsync 同步文件 / 目录 |
高效同步大量文件、代码分发 |
src(源)、dest(目标)、delete(删除远程多余文件)、rsync_opts(rsync 参数) |
stat |
检索文件状态信息(类似 Linux stat) |
检查文件是否存在、获取校验和 |
path、checksum_algorithm(校验和算法)、get_checksum(是否获取校验和) |
2. 实战示例(核心模块)
2.1 file 模块(属性管理 / 创建 / 删除)
yaml
复制代码
- name: file 模块示例
hosts: node1
tasks:
# 1. 创建目录(含权限、属主)
- name: 创建 /webapp 目录
file:
path: /webapp
state: directory
owner: apache
group: apache
mode: 0755 # 权限(必须加前导 0 或引号)
# 2. 创建空文件
- name: 创建配置文件
file:
path: /webapp/app.conf
state: touch
mode: 0644
# 3. 创建符号链接
- name: 建立 /etc/app.conf 链接到 /webapp/app.conf
file:
src: /webapp/app.conf
dest: /etc/app.conf
state: link
# 4. 删除文件
- name: 删除临时文件
file:
path: /tmp/temp.txt
state: absent
2.2 copy 模块(复制 / 写入内容)
yaml
复制代码
- name: copy 模块示例
hosts: webservers
tasks:
# 1. 复制控制节点文件到受管节点
- name: 分发 HTTPD 配置文件
copy:
src: ./conf/httpd.conf
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 0644
backup: yes # 覆盖前备份原文件(后缀为时间戳)
# 2. 直接写入内容到文件
- name: 生成虚拟主机配置
copy:
content: |
<VirtualHost *:80>
ServerName {{ ansible_fqdn }}
DocumentRoot /var/www/html
ErrorLog /var/log/httpd/error.log
</VirtualHost>
dest: /etc/httpd/conf.d/vhost.conf
mode: 0644
create: yes # 文件不存在则创建
# 3. 递归复制目录
- name: 同步网站静态资源
copy:
src: ./static/
dest: /var/www/html/static/
recursive: yes # 递归复制目录
directory_mode: 0755 # 目录权限(文件权限继承源文件)
2.3 lineinfile 模块(单行编辑)
yaml
复制代码
- name: lineinfile 模块示例
hosts: webservers
tasks:
# 1. 确保文件中存在特定行
- name: 添加 KeepAlive 配置
lineinfile:
path: /etc/httpd/conf/httpd.conf
line: "KeepAlive On"
state: present
# 2. 在指定行前插入
- name: 在 Listen 80 前插入 Listen 8080
lineinfile:
path: /etc/httpd/conf/httpd.conf
line: "Listen 8080"
insertbefore: '^Listen 80' # 匹配以 Listen 80 开头的行
# 3. 替换匹配的行
- name: 替换 MaxClients 配置
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^MaxClients'
line: 'MaxClients 150'
state: present
# 4. 删除特定行
- name: 删除注释行(以 #ServerName 开头)
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^#ServerName'
state: absent
2.4 blockinfile 模块(多行编辑)
yaml
复制代码
- name: blockinfile 模块示例
hosts: dbservers
tasks:
# 1. 添加多行文本块
- name: 添加数据库配置块
blockinfile:
path: /etc/my.cnf
block: |
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
max_connections=1000
state: present
marker: "# {mark} ANSIBLE MANAGED BLOCK" # 标记注释(默认)
create: no # 不创建文件(文件不存在则报错)
# 2. 替换现有文本块
- name: 替换防火墙规则块
blockinfile:
path: /etc/firewalld/zones/public.xml
block: |
<rule family="ipv4">
<source address="192.168.108.0/24"/>
<service name="mysql"/>
<accept/>
</rule>
regexp: '<rule family="ipv4">.*<service name="mysql"/>.*</rule>'
state: present
2.5 fetch 模块(拉取文件)
yaml
复制代码
- name: fetch 模块示例
hosts: webservers
tasks:
# 拉取受管节点的 HTTPD 访问日志到控制节点
- name: 收集访问日志
fetch:
src: /var/log/httpd/access_log
dest: ./logs/ # 控制节点存储路径(自动创建 主机名/var/log/httpd/ 目录)
flat: no # 保留原目录结构(默认 no)
2.6 synchronize 模块(rsync 同步)
yaml
复制代码
- name: synchronize 模块示例
hosts: webservers
tasks:
# 同步控制节点的网站代码到受管节点
- name: 同步网站代码
synchronize:
src: ./website/
dest: /var/www/html/
delete: yes # 删除远程节点不存在的文件(保持一致)
rsync_opts:
- "--exclude=.git" # 排除 .git 目录
- "--exclude=*.log" # 排除日志文件
九、Ansible 最佳实践与使用场景
1. 最佳实践
- 版本控制:将 Playbook、清单、变量文件、角色等纳入 Git 管理,提交时添加清晰注释
- 模块化设计:复杂任务拆分为多个 Play,公共功能提取为角色(Role),提高复用性
- 变量分离:敏感变量用 Ansible Vault 加密,普通变量按环境(开发 / 测试 / 生产)拆分
- 幂等性优先 :所有任务必须保证幂等(如使用
state: present 而非 state: started)
- 事实合理使用:利用事实变量适配不同主机环境(如根据操作系统选择包管理器)
- 日志与监控:开启 Ansible 日志,结合 Prometheus/Grafana 监控自动化执行状态
- 测试先行 :新 Playbook 先在测试环境执行,用
-C 空运行验证,再推广到生产
- 最小权限原则 :远程连接用户使用普通用户,通过
become 提升权限,避免直接使用 root
2. 核心使用场景
- 配置管理:统一管理服务器配置文件、用户、组、服务、防火墙规则
- 应用部署:自动化部署 Web 应用(如 Apache/NGINX)、数据库(MySQL/MariaDB)、中间件(Tomcat)
- 批量操作:批量安装软件、执行命令、更新系统、重启服务
- 生命周期编排:从服务器初始化(操作系统安装、基础配置)到应用上线的全流程自动化
- 网络自动化:配置路由器、交换机、防火墙等网络设备(Cisco、Juniper、华为等)
- 安全与合规:自动化安全基线配置、漏洞扫描、合规检查(如 SELinux 配置、密码策略)
- 灾备恢复:自动化数据备份、备份验证、恢复流程
- 云平台集成:与 OpenStack、Kubernetes、AWS 等云平台集成,实现云资源自动化管理
3. 常见问题与注意事项
- SSH 连接问题 :确保受管节点 SSH 服务正常,控制节点能免密登录,关闭
host_key_checking
- Python 依赖:Linux 受管节点必须安装 Python(大部分模块依赖),Windows 节点需安装 PowerShell 3.0+
- 权限问题 :确保远程用户有
sudo 权限且无需密码(become_ask_pass = False)
- 模块兼容性 :部分模块仅支持特定系统(如
yum 仅支持 RedHat 系,apt 仅支持 Debian 系)
- 变量引用问题 :变量作为值的第一个元素时必须加引号(如
name: "{``{ user }}")
- 中文编码问题:Playbook 和变量文件建议使用 UTF-8 编码,避免中文乱码
十、总结
Ansible 是一款简单、强大、灵活的自动化工具,核心优势在于无代理架构、易用的 YAML 语法和丰富的模块生态。通过 Playbook 实现 "基础架构即代码",可覆盖从单机配置到集群部署的全场景自动化,是 DevOps 实践的核心工具之一。
掌握 Ansible 的关键在于:理解核心概念(清单、Playbook、变量、模块)、熟练使用常用模块、遵循幂等性和模块化设计原则,并结合版本控制和加密工具保障自动化的安全性和可维护性。