Ansible 学习指南
一、Ansible 概述
1.1 什么是 Ansible?
- 自动化运维工具:用于配置管理、应用部署、任务自动化
- 无代理架构:通过 SSH 或 WinRM 直接管理节点,无需在目标机器安装客户端
- 声明式语言:使用 YAML 描述系统状态,而非具体操作步骤
- 幂等性:多次执行同一任务,结果保持一致
1.2 核心优势
- 简单易学:YAML 语法直观,学习曲线平缓
- 模块化设计:丰富的内置模块,支持自定义扩展
- 跨平台:支持 Linux、Windows、网络设备等
- 开源免费:Red Hat 支持,社区活跃
二、核心概念
2.1 控制节点 vs 受管节点
- 控制节点:运行 Ansible 的主机
- 受管节点:被管理的主机
2.2 主要组件
- Inventory:主机清单,定义管理哪些主机
- Playbook:任务剧本,YAML 格式的自动化脚本
- Module:执行具体任务的模块
- Task:调用模块执行的操作
- Role:预定义的任务集合,可复用
- Collection:模块、插件、角色的分发单元
三、安装与配置
3.1 安装 Ansible
bash
# Ubuntu/Debian
sudo apt update
sudo apt install ansible
# RHEL/CentOS
sudo yum install ansible
# macOS
brew install ansible
# Python pip 安装
pip install ansible
3.2 基础配置
bash
# 配置文件优先级
1. ANSIBLE_CONFIG 环境变量指定
2. ./ansible.cfg(当前目录)
3. ~/.ansible.cfg(用户目录)
4. /etc/ansible/ansible.cfg(系统目录)
# 最小化配置示例
[defaults]
inventory = ./inventory
host_key_checking = False
四、Inventory(主机清单)
4.1 基本格式
ini
# inventory 文件示例
[webservers]
web1.example.com ansible_ssh_user=root
web2.example.com ansible_port=2222
[databases]
db1.example.com
db2.example.com
[all:vars]
ansible_python_interpreter=/usr/bin/python3
4.2 分组与变量
yaml
# YAML 格式 inventory
all:
hosts:
host1:
ansible_connection: ssh
ansible_user: admin
children:
webservers:
hosts:
web[1:3].example.com:
databases:
hosts:
db[1:2].example.com:
vars:
db_port: 5432
五、Ad-hoc 命令
5.1 基本语法
bash
ansible <pattern> -m <module> -a "<arguments>"
# 示例
ansible webservers -m ping
ansible all -m shell -a "uptime"
ansible db -m apt -a "name=nginx state=present"
5.2 常用模块
bash
# 系统信息
ansible all -m setup # 收集事实
ansible all -m command -a "df -h" # 执行命令
# 软件管理
ansible webservers -m apt -a "name=nginx state=latest"
ansible webservers -m yum -a "name=httpd state=present"
# 文件管理
ansible all -m copy -a "src=/local/file dest=/remote/file"
ansible all -m file -a "path=/tmp/test state=directory"
# 服务管理
ansible webservers -m service -a "name=nginx state=started"
六、Playbook 基础
6.1 Playbook 结构
yaml
---
- name: 配置 Web 服务器
hosts: webservers
become: yes
vars:
http_port: 80
max_clients: 200
tasks:
- name: 安装 Nginx
apt:
name: nginx
state: latest
- name: 复制配置文件
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: 重启 Nginx
handlers:
- name: 重启 Nginx
service:
name: nginx
state: restarted
6.2 核心指令
- name: 任务描述
- hosts: 目标主机
- become: 是否提权
- vars: 定义变量
- tasks: 任务列表
- handlers: 触发任务
- when: 条件判断
- loop: 循环执行
七、变量与事实
7.1 变量定义
yaml
# 多种变量定义方式
vars:
package_name: nginx
port: 80
vars_files:
- vars/main.yml
# 主机变量
# inventory 或 host_vars/ 目录
# 组变量
# inventory 或 group_vars/ 目录
7.2 事实收集
yaml
# 查看所有事实
- debug:
var: ansible_facts
# 常用事实
- debug:
var: ansible_distribution
- debug:
var: ansible_ip_addresses
- debug:
var: ansible_memory_mb
八、条件、循环和错误处理
8.1 条件判断
yaml
tasks:
- name: 重启服务(仅当 CentOS)
service:
name: httpd
state: restarted
when: ansible_os_family == "RedHat"
- name: 多种条件
command: /bin/false
register: result
ignore_errors: yes
- debug:
msg: "命令失败"
when: result.failed
8.2 循环
yaml
tasks:
- name: 添加多个用户
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie
- name: 带字典的循环
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
loop:
- { name: 'user1', uid: 1001 }
- { name: 'user2', uid: 1002 }
九、Roles 和 Collections
9.1 Role 结构
roles/
└── nginx/
├── defaults/
│ └── main.yml # 默认变量
├── tasks/
│ └── main.yml # 主要任务
├── handlers/
│ └── main.yml # 处理器
├── templates/
│ └── nginx.conf.j2 # 模板文件
├── files/
├── vars/
│ └── main.yml # 变量定义
└── meta/
└── main.yml # 依赖信息
9.2 使用 Role
yaml
# playbook.yml
- hosts: webservers
roles:
- role: nginx
vars:
nginx_port: 8080
十、模板和文件管理
10.1 Jinja2 模板
jinja2
# nginx.conf.j2
server {
listen {{ http_port }};
server_name {{ server_name }};
{% if ssl_enabled %}
ssl_certificate {{ ssl_cert }};
ssl_certificate_key {{ ssl_key }};
{% endif %}
location / {
proxy_pass http://backend;
}
}
10.2 文件操作模块
yaml
tasks:
- name: 复制文件
copy:
src: files/app.conf
dest: /etc/app.conf
owner: root
mode: '0644'
- name: 创建符号链接
file:
src: /file/to/link
dest: /path/to/symlink
state: link
- name: 获取文件内容
slurp:
src: /etc/hosts
register: hosts_file
十一、实战案例
11.1 部署 LAMP 栈
yaml
---
- name: 部署 LAMP 环境
hosts: webservers
become: yes
tasks:
- name: 更新 apt 缓存
apt:
update_cache: yes
- name: 安装 Apache
apt:
name: apache2
state: present
- name: 安装 MySQL
apt:
name: mysql-server
state: present
- name: 安装 PHP
apt:
name: "{{ item }}"
state: present
loop:
- php
- php-mysql
- libapache2-mod-php
- name: 复制网站文件
copy:
src: files/index.php
dest: /var/www/html/
- name: 启动服务
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- apache2
- mysql
11.2 管理 Docker 容器
yaml
---
- name: 管理 Docker 容器
hosts: docker_hosts
become: yes
tasks:
- name: 安装 Docker
apt:
name: docker.io
state: present
- name: 启动 Nginx 容器
docker_container:
name: my-nginx
image: nginx:latest
ports:
- "80:80"
volumes:
- "/data:/usr/share/nginx/html"
state: started
十二、最佳实践
12.1 目录结构建议
project/
├── inventory/
│ ├── production
│ ├── staging
│ └── dev
├── group_vars/
│ ├── all.yml
│ ├── webservers.yml
│ └── databases.yml
├── host_vars/
│ └── server1.yml
├── roles/
│ ├── common/
│ ├── nginx/
│ └── mysql/
├── playbooks/
│ ├── site.yml
│ ├── webservers.yml
│ └── databases.yml
├── files/
├── templates/
└── ansible.cfg
12.2 性能优化
ini
# ansible.cfg
[defaults]
forks = 50 # 并发连接数
host_key_checking = False
gathering = smart # 智能事实收集
fact_caching = jsonfile # 事实缓存
[ssh_connection]
pipelining = True # 管道传输
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
十三、学习资源
13.1 官方资源
- 官方文档
- Ansible Galaxy:角色市场
- GitHub 仓库
13.2 推荐书籍
- 《Ansible 权威指南》
- 《Ansible for DevOps》
13.3 练习平台
十四、常见问题
14.1 调试技巧
bash
# 详细输出
ansible-playbook playbook.yml -vvv
# 检查语法
ansible-playbook playbook.yml --syntax-check
# 测试运行(不实际执行)
ansible-playbook playbook.yml --check
# 逐步执行
ansible-playbook playbook.yml --step
14.2 常见错误
- 权限问题 :使用
become: yes或--become - 主机不可达:检查网络和 SSH 配置
- 模块不存在:确认模块名称或安装对应集合
- 语法错误:使用 YAML 语法检查工具
学习路线建议
- 第一周:安装配置 + Ad-hoc 命令
- 第二周:Playbook 基础语法
- 第三周:变量、条件和循环
- 第四周:模板和文件管理
- 第五周:Roles 和 Collections
- 第六周:实际项目练习
通过以上内容系统学习,你将能够熟练使用 Ansible 进行自动化运维管理。建议结合实际项目练习,逐步掌握各项技能。