这是一个面向实战的 Ansible 自动化教程,带你从环境准备、核心概念、到完整 Playbook 与角色实践,逐步掌握主机编排、配置管理与应用发布。文中包含常见命令、模板示例、密码加密、CI 集成与排错要点,力求让你看完就能在小规模和生产环境里稳妥落地,讲得很直接也有一点随想的口气。

为什么选 Ansible?先讲清楚它解决了什么问题
想象一下:你有几十台、几百台服务器,要统一安装软件、修改配置、发布新版本,传统人工和脚本会变得脆弱且难以维护。Ansible 的价值在于它是“无代理”的配置管理与编排工具,使用 SSH(或 WinRM)连接受控节点,通过可读性很强的 YAML Playbook 把操作变成可复现的步骤。
核心优势一览
- 无代理(agentless):只需在控制节点安装 Ansible,受控端无需额外守护进程。
- 可读性强:Playbook 是 YAML,运维与开发都能轻松读懂。
- 丰富模块:覆盖系统包、服务、文件、用户、云平台等常用操作。
- 幂等性:模块设计通常是幂等的,减少重复执行带来的副作用。
先从最简单开始:安装与基本验证
你只需要一台控制节点(常用 Linux)和若干受控主机(Linux/Windows)。控制节点安装 Ansible,受控主机开启 SSH 并能用密钥登录即可。
控制节点安装(常见方案)
- 基于系统包(Ubuntu/Debian):
sudo apt update sudo apt install -y ansible - 基于 pip(更灵活,适用于虚拟环境):
python3 -m venv ~/ansible-venv source ~/ansible-venv/bin/activate pip install --upgrade pip pip install ansible
最小验证:ping 模块
在控制节点上准备好 SSH 密钥互信后,用一个简单命令确认连通性:
ansible all -i inventory.ini -m ping
返回 pong 即表示成功。inventory.ini 可以是:
[web]
10.0.0.10
[db]
10.0.0.20
核心概念:Inventory、Modules、Playbook、Roles、Facts
- Inventory(清单):定义受控主机,支持 INI 与 YAML 格式,可按组管理。
- Module(模块):执行单一操作的代码单元,如 apt、yum、service、copy、template。
- Playbook:一组 Plays(针对主机组的步骤集合),用 YAML 描述自动化流程。
- Role(角色):按职责拆分的 Playbook 单元,便于复用与分享。
- Facts(事实):Ansible 采集的主机信息(CPU、内存、系统类型等),可以做条件判断。
写第一个 Playbook:安装 Nginx 并部署简单页面
我们一步步来,先写个最常见的示例:在 web 组主机上安装 nginx,放置 index.html,启用并启动服务。
目录结构建议
- project/
- inventory.ini
- site.yml
- roles/(后面会讲 Role)
site.yml(示例 Playbook)
- name: deploy nginx web
hosts: web
become: true
tasks:
- name: ensure nginx is installed
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: copy index.html
copy:
dest: /var/www/html/index.html
content: "Hello from Ansible
"
owner: www-data
group: www-data
mode: '0644'
- name: ensure nginx started and enabled
service:
name: nginx
state: started
enabled: true
注意点:用 become: true 提权执行需要 sudo 权限,并且用 Facts 做 OS 家族的条件判断。
Variables(变量)与 Templates(模板)
当配置项需要动态化时,用变量与 Jinja2 模板,可以把 Playbook 写得更通用。
示例:使用模板部署配置
# templates/nginx.conf.j2
server {
listen 80;
server_name {{ server_name | default('localhost') }};
root /var/www/html;
index index.html;
}
- name: deploy nginx with template
hosts: web
vars:
server_name: example.com
tasks:
- name: template nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
notify: reload nginx
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
这里用了 handler:当某个任务改变了文件(状态 changed),才触发 handler,避免不必要的重载。
Roles:把复杂项目拆成模块化单元
当你需要管理多个应用或复杂配置时,用 Role 会让项目更整洁。Role 有固定目录结构:
| roles/myapp/tasks | 主要任务(main.yml) |
| roles/myapp/templates | Jinja2 模板 |
| roles/myapp/vars | 默认变量 |
| roles/myapp/handlers | handlers(如重启服务) |
调用 Role 很简单:
- hosts: web
roles:
- myapp
Secrets 管理:Ansible Vault
配置里可能有密码、私钥,这时候不要把明文放在版本库。Ansible Vault 可以加密文件,执行时解密或传入密码:
ansible-vault create secret.yml
ansible-playbook site.yml --ask-vault-pass
也可以用密码文件或集成 CI 的密钥管理工具。关键是把密钥控制好,避免泄露。
调试与幂等性验证
- –check(dry run):模拟执行,不做实际更改,用来预览改动。
- –diff:配合模板或 copy,可以显示文件差异,帮助审查变更。
- –limit:限定目标主机,避免误跑全网。
ansible-playbook site.yml --check --diff --limit web1.example.com
性能与扩展(当节点很多时)
Ansible 默认并发执行(forks)为 5,可以在 ansible.cfg 或命令行调整:
ansible-playbook -f 50 site.yml
注意过高并发会带来 SSH 连接压力;大规模场景一般配合 AWX/Tower、并使用拉取型或分层配置来分担控制节点负载。
常见模块速查表
| 场景 | 常用模块 |
| 包管理(Debian) | apt |
| 包管理(RHEL) | yum / dnf |
| 服务管理 | service / systemd |
| 文件拷贝 | copy / template |
| 用户/组 | user / group |
| 命令执行 | command / shell |
CI 集成与流水线实践(一个常见流程)
把 Ansible 纳入 CI/CD 时,一般流程是这样的:
- 代码(Playbook/Role)在 Git 仓库中管理,合并前运行静态检查(ansible-lint)与单元测试。
- 在 CI 环境运行 ansible-playbook –check 做干跑验证,或在临时环境执行完整部署并回滚。
- 正式发布由受控的流水线(带密钥管理)触发,或通过 Ansible Tower/AWX 的 Job Template 调度。
常见问题与排错要点(边用边会遇到)
- SSH 连接失败:检查密钥、用户名、SSH port、代理跳板设置。
- 权限不足(sudo):确认 become、become_user 与受控端 sudoers 配置。
- 变量优先级混乱:Ansible 有明确的变量优先级表(Play vars、Host vars、Role defaults 等),遇到问题用
ansible-playbook -vvv查看实际变量。 - 模块不可用或老版本问题:检查控制节点 Ansible 版本与受控节点兼容性,必要时升级或使用兼容模块。
实战小贴士(那些不太写进手册的东西)
- 把 inventory 拆分:按环境分 inventory(prod/stage)、按角色分组,利于权限管理和回滚。
- Role 尽量保持幂等:不要在任务里重复执行会改变系统状态的命令,优先使用模块。
- 模板里使用默认值与类型检查:用 Jinja 的 default 过滤器和条件判断减少空变量导致的错误。
- 对关键任务写单元测试:用 Molecule 做 Role 的本地测试,结合 Docker/Podman 做快速验证。
进阶:动态 Inventory 与云资源
当托管在云上(AWS、Azure、GCP)时,可以用动态 inventory 通过 API 获取主机列表,或者使用 cloud modules 直接创建资源。动态 inventory 的思路是,把 inventory 交给脚本或插件来生成,Playbook 则只关心组名与变量。
示例:把上面的 Nginx 部署包装成 Role(简化示范)
roles/nginx/tasks/main.yml
---
- name: install nginx
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: deploy index
template:
src: index.html.j2
dest: /var/www/html/index.html
notify: restart nginx
roles/nginx/handlers/main.yml
---
- name: restart nginx
service:
name: nginx
state: restarted
然后在 site.yml 中调用 - roles: - nginx。当项目复杂时,把变量放 roles/nginx/vars 或 defaults,模板放 templates,任务里保持短小清晰。
安全与合规注意
- 确保 Ansible 运行用户、Vault 密钥受到严格访问控制。
- 对变更做审计:在 CI 或 AWX 中记录谁触发了哪次 Job 与参数。
- 不要把敏感信息放在 Playbook 明文或公共仓库中。
常见命令速参(记得慢慢熟悉而不是死记)
- 检查版本:
ansible --version - 列主机:
ansible-inventory --list -i inventory.ini - 执行 Playbook:
ansible-playbook -i inventory.ini site.yml - 语法检查:
ansible-playbook --syntax-check site.yml - lint 检查:
ansible-lint roles/
学习路径建议(我通常这样安排)
- 先学基础命令与 Inventory、ad-hoc 命令(ping、shell、copy 等)。
- 掌握 Playbook 的基本结构、变量与模板,写几个示例来巩固。
- 学习 Role,把常见任务抽成可复用模块,开始用 ansible-lint 与 Molecule 做测试。
- 引入 Vault 管理密钥,学习动态 Inventory 与云模块。
- 最后把 Ansible 放进 CI,或部署 AWX/Tower 做作业调度、审计与权限控制。
写到这里,或许有点信息量,但大体思路是:从小处试验、把结果自动化、逐步提炼成 Role 与流水线,再把安全和监控做好。实践中你会遇到各种小坑,但 Ansible 的可读性和丰富模块能让问题变得更易追踪。接下来随手搭一个小型 repo,把 Playbook、Role 和一个测试 inventory 放好,边做边学,反复迭代会越来越顺手。