Ansible架构与核心概念
Ansible是无代理(Agentless)的自动化运维工具,通过SSH连接目标主机执行任务,无需在远端安装任何客户端。其核心架构包括:Inventory(主机清单,定义管理目标)、Module(功能模块,执行具体操作)、Playbook(YAML编排,定义任务流程)、Role(角色,组织复用Playbook逻辑)。
与SaltStack/Puppet/Chef相比,Ansible的核心优势是零依赖部署——只需控制端安装,目标端开箱即用。代价是每次执行需建立SSH连接,在大规模并发场景(>1000节点)下性能不如SaltStack的ZeroMQ推送模式。但通过mitogen策略插件和ansible-pull模式可有效弥补。
# ansible.cfg 关键性能配置
[defaults]
inventory = ./inventory
roles_path = ./roles
forks = 50 # 并发进程数
host_key_checking = False # 跳过SSH密钥检查
gathering = smart # 智能facts收集(仅变化时采集)
strategy = mitogen_linear # Mitogen策略(10x加速)
pipelining = True # SSH管道复用
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
# SSH多路复用,减少连接建立开销
动态Inventory:对接云平台与CMDB
静态Inventory文件无法应对云环境主机的动态扩缩容。Ansible支持通过脚本或插件动态生成Inventory:
#!/usr/bin/env python3
"""动态Inventory脚本:从云API获取主机列表"""
import json
import requests
def get_hosts():
# 示例:从自建CMDB获取主机
resp = requests.get("http://cmdb.internal/api/v1/hosts",
headers={"Authorization": "Bearer xxx"})
hosts = resp.json()
inventory = {"_meta": {"hostvars": {}}}
for host in hosts:
group = host["group"] # e.g. web, db, cache
if group not in inventory:
inventory[group] = {"hosts": [], "vars": {}}
inventory[group]["hosts"].append(host["hostname"])
# 主机变量
inventory["_meta"]["hostvars"][host["hostname"]] = {
"ansible_host": host["ip"],
"ansible_port": host.get("ssh_port", 22),
"server_id": host["id"],
"env": host.get("env", "production")
}
return inventory
if __name__ == "__main__":
print(json.dumps(get_hosts(), indent=2))
# inventory 目录结构
inventory/
├── group_vars/
│ ├── web.yml # web组变量
│ └── db.yml # db组变量
├── host_vars/
│ └── db-master.yml # 特定主机变量
└── cloud.yml # 动态Inventory插件配置
# plugin: aws_ec2
# regions:
# - us-east-1
# filters:
# tag:Environment: production
动态Inventory在每次执行时实时查询主机列表,自动适应云实例的创建和销毁。AWS/GCP/Azure/OpenStack都有官方插件支持。
Playbook编写最佳实践
Playbook的质量直接决定自动化运维的可靠性。以下是生产级Playbook的关键实践:
---
# Nginx部署Playbook(含幂等性与错误处理)
- name: Deploy and configure Nginx
hosts: web
become: true
serial: "20%" # 滚动更新,每次20%主机
any_errors_fatal: false # 单台失败不中止全部
pre_tasks:
- name: Validate required variables
assert:
that:
- nginx_port is defined
- nginx_port | int > 0
fail_msg: "nginx_port must be a positive integer"
- name: Check disk space
ansible.builtin.shell: df -h / | tail -1 | awk {print