Ansible运维自动化进阶:从Inventory详解到Playbook实战
在运维自动化的实践中,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)实现完全自动化的配置管理。作为运维自动化的重要工具,Ansible 的强大功能和灵活配置将为你的工作带来极大的便利和效率提升。


暂无评论内容