用途
Ansible 是一款开源自动化工具,用于配置 IT 基础设施、部署应用,并通过无代理(agentless)的 YAML playbook 编排任务。它保证幂等操作,即无论初始状态如何,运行都会产生相同结果,并通过 SSH 运行,无需在目标主机上安装代理。
何时使用
在 DevOps 流水线中需要可重复的基础设施任务时使用 Ansible,例如置备服务器、跨主机群管理配置,或在动态环境中部署应用。当你需要无代理自动化时适用,例如更新远程机器上的软件、编排多步骤工作流,或与 CI/CD 工具集成。但应避免将其用于实时监控,此类场景更适合 Prometheus 等工具。
主要能力
- 无代理执行:通过 SSH 或 WinRM 连接;在清单文件(如 /etc/ansible/hosts)中指定主机,支持 [web:children] 等分组格式。
- 幂等 Playbook:编写定义任务的 YAML 文件;例如仅在软件包不存在时安装它的任务。
- 模块与角色:使用内置模块(如 apt 用于包管理);将代码组织为角色以实现复用,存放在 roles/webserver/tasks/main.yml 等目录中。
- 变量与模板:在 YAML 中定义变量(如 { "http_port": 80 }),并使用 Jinja2 模板生成动态配置,例如从模板生成 nginx.conf。
- 编排:通过 play 处理依赖关系,跨主机对任务排序,确保有序执行。
使用方式
要自动化任务,创建一个 playbook(如 site.yml),定义包含 hosts、tasks 和 vars 的 play。使用 ansible-playbook 命令运行它。对于动态清单,使用输出 JSON 的脚本,例如从 AWS EC2 拉取。项目结构通常包含清单文件、用于主机特定变量的 group_vars,以及用于模块化代码的 roles。始终先用 --check 标志测试 playbook,以模拟变更而不实际应用。
常用命令/API
- 运行 Playbook:ansible-playbook site.yml --check --diff 用于模拟并显示变更;添加 -l web 可限制到某个主机组。
- Ad Hoc 命令:ansible web -m ping 测试连通性;使用 -a "uptime" 执行任意命令。
- 管理角色:ansible-galaxy install geerlingguy.apache 拉取角色;使用 ansible-galaxy init role_name 构建自定义角色。
- 清单与变量:通过 -e "var1=value1" 或环境变量设置变量,如 export ANSIBLE_HOST_KEY_CHECKING=False 绕过主机密钥验证。
- API 集成:通过 ansible_runner 库使用 Ansible 的 Python API;例如 import ansible_runner 并运行 interface.run(playbook='site.yml', extravars={'key': 'value'}) 以编程方式执行。
- 认证:使用环境变量,如 $ANSIBLE_PRIVATE_KEY_FILE=/path/to/key.pem 指定 SSH 密钥,或 $ANSIBLE_BECOME_PASS 提供 sudo 密码。
集成说明
通过脚本触发 playbook,将 Ansible 与 Jenkins 等 CI/CD 工具集成;例如在 Jenkinsfile 中:sh 'ansible-playbook deploy.yml -e "env=prod"'。对于云厂商,使用动态清单;例如用 export AWS_ACCESS_KEY_ID=$AWS_KEY 配置 AWS,并运行 ansible-playbook -i ec2.py site.yml。与 Terraform 结合时,在置备后运行 Ansible;确保通过文件或环境变量传递变量。使用版本控制:将 playbook 存储在 Git 中,并在流水线中拉取。
错误处理
在 playbook 中,使用带 rescue 和 always 子句的 block;例如:
- block:
- debug: msg="Task succeeded" rescue:
- debug: msg="Error occurred" always:
- debug: msg="Cleanup step"
检查命令退出码;例如在脚本中:ansible-playbook site.yml && echo "Success" || echo "Failed"。对于常见问题,使用 -vvv 启用详细输出以调试 SSH 连接或模块故障。使用 facts 收集处理变量错误,并对非关键任务设置 ignore_errors: yes,但仅在适当时使用,以免掩盖问题。
具体使用示例
在 Ubuntu 主机上部署 Web 服务器:创建 playbook(webserver.yml),包含安装 Apache 的任务:
- hosts: webservers
tasks:
- name: Install Apache apt: name: apache2 state: present
运行:ansible-playbook webserver.yml -i inventory.txt --become 以提升权限。
为多台主机配置 NTP:编写 playbook(ntp_config.yml)同步时间:
- hosts: all
tasks:
- name: Install NTP yum: name: ntp state: latest
- name: Start NTP service service: name: ntpd state: started
执行:ansible-playbook ntp_config.yml -l ntp_hosts 以针对特定组。
关联关系
- 相关:terraform(基础设施即代码)、kubernetes(容器编排)、jenkins(CI/CD 集成),均属于 devops-sre 集群。
- 依赖:常与 vault 搭配用于密钥管理。
- 冲突:若偏好基于代理的管理,应避免与 Puppet 等工具同时使用。