🚀 Ansible 笔记:构建自动化运维集群(Nginx + HAProxy + Roles)
Contents
1. 实验环境规划
我使用了 3 台虚拟机,操作系统涵盖了 RHEL 系和 Debian 系,以测试 Ansible 对异构系统的兼容性。
1. 实验环境规划
我使用了 3 台虚拟机,操作系统涵盖了 RHEL 系和 Debian 系,以测试 Ansible 对异构系统的兼容性。
| 主机名 | IP 地址 | 角色 | 操作系统 | 备注 |
|---|---|---|---|---|
| Rocky-12 | 10.0.0.12 | 控制节点 (Ansible Server) 负载均衡器 (HAProxy) | Rocky Linux 9 | 指挥官,所有命令在此执行 |
| Ubuntu-13 | 10.0.0.13 | 被控节点 (Web Server) | Ubuntu 24.04 | 运行 Nginx |
| Ubuntu-16 | 10.0.0.16 | 被控节点 (Web Server) | Ubuntu 24.04 | 运行 Nginx |
2. 基础环境配置 (The Foundation)
2.1 安装 Ansible
Ansible 是无代理(Agentless)的,只需要在控制节点安装即可。
| |
2.2 SSH 免密互信 (踩坑记录)
这是 Ansible 通信的基础。
- 踩坑: 一开始使用了
ssh-keygen -p导致报错,后来发现小写-p是修改密码,大写-P才是设置新密码(空密码)。
正确操作:
| |
2.3 构建 Inventory (花名册)
为了不污染系统配置,我在项目目录建立了独立的配置文件。
文件结构: /root/ansible_start/
hosts(清单文件):1 2 3 4 5 6[web] 10.0.0.13 10.0.0.16 [lb] 10.0.0.12ansible.cfg(配置文件):1 2 3[defaults] inventory = ./hosts host_key_checking = False # 关键配置:跳过 SSH 指纹验证
3. Ad-Hoc 命令体验
在写剧本前,先用单行命令测试连接。
- 连通性测试:
1ansible all -m ping - 跨平台安装软件 (混合双打):
使用
package模块,它会自动判断是apt还是yum/dnf。1 2# 批量安装 git ansible web -m package -a "name=git state=present"
4. Playbook 实战:Nginx 差异化部署
我编写了一个剧本,不仅安装 Nginx,还利用 Jinja2 模板实现了“千人千面”的网页效果。
4.1 编写模板 (templates/index.html.j2)
| |
4.2 编写剧本 (deploy.yml)
这里处理了一个难点:Ubuntu 和 Rocky 的 Nginx 默认网页路径不同。我使用了 when 条件判断。
| |
5. 进阶挑战:HAProxy 负载均衡集群
这是本次实验最高光的时刻。我将控制节点(Rocky-12)配置为负载均衡器,自动分发流量给后端的 Web 服务器。
5.1 动态配置模板
难点在于不能把后端 IP 写死。我使用了 Jinja2 的 for 循环遍历 [web] 组。
文件:templates/haproxy.cfg.j2 (核心片段)
| |
5.2 效果验证
部署完成后,访问负载均衡器端口,实现了轮询效果:
| |
6. 架构重构:使用 Roles (角色)
随着 yml 文件越来越多,管理变得混乱。我使用 Ansible Roles 进行了重构。
操作步骤:
- 初始化:
ansible-galaxy init nginx - 拆解:
- 将 tasks 移动到
roles/nginx/tasks/main.yml - 将 templates 移动到
roles/nginx/templates/ - 将 handlers 移动到
roles/nginx/handlers/main.yml
- 将 tasks 移动到
- 主入口 (
site.yml):1 2 3 4--- - hosts: web roles: - nginx
心得: 重构后的代码结构清晰,就像把散乱的衣服整理进了收纳柜,非常适合大规模维护。
7. 安全加固:Ansible Vault
为了不让管理员密码明文暴露,我学习了加密功能。
- 创建加密柜:
1 2 3ansible-vault create secrets.yml # 输入密码:123456 # 内容:admin_pass: "MySecretP@ssword" - 使用加密变量:
在 playbook 中加载
vars_files: secrets.yml。 - 执行:
1ansible-playbook create_user.yml --ask-vault-pass
8. 常见报错与排查 (Troubleshooting)
在学习过程中遇到的几个典型报错,非常具有参考价值:
- [WARNING]: provided hosts list is empty
- 原因: 在非项目目录下执行了
ansible命令,导致读不到hosts文件。 - 解决: 必须进入
ansible.cfg所在的目录操作。
- 原因: 在非项目目录下执行了
- Syntax Error while loading YAML
- 原因: 复制粘贴代码时,缩进错误,或者文件开头多写了
---。 - 解决: YAML 对缩进极其敏感,务必对齐;使用
--syntax-check参数预检。
- 原因: 复制粘贴代码时,缩进错误,或者文件开头多写了
- Command not found (curl)
- 原因: 最小化安装的 Ubuntu 缺少
curl命令。 - 解决: 使用 Ansible 批量补装:
ansible web -m package -a "name=curl state=present"。
- 原因: 最小化安装的 Ubuntu 缺少
结语
通过这次实战,我深刻理解了 Ansible “约定大于配置” 的设计哲学。从简单的命令执行,到复杂的集群编排,Ansible 极大地释放了运维的生产力。