1. Ansible Playbook 快速实施指南
作为运维工程师,我使用 Ansible 已有五年多时间,从最初的简单任务到现在的全栈自动化部署,Playbook 一直是我的得力助手。今天我想分享一套经过实战检验的 Ansible Playbook 快速实施方法,特别适合刚接触 Ansible 的同行快速上手。
2. 主机清单配置与管理
2.1 静态清单的实战应用
在实际项目中,我通常会在项目根目录创建 inventory 目录来存放清单文件,而不是使用默认的 /etc/ansible/hosts。这样做有几个好处:版本控制友好、多环境隔离、便于团队协作。
一个典型的生产环境清单文件可能长这样:
ini复制[web_servers]
web01.example.com ansible_host=192.168.1.101
web02.example.com ansible_host=192.168.1.102
web[03:05].example.com ansible_host=192.168.1.[103:105]
[db_servers]
db01.example.com
db02.example.com
[production:children]
web_servers
db_servers
[all:vars]
ansible_user=deploy
ansible_port=2222
注意:使用主机名时,请确保 DNS 解析正常或在
/etc/hosts中有相应配置。我习惯同时指定ansible_host作为备用连接方式。
2.2 动态清单的实用技巧
虽然静态清单适合大多数场景,但在云环境中动态清单更为实用。我曾为一个 AWS 项目编写过这样的动态清单脚本:
python复制#!/usr/bin/env python3
import boto3
import json
ec2 = boto3.client('ec2')
response = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
instances = {
'_meta': {
'hostvars': {}
},
'web': {
'hosts': [],
'vars': {
'ansible_user': 'ubuntu'
}
}
}
for reservation in response['Reservations']:
for instance in reservation['Instances']:
for tag in instance.get('Tags', []):
if tag['Key'] == 'Role' and tag['Value'] == 'web':
instances['web']['hosts'].append(instance['PrivateDnsName'])
instances['_meta']['hostvars'][instance['PrivateDnsName']] = {
'ansible_host': instance['PublicIpAddress']
}
print(json.dumps(instances))
这个脚本会输出 JSON 格式的清单,Ansible 可以直接使用。记得给脚本添加可执行权限,并通过 -i 参数指定。
3. 配置管理最佳实践
3.1 ansible.cfg 的优化配置
经过多次项目实践,我发现以下配置组合既安全又高效:
ini复制[defaults]
inventory = ./inventory/production
host_key_checking = False
retry_files_enabled = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./facts_cache
fact_caching_timeout = 86400
stdout_callback = yaml
bin_ansible_callbacks = True
[privilege_escalation]
become = False
become_method = sudo
become_user = root
become_ask_pass = False
关键点说明:
host_key_checking = False可以避免首次连接时的确认提示,但在生产环境应配合 SSH 指纹验证使用- 启用 fact 缓存可以显著提升 Playbook 执行速度,特别是当任务需要频繁获取系统信息时
- 我推荐使用
yaml输出格式,比默认的default更易读
3.2 SSH 连接优化
在管理大量服务器时,SSH 连接性能至关重要。我通常会做以下优化:
-
在
~/.ssh/config中添加:code复制Host * ControlMaster auto ControlPath ~/.ssh/ansible-%r@%h:%p ControlPersist 10m ServerAliveInterval 60 -
使用
ssh-agent管理密钥:bash复制eval $(ssh-agent) ssh-add ~/.ssh/deploy_key -
对于大规模环境,可以调整 Ansible 的 forks 参数(默认是 5):
ini复制[defaults] forks = 50
4. Playbook 编写实战技巧
4.1 结构化 Playbook 项目
我建议采用这样的目录结构:
code复制project/
├── inventory/
│ ├── production
│ └── staging
├── group_vars/
│ ├── all/
│ │ └── vars.yml
│ └── web_servers/
│ └── vars.yml
├── host_vars/
│ └── web01.example.com.yml
├── roles/
│ ├── common/
│ ├── nginx/
│ └── mysql/
└── site.yml
这种结构的好处是:
- 变量分层管理(全局→组→主机)
- 角色复用方便
- 环境隔离清晰
4.2 编写健壮的 Playbook
一个生产级的 Playbook 示例:
yaml复制---
- name: 配置 Web 服务器
hosts: web_servers
any_errors_fatal: true
serial: "30%"
vars:
http_port: 80
max_clients: 200
pre_tasks:
- name: 检查磁盘空间
ansible.builtin.command: df -h
register: df_output
changed_when: false
tags: always
roles:
- role: common
vars:
timezone: Asia/Shanghai
- role: nginx
when: "'nginx' in group_names"
tasks:
- name: 确保 Nginx 服务运行
ansible.builtin.service:
name: nginx
state: started
enabled: yes
notify: reload nginx
handlers:
- name: reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
关键特性:
serial控制滚动更新比例pre_tasks用于前置检查any_errors_fatal确保失败立即停止- 使用 handlers 处理服务重载
5. 高级技巧与故障排查
5.1 条件执行与错误处理
在实际运维中,条件判断必不可少:
yaml复制- name: 仅当内存大于4G时安装Redis
ansible.builtin.apt:
name: redis-server
state: present
when: ansible_memtotal_mb > 4096
- name: 安全更新系统
ansible.builtin.apt:
upgrade: dist
autoremove: yes
ignore_errors: yes
register: update_result
changed_when: "'upgraded' in update_result.stdout"
5.2 常见问题排查
-
连接问题:
bash复制
ansible -i inventory/production all -m ping -vvv加
-vvv可以看到详细的 SSH 连接过程 -
模块执行问题:
bash复制
ANSIBLE_DEBUG=1 ansible-playbook site.yml这会输出模块执行的底层细节
-
变量调试:
yaml复制- name: 显示变量值 ansible.builtin.debug: var: ansible_facts tags: debug
5.3 性能优化
-
启用 pipelining(在 ansible.cfg 中):
ini复制[defaults] pipelining = True -
使用 mitogen 插件(能提升 2-7 倍速度):
ini复制[defaults] strategy_plugins = /path/to/mitogen/ansible_mitogen/plugins/strategy strategy = mitogen_linear -
对静态内容使用
copy模块的validate参数,避免不必要的文件传输
6. 实际项目经验分享
在最近的一个电商平台项目中,我们使用 Ansible 管理着 200+ 服务器。以下是一些实战经验:
-
金丝雀发布:
通过清单分组实现:yaml复制- name: 金丝雀发布 hosts: canary_web_servers serial: 1 tasks: - include_role: name: deploy vars: version: "{{ canary_version }}" - name: 全量发布 hosts: web_servers:!canary_web_servers serial: "20%" tasks: - include_role: name: deploy vars: version: "{{ stable_version }}" -
配置漂移检测:
使用ansible.builtin.template的diff参数:yaml复制- name: 应用 Nginx 配置 ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf diff: yes notify: reload nginx -
敏感数据管理:
使用 Ansible Vault 加密:bash复制
ansible-vault encrypt group_vars/production/secrets.yml执行时:
bash复制
ansible-playbook site.yml --ask-vault-pass
通过这些实践,我们的部署时间从原来的 2 小时缩短到 15 分钟,配置错误率降低了 90%。Ansible Playbook 的可重复性和幂等性确实为运维工作带来了革命性的改变。