Ansible教程
5分钟阅读
Ansible 基础概念
什么是 Ansible
Ansible 是一个开源的自动化运维工具,由 Red Hat 公司维护。它可以帮助我们实现:
- 配置管理:统一管理服务器配置
- 应用部署:自动化应用程序部署
- 任务执行:批量执行系统任务
- 编排协调:复杂工作流程自动化
核心特性
1. 无代理架构(Agentless)
- 不需要在目标主机上安装客户端
- 通过 SSH 连接进行管理
- 减少系统资源消耗
2. 简单易用
- 使用 YAML 语法编写配置
- 人类可读的配置文件
- 学习曲线平缓
3. 幂等性
- 多次执行相同操作结果一致
- 避免重复配置导致的问题
- 确保系统状态的一致性
4. 模块化设计
- 丰富的内置模块
- 支持自定义模块开发
- 社区贡献的模块生态
核心组件
1. Control Node(控制节点)
- 安装 Ansible 的机器
- 执行 Playbook 和命令
- 管理 Inventory 和配置
2. Managed Nodes(被管理节点)
- 被 Ansible 管理的目标主机
- 通过 SSH 连接
- 不需要安装 Ansible
3. Inventory(主机清单)
- 定义被管理的主机列表
- 支持静态和动态清单
- 可以分组管理主机
4. Modules(模块)
- 执行具体任务的代码单元
- 如文件操作、服务管理等
- 支持各种操作系统和应用
5. Playbooks(剧本)
- 定义自动化任务的 YAML 文件
- 包含一系列 plays 和 tasks
- 描述期望的系统状态
6. Roles(角色)
- 可重用的 Playbook 组件
- 按功能组织任务和配置
- 便于分享和维护
工作原理
graph LR
A[Control Node] --> B[SSH Connection]
B --> C[Managed Node 1]
B --> D[Managed Node 2]
B --> E[Managed Node N]
A --> F[Inventory]
A --> G[Playbook]
A --> H[Modules]
执行流程
- 读取 Inventory:确定目标主机
- 解析 Playbook:理解要执行的任务
- 建立连接:通过 SSH 连接目标主机
- 传输模块:将 Python 模块传输到目标主机
- 执行任务:在目标主机上执行模块
- 收集结果:返回执行结果到控制节点
- 清理临时文件:删除临时文件
安装 Ansible
系统要求
控制节点要求:
- Python 3.8 或更高版本
- Linux 或 macOS 系统
- 不支持 Windows 作为控制节点
被管理节点要求:
- Python 2.7 或 3.5+
- SSH 服务
- 支持 Linux、Windows、macOS
安装方法
1. 使用包管理器安装
Ubuntu/Debian:
sudo apt update
sudo apt install ansible
CentOS/RHEL:
sudo yum install epel-release
sudo yum install ansible
macOS:
brew install ansible
2. 使用 pip 安装
# 安装最新版本
pip install ansible
# 安装指定版本
pip install ansible==6.0.0
# 升级 Ansible
pip install --upgrade ansible
3. 从源码安装
git clone https://github.com/ansible/ansible.git
cd ansible
make install
验证安装
# 查看版本信息
ansible --version
# 查看配置信息
ansible-config dump
# 测试连接
ansible localhost -m ping
基本配置
1. 配置文件位置
Ansible 按以下顺序查找配置文件:
ANSIBLE_CONFIG环境变量指定的文件- 当前目录下的
ansible.cfg - 用户家目录下的
~/.ansible.cfg - 系统配置文件
/etc/ansible/ansible.cfg
2. 基本配置示例
[defaults]
# 默认主机清单文件
inventory = ./inventory
# 默认远程用户
remote_user = ansible
# SSH 私钥文件
private_key_file = ~/.ssh/id_rsa
# 禁用主机密钥检查
host_key_checking = False
# 并发连接数
forks = 10
# 日志文件
log_path = ./ansible.log
[ssh_connection]
# SSH 连接超时时间
timeout = 30
# 启用 SSH 管道
pipelining = True
3. 环境变量
# 配置文件路径
export ANSIBLE_CONFIG=/path/to/ansible.cfg
# 主机清单文件
export ANSIBLE_INVENTORY=/path/to/inventory
# 远程用户
export ANSIBLE_REMOTE_USER=ansible
# SSH 私钥
export ANSIBLE_PRIVATE_KEY_FILE=~/.ssh/id_rsa
第一个 Ansible 命令
1. 创建主机清单
# inventory 文件
[webservers]
web1.example.com
web2.example.com
[databases]
db1.example.com
db2.example.com
[all:vars]
ansible_user=ansible
ansible_ssh_private_key_file=~/.ssh/id_rsa
2. 测试连接
# 测试所有主机连接
ansible all -m ping
# 测试特定组
ansible webservers -m ping
# 测试单个主机
ansible web1.example.com -m ping
3. 执行简单命令
# 查看系统信息
ansible all -m setup
# 执行 shell 命令
ansible webservers -m shell -a "uptime"
# 安装软件包
ansible webservers -m yum -a "name=nginx state=present" --become
Ansible 与其他工具对比
1. Ansible vs Puppet
| 特性 | Ansible | Puppet |
|---|---|---|
| 架构 | 无代理 | 需要代理 |
| 配置语言 | YAML | Ruby DSL |
| 学习曲线 | 平缓 | 陡峭 |
| 执行方式 | 推送模式 | 拉取模式 |
| 适用场景 | 快速部署、临时任务 | 大规模配置管理 |
2. Ansible vs Chef
| 特性 | Ansible | Chef |
|---|---|---|
| 配置复杂度 | 简单 | 复杂 |
| 代理要求 | 无需代理 | 需要代理 |
| 配置文件 | YAML | Ruby |
| 社区支持 | 活跃 | 活跃 |
| 企业支持 | Red Hat | Progress |
3. Ansible vs SaltStack
# Ansible 示例
- name: Install nginx
yum:
name: nginx
state: present
# SaltStack 示例(对比)
# nginx:
# pkg.installed
实际应用场景
1. 基础设施即代码(IaC)
# infrastructure.yml
---
- name: Infrastructure as Code
hosts: localhost
tasks:
- name: Create AWS EC2 instances
ec2:
key_name: mykey
instance_type: t2.micro
image: ami-12345678
wait: yes
count: 3
vpc_subnet_id: subnet-12345678
assign_public_ip: yes
- name: Add instances to inventory
add_host:
name: "{{ item.public_ip }}"
groups: webservers
loop: "{{ ec2.instances }}"
2. 配置漂移检测
# drift_detection.yml
---
- name: Configuration drift detection
hosts: all
tasks:
- name: Check nginx configuration
stat:
path: /etc/nginx/nginx.conf
checksum_algorithm: md5
register: nginx_config
- name: Compare with baseline
fail:
msg: "Configuration drift detected!"
when: nginx_config.stat.checksum != expected_checksum
3. 灾难恢复自动化
# disaster_recovery.yml
---
- name: Disaster recovery procedure
hosts: backup_servers
serial: 1
tasks:
- name: Stop application services
service:
name: "{{ item }}"
state: stopped
loop: "{{ app_services }}"
- name: Restore from backup
unarchive:
src: "{{ backup_location }}/{{ backup_file }}"
dest: "{{ app_directory }}"
remote_src: yes
- name: Start services
service:
name: "{{ item }}"
state: started
loop: "{{ app_services }}"
开发环境搭建
1. 使用 Vagrant 搭建测试环境
# Vagrantfile
Vagrant.configure("2") do |config|
# 定义多个虚拟机
(1..3).each do |i|
config.vm.define "web#{i}" do |web|
web.vm.box = "centos/7"
web.vm.network "private_network", ip: "192.168.56.#{10+i}"
web.vm.hostname = "web#{i}.local"
# 配置 SSH
web.vm.provision "shell", inline: <<-SHELL
# 添加 ansible 用户
useradd ansible
echo "ansible ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ansible
# 配置 SSH 密钥
mkdir -p /home/ansible/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2E..." > /home/ansible/.ssh/authorized_keys
chown -R ansible:ansible /home/ansible/.ssh
chmod 700 /home/ansible/.ssh
chmod 600 /home/ansible/.ssh/authorized_keys
SHELL
end
end
end
2. Docker 测试环境
# Dockerfile.ansible-target
FROM centos:7
# 安装 SSH 和 Python
RUN yum update -y && \
yum install -y openssh-server python3 sudo && \
yum clean all
# 配置 SSH
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && \
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' && \
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ''
# 创建 ansible 用户
RUN useradd -m ansible && \
echo "ansible ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/ansible && \
mkdir -p /home/ansible/.ssh
# 复制公钥
COPY ansible_rsa.pub /home/ansible/.ssh/authorized_keys
RUN chown -R ansible:ansible /home/ansible/.ssh && \
chmod 700 /home/ansible/.ssh && \
chmod 600 /home/ansible/.ssh/authorized_keys
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
# 构建和运行测试容器
docker build -t ansible-target -f Dockerfile.ansible-target .
docker run -d --name test-node1 -p 2221:22 ansible-target
docker run -d --name test-node2 -p 2222:22 ansible-target
3. 测试清单配置
# test-inventory
[test_nodes]
test-node1 ansible_host=localhost ansible_port=2221 ansible_user=ansible
test-node2 ansible_host=localhost ansible_port=2222 ansible_user=ansible
[test_nodes:vars]
ansible_ssh_private_key_file=~/.ssh/ansible_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
企业级部署考虑
1. 高可用性配置
# ha_setup.yml
---
- name: Setup Ansible Tower HA
hosts: tower_nodes
tasks:
- name: Install PostgreSQL cluster
include_role:
name: postgresql_ha
- name: Configure shared storage
mount:
path: /var/lib/awx
src: "{{ nfs_server }}:/var/lib/awx"
fstype: nfs
state: mounted
- name: Setup load balancer
template:
src: haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: restart haproxy
2. 监控集成
# monitoring.yml
---
- name: Setup monitoring
hosts: ansible_controllers
tasks:
- name: Install Prometheus node exporter
unarchive:
src: https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz
dest: /opt
remote_src: yes
- name: Create systemd service
template:
src: node_exporter.service.j2
dest: /etc/systemd/system/node_exporter.service
notify:
- reload systemd
- start node_exporter
- name: Configure Ansible callback plugins
lineinfile:
path: /etc/ansible/ansible.cfg
regexp: '^callback_whitelist'
line: 'callback_whitelist = profile_tasks, timer, log_plays'
小结
本章我们学习了:
- Ansible 基本概念:了解了什么是 Ansible 及其核心特性
- 架构组件:掌握了控制节点、被管理节点等核心组件
- 工作原理:理解了 Ansible 的执行流程
- 安装配置:学会了如何安装和配置 Ansible
- 基本使用:执行了第一个 Ansible 命令
- 工具对比:了解了 Ansible 与其他自动化工具的区别
- 应用场景:掌握了实际工作中的应用场景
- 开发环境:学会了搭建测试和开发环境
- 企业部署:了解了企业级部署的考虑因素
下一章我们将学习如何管理 Inventory 主机清单,这是使用 Ansible 的基础。