Ansible Roles 实战全攻略:从零散 Playbook 到可复用项目
来源:zhou | 发布日期:2026-05-26
为什么拆成 Roles
Playbook 膨胀到几百行,变量散落各处,想改个 Nginx 配置翻半天,复用到新项目等于重写——这是从入门到进阶的典型瓶颈。Roles 就是 Ansible 的模块化:安装 Nginx、配置 MySQL、部署 PHP 各放一个 role,主 playbook 一句话调用。
对比:不用 Role vs 用 Role
# ❌ 零散文件,缺乏组织
myproject/
├── install_nginx.yml
├── install_mysql.yml
├── install_php.yml
├── vars.yml # 所有变量混在一起
└── hosts
# ✅ Roles 结构化
myproject/
├── site.yml # 主入口
├── ansible.cfg # 项目级配置
├── inventory/
│ ├── hosts
│ └── group_vars/
│ ├── all.yml
│ └── webservers.yml
├── roles/
│ ├── nginx/
│ │ ├── tasks/main.yml
│ │ ├── handlers/main.yml
│ │ ├── templates/nginx.conf.j2
│ │ ├── defaults/main.yml
│ │ └── vars/main.yml
│ ├── mysql/
│ └── php/
└── vault/
└── secrets.yml.enc
创建新 role:ansible-galaxy role init nginx,自动生成完整目录骨架。
Ansible Vault 加密
文件级加密
ansible-vault create vault/secrets.yml # 创建并加密
ansible-vault encrypt vars/db_credentials.yml # 加密已有文件
ansible-vault view vault/secrets.yml # 查看(需密码)
ansible-vault edit vault/secrets.yml # 编辑
ansible-vault rekey vault/secrets.yml # 改密码
单变量加密
ansible-vault encrypt_string "MyS3cretP@ss" --name "db_password"
# 输出 !vault| 开头的密文,直接贴到 group_vars 或 vars 中
运行 & Vault ID
ansible-playbook site.yml --ask-vault-pass # 交互式
ansible-playbook site.yml --vault-password-file ~/.vault_pass # CI/CD 推荐
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass # 环境变量
# vault ID 管理多套密码
ansible-vault encrypt --vault-id prod@prompt vault/prod_secrets.yml
ansible-playbook site.yml --vault-id prod@~/.vault_pass_prod
高并发调优(200 台 15 分钟跑完)
| 优化项 | 配置 | 收益 |
|---|---|---|
| 增大 forks | forks=50(默认 5) |
同时并发多台 |
| SSH Pipelining | pipelining=True |
减少连接开销,速度 2-3 倍 |
| SSH 连接复用 | ControlPersist=60s |
减少 TCP 握手 |
| 关掉不必要的 facts | gather_facts: false |
每台省 3-5 秒 |
| Fact 缓存 | fact_caching=jsonfile |
避免重复收集 |
| free 策略 | strategy: free |
机器按自己节奏跑 |
| 分批执行 | serial: "30%" |
生产滚动更新安全 |
实战场景
场景一:LNMP 环境一键安装
用 roles 组织后,主 playbook 干净得不像话:
# site.yml
- hosts: webservers
become: true
roles:
- common
- nginx
- mysql
- php
Nginx role 核心:安装 → 部署模板 → 确保运行。Jinja2 模板使用 {{ nginx_port | default(80) }} 等变量做到环境无关。
MySQL role 核心:安装 → 设 root 密码(从 vault 读取)→ 创建应用库。关键变量如 mysql_root_password 必须从加密的 vault 文件读取,不在 defaults 中明文写死。
PHP role 核心:安装 php + php-fpm + 扩展 → 配置 www.conf。
场景二:LVS + Keepalived 一键部署
LVS 是 Linux 内核级四层负载均衡,搭配 Keepalived 实现 VIP 高可用。我的 Role 完整覆盖 DR 模式部署:
- LVS 主节点:安装 ipvsadm + keepalived,配置 keepalived.conf(DR 模式),设
net.ipv4.ip_forward=1 - LVS 备节点:相同流程,priority 90(主节点 100)
- Real Server:抑制 ARP(
arp_ignore=1, arp_announce=2),VIP 配置到 lo:0,否则客户端会绕过 LVS 直连 Real Server
关键配置:Keepalived 模板用 {% for host in groups["lvs_real_servers"] %} 动态生成 Real Server 列表。
场景三:批量收集服务器信息
- hosts: all
tasks:
- name: Collect server info
ansible.builtin.setup:
gather_subset: ['!all', '!min', 'hostname', 'distribution', 'memory', 'processor', 'network']
- name: Generate report
ansible.builtin.copy:
content: |
Hostname: {{ ansible_hostname }}
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPUs: {{ ansible_processor_vcpus }}
Total Memory: {{ ansible_memtotal_mb }} MB
dest: "/tmp/server_info_{{ ansible_hostname }}.txt"
delegate_to: localhost
快速查看:ansible web01 -m setup -a "filter=*mem*"
场景四:批量 NTP 校时
使用阿里云 NTP 源(国内延迟更低),含强制立即校时:
- name: Force immediate time sync
ansible.builtin.command: chronyc -a makestep
changed_when: false
场景五:裸服务器一键初始化
一个 playbook 完成 13 步:主机名 → DNS → 基础工具(vim/wget/curl/htop/sysstat 等)→ 创建运维用户 → sudo 免密 → SSH 公钥 → 关 SELinux → 关 firewalld → 内核参数调优(fs.file-max/net.core.somaxconn/vm.swappiness 等)→ 时区 → NTP → 远程 syslog → 清理无用服务(postfix/abrt)。
配套变量文件用 group_vars + vault,新机器批量上架效率极高。
实用脚本速查
| 脚本 | 一句话 | 运行方式 |
|---|---|---|
| 批量改 root 密码 | change_root_password.yml |
-e "new_root_password=..." --ask-vault-pass |
| 批量部署 SSH 密钥 | deploy_ssh_keys.yml |
支持多用户,禁用 SSH 密码登录 |
| 磁盘使用率告警 | disk_check.yml |
df 超 80% 自动告警 |
| 防火墙规则 | firewall_setup.yml |
批量开放/关闭端口 |
| Docker 安装 | docker_install.yml |
安装 CE + 添加用户到 docker 组 |
总结
核心三句话:结构先行——拆成 roles 按模块组织;安全第一——密码走 Vault;性能调优——forks、pipelining、fact 缓存几个配置一改效率翻倍。
关联页面
| 页面 | 关联点 |
|---|---|
| jenkins-ansible-integration-guide | Jenkins + Ansible 集成实战(本文互补:Roles 代码组织 vs CI/CD 工具链) |
| ops-automation-scripts | 运维自动化脚本合集 |
| devops-interview-guide | DevOps 面试指南(Ansible 面试题) |
| linux-essential-commands-reference | Linux 常用命令参考 |
| docker-production-pitfalls | Docker 生产级实践 |