在运维自动化的实践中,Ansible 凭借其无代理架构、易读的 YAML 语法和强大的模块生态,成为配置管理和应用部署的首选工具。本文将从 Inventory 详解、ansible.cfg 核心配置、Playbook 语法、Roles 目录结构 以及 Ansible Vault 加密 五个方面,深入探讨 Ansible 的进阶用法,并提供完整可用的 Playbook 示例。
一、Inventory 详解:从静态清单到动态分组
Inventory(清单)定义了 Ansible 管理的主机列表。除了基础的 hosts 文件,进阶用法包括变量定义、分组嵌套和动态 Inventory。
1.1 基础格式与分组
默认 Inventory 文件位于 /etc/ansible/hosts,支持 INI 和 YAML 两种格式。
INI 格式示例 (inventory.ini):
[webservers] web1.example.com web2.example.com ansible_host=192.168.1.10 ansible_user=deploy [dbservers] db1.example.com ansible_port=2222 ansible_ssh_private_key_file=~/.ssh/db_key [all:vars] ansible_python_interpreter=/usr/bin/python3
YAML 格式示例 (inventory.yml):
all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
ansible_host: 192.168.1.10
ansible_user: deploy
dbservers:
hosts:
db1.example.com:
ansible_port: 2222
ansible_ssh_private_key_file: ~/.ssh/db_key
vars:
ansible_python_interpreter: /usr/bin/python3
1.2 变量定义与继承
变量可以在 Inventory 的多个层级定义,优先级从低到高为:组变量 → 主机变量 → Playbook 变量 → 命令行变量。
[atlanta] host1 http_port=80 maxRequestsPerChild=808 host2 http_port=303 [atlanta:vars] ntp_server=ntp.atlanta.example.com proxy=proxy.atlanta.example.com [raleigh] host3 host4 [southeast:children] atlanta raleigh [southeast:vars] some_server=foo.southeast.example.com
1.3 动态 Inventory
当主机数量庞大或云环境变化频繁时,可使用动态 Inventory 脚本。Ansible 支持 AWS EC2、OpenStack、VMware 等云平台的动态 Inventory。
# 使用 aws_ec2 插件(需安装 boto3)
ansible-inventory -i aws_ec2.yml --graph
# aws_ec2.yml 配置示例
plugin: aws_ec2
regions:
- us-east-1
keyed_groups:
- key: tags
prefix: tag
filters:
instance-state-name: running
二、ansible.cfg 核心配置
ansible.cfg 是 Ansible 的行为控制器,按优先级查找顺序为:ANSIBLE_CONFIG 环境变量 → ./ansible.cfg → ~/.ansible.cfg → /etc/ansible/ansible.cfg。
2.1 常用配置项
[defaults] # 并发执行数量 forks = 20 # 默认 Inventory 路径 inventory = ./inventory.ini # SSH 连接超时 timeout = 30 # 是否收集 Facts gathering = smart # 远程用户 remote_user = ansible # 日志路径 log_path = /var/log/ansible.log # 主机密钥检查(建议关闭) host_key_checking = False # 模块语言 module_lang = en_US.UTF-8 # 回调插件 stdout_callback = yaml # 仅显示变更 display_skipped_hosts = no [ssh_connection] # 使用 SSH 连接复用加速 ssh_args = -o ControlMaster=auto -o ControlPersist=60s # 管道模式(加速文件传输) pipelining = True [privilege_escalation] # 特权升级方式 become = True become_method = sudo become_user = root become_ask_pass = False
2.2 多环境配置策略
通过 ansible.cfg 的 inventory 和 remote_user 等参数,可以快速切换不同环境:
# 开发环境 export ANSIBLE_CONFIG=./dev.cfg # 生产环境 export ANSIBLE_CONFIG=./prod.cfg
三、Playbook 语法进阶
Playbook 是 Ansible 的核心,使用 YAML 描述配置状态。以下示例展示 tasks、handlers、variables 和 templates 的协同使用。
3.1 完整 Playbook 示例:部署 Nginx + PHP 应用
---
- name: 部署 Web 应用
hosts: webservers
become: yes
vars:
app_name: "myapp"
app_version: "1.2.3"
nginx_port: 80
php_version: "7.4"
# 加密变量通过 Vault 注入
db_password: "{{ vault_db_password }}"
tasks:
# 1. 安装系统依赖
- name: 安装 Nginx 和 PHP
apt:
name:
- nginx
- php{{ php_version }}-fpm
- php{{ php_version }}-mysql
state: present
update_cache: yes
# 2. 创建应用目录
- name: 创建应用部署目录
file:
path: "/var/www/{{ app_name }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
# 3. 部署 Nginx 配置文件(使用模板)
- name: 配置 Nginx 虚拟主机
template:
src: nginx.conf.j2
dest: "/etc/nginx/sites-available/{{ app_name }}"
notify: 重载 Nginx
# 4. 启用站点
- name: 启用 Nginx 站点
file:
src: "/etc/nginx/sites-available/{{ app_name }}"
dest: "/etc/nginx/sites-enabled/{{ app_name }}"
state: link
notify: 重载 Nginx
# 5. 部署应用代码(从 Git 仓库拉取)
- name: 从 Git 部署应用代码
git:
repo: "https://github.com/example/{{ app_name }}.git"
dest: "/var/www/{{ app_name }}"
version: "v{{ app_version }}"
force: yes
register: git_result
# 6. 配置应用环境变量
- name: 设置应用环境变量
copy:
content: |
DB_HOST=localhost
DB_USER=app_user
DB_PASSWORD={{ db_password }}
dest: "/var/www/{{ app_name }}/.env"
owner: www-data
group: www-data
mode: '0600'
when: git_result.changed
# 7. 确保 PHP-FPM 运行
- name: 启动 PHP-FPM 服务
service:
name: "php{{ php_version }}-fpm"
state: started
enabled: yes
handlers:
- name: 重载 Nginx
service:
name: nginx
state: reloaded
3.2 模板文件示例 (`nginx.conf.j2`)
server {
listen {{ nginx_port }};
server_name {{ ansible_fqdn }};
root /var/www/{{ app_name }}/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php{{ php_version }}-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
四、Roles 目录结构与复用
Roles 是 Playbook 的模块化封装,遵循标准目录结构便于复用和分享。
4.1 标准 Roles 目录结构
roles/
└── nginx/
├── defaults/ # 默认变量(最低优先级)
│ └── main.yml
├── vars/ # 覆盖变量(高优先级)
│ └── main.yml
├── tasks/ # 主要任务(必须)
│ └── main.yml
├── handlers/ # 处理器
│ └── main.yml
├── templates/ # Jinja2 模板
│ └── nginx.conf.j2
├── files/ # 静态文件
│ └── index.html
├── meta/ # Role 依赖关系
│ └── main.yml
└── tests/ # 测试文件
├── inventory
└── test.yml
4.2 使用 Role 的 Playbook
---
- name: 应用 Role 部署
hosts: webservers
become: yes
roles:
- role: common
vars:
ntp_server: "pool.ntp.org"
- role: nginx
nginx_port: 8080
- role: php-fpm
php_version: "8.1"
- role: app_deploy
app_name: "myapp"
app_version: "2.0.0"
4.3 Role 依赖管理 (`meta/main.yml`)
dependencies:
- role: common
vars:
packages:
- curl
- git
- role: firewall
vars:
open_ports:
- 80
- 443
五、Ansible Vault 加密
Vault 用于加密敏感数据(密码、密钥、证书),支持文件级和变量级加密。
5.1 基本操作
# 创建加密文件 ansible-vault create secrets.yml # 编辑加密文件 ansible-vault edit secrets.yml # 加密已有文件 ansible-vault encrypt credentials.yml # 解密文件 ansible-vault decrypt credentials.yml --output=decrypted.yml # 更改密码 ansible-vault rekey secrets.yml
5.2 在 Playbook 中使用 Vault
加密变量文件 (vars/vault.yml):
vault_db_password: "SuperSecret123!" vault_api_key: "sk-abc123def456"
Playbook 引用加密变量:
---
- name: 使用 Vault 变量
hosts: all
vars_files:
- vars/main.yml
- vars/vault.yml # 加密文件
tasks:
- name: 创建数据库用户
mysql_user:
name: app_user
password: "{{ vault_db_password }}"
state: present
执行时提供密码:
# 交互式输入密码 ansible-playbook deploy.yml --ask-vault-pass # 使用密码文件 ansible-playbook deploy.yml --vault-password-file vault_pass.txt # 使用环境变量(需设置 ANSIBLE_VAULT_PASSWORD_FILE) export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass ansible-playbook deploy.yml
5.3 加密单个变量(Inline Vault)
vars:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336... # 加密后的内容
总结
本文从 Inventory 的灵活分组、ansible.cfg 的性能调优,到 Playbook 的完整示例、Roles 的模块化复用,再到 Vault 的安全加密,系统梳理了 Ansible 进阶配置的核心要点。掌握这些技巧后,你可以:
• **通过 Inventory 变量继承** 管理多环境差异
• **利用 ansible.cfg 优化** 大规模并发执行
• **编写模块化 Playbook** 实现幂等部署
• **构建标准 Roles** 促进团队协作
• **使用 Vault 保护敏感数据** 确保安全合规
建议将这些实践融入日常运维流程,并配合 CI/CD 工具(如 Jenkins、GitLab CI)实现完全自动化的配置管理。
