目录
[一、多 Play Playbook管理服务器](#一、多 Play Playbook管理服务器)
[什么是多 Play Playbook?](#什么是多 Play Playbook?)
[1. 连接用户配置层级](#1. 连接用户配置层级)
[2. 权限提升控制](#2. 权限提升控制)
[3. 实际场景示例](#3. 实际场景示例)
[三、Ansible 模块宝库:找到合适的工具](#三、Ansible 模块宝库:找到合适的工具)
[五、YAML 语法细节:写出优雅的 Playbook](#五、YAML 语法细节:写出优雅的 Playbook)
[1. 注释的写法](#1. 注释的写法)
[2. 字符串的多种写法](#2. 字符串的多种写法)
[3. 列表和字典的格式](#3. 列表和字典的格式)
[4. 任务格式的选择](#4. 任务格式的选择)
一、多 Play Playbook管理服务器
什么是多 Play Playbook?
想象一下你要部署一个完整的 Web 应用,需要:
-
先在数据库服务器上安装和配置 MySQL
-
然后在 Web 服务器上部署应用代码
-
最后在负载均衡器上配置转发规则
这就是多 Play Playbook 的用武之地!一个 Playbook 可以包含多个 Play,每个 Play 针对不同的主机组执行不同的任务。
基本结构示例
bash
---
# Playbook:部署完整的博客系统
# 第一个 Play:配置数据库服务器
- name: 配置MySQL数据库服务器
hosts: db_servers # 针对数据库服务器组
tasks:
- name: 安装MySQL服务器
ansible.builtin.dnf:
name: mysql-server
state: present
- name: 初始化数据库
ansible.builtin.mysql_db:
name: blogdb
state: present
# 第二个 Play:配置Web应用服务器
- name: 部署Web应用程序
hosts: web_servers # 针对Web服务器组
tasks:
- name: 安装PHP环境
ansible.builtin.dnf:
name: [php, php-mysql, httpd]
state: present
- name: 部署博客代码
ansible.builtin.copy:
src: ./blog-code/
dest: /var/www/html/
# 第三个 Play:配置负载均衡器
- name: 配置Nginx负载均衡
hosts: lb_servers # 针对负载均衡器组
tasks:
- name: 安装Nginx
ansible.builtin.dnf:
name: nginx
state: latest
- name: 配置负载均衡
ansible.builtin.copy:
src: ./nginx-config.conf
dest: /etc/nginx/nginx.conf
关键点
-
顺序执行:Ansible 按顺序执行每个 Play
-
独立配置:每个 Play 可以有完全不同的配置
-
灵活组合:可以针对不同环境(开发、测试、生产)编写不同的 Play
二、用户和权限:谁在做什么?
1. 连接用户配置层级
Ansible 决定使用哪个用户连接服务器的优先级(从高到低):
bash
# 第1优先级:主机或组变量
# 在 inventory 或变量文件中设置
[web_servers]
web01.example.com ansible_user=app_deploy
# 第2优先级:Play 中的 remote_user
- name: 以特定用户执行任务
hosts: web_servers
remote_user: app_deploy # 覆盖默认用户
tasks: ...
# 第3优先级:ansible.cfg 中的配置
[defaults]
remote_user = ansible_user # 全局默认用户
# 第4优先级:默认值
# ansible-navigator: root
# ansible-playbook: 当前执行用户
2. 权限提升控制
权限提升(比如使用 sudo)可以在不同层级控制:
bash
---
# 全局启用(ansible.cfg中)
[privilege_escalation]
become = true
become_method = sudo
become_user = root
# Play 级别覆盖
- name: 以非root用户部署应用
hosts: app_servers
remote_user: deploy_user
become: true # 需要时提升权限
become_user: app_user # 提升到app_user,不是root
tasks:
- name: 创建应用目录
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: app_user
mode: '0755'
- name: 执行系统级配置
hosts: all
remote_user: admin
become: true # 提升到root
become_method: sudo
tasks:
- name: 更新系统
ansible.builtin.dnf:
name: "*"
state: latest
3. 实际场景示例
bash
---
# 场景:混合权限需求
# Play 1:普通用户执行,无需特权
- name: 拉取应用代码
hosts: dev_servers
remote_user: developer
become: false # 明确禁用权限提升
tasks:
- name: 从Git拉取代码
ansible.builtin.git:
repo: https://github.com/company/app.git
dest: /home/developer/app
version: main
# Play 2:需要root权限的系统配置
- name: 系统环境配置
hosts: dev_servers
remote_user: developer
become: true # 需要时使用sudo
become_method: sudo
become_user: root
tasks:
- name: 安装系统依赖
ansible.builtin.dnf:
name: [gcc, make, python3-devel]
state: present
三、Ansible 模块宝库:找到合适的工具
常用模块分类速查
文件管理模块
bash
# 1. copy - 复制文件
- name: 复制配置文件
ansible.builtin.copy:
src: configs/app.conf
dest: /etc/myapp/app.conf
owner: appuser
mode: '0644'
# 2. file - 管理文件和目录
- name: 创建日志目录
ansible.builtin.file:
path: /var/log/myapp
state: directory
owner: appuser
group: appuser
mode: '0755'
# 3. lineinfile - 管理文件中的行
- name: 配置时区
ansible.builtin.lineinfile:
path: /etc/sysconfig/clock
line: 'ZONE="Asia/Shanghai"'
regexp: '^ZONE='
软件包管理模块
bash
# 1. dnf - RHEL 8+ 系统
- name: 安装Web服务器
ansible.builtin.dnf:
name: [nginx, php-fpm, mysql-client]
state: present
# 2. package - 自动检测包管理器
- name: 跨平台安装curl
ansible.builtin.package:
name: curl
state: present
# 3. pip - Python包管理
- name: 安装Python依赖
ansible.builtin.pip:
name:
- django
- requests
state: latest
系统管理模块
bash
# 1. service - 服务管理
- name: 启动并启用服务
ansible.builtin.service:
name: nginx
state: started
enabled: true
# 2. user - 用户管理
- name: 创建应用用户
ansible.builtin.user:
name: appuser
uid: 1001
group: appgroup
shell: /bin/bash
# 3. firewalld - 防火墙管理
- name: 开放Web端口
ansible.posix.firewalld:
service: http
permanent: true
state: enabled
immediate: yes
如何查找和使用模块
bash
# 1. 浏览所有可用的集合和模块
ansible-navigator collections
# 2. 查看特定模块的详细文档
ansible-navigator doc ansible.builtin.copy -m stdout
# 3. 查看模块的简短用法摘要(很好的起点)
ansible-navigator doc ansible.builtin.service -s
四、执行命令模块:最后的备用方案
三个命令模块的区别
bash
# 1. command - 最简单,不支持shell特性
- name: 运行简单命令
ansible.builtin.command:
cmd: /usr/local/bin/setup.sh
# 缺点:不支持管道、重定向、环境变量
# 2. shell - 支持完整的shell功能
- name: 运行shell命令
ansible.builtin.shell:
cmd: |
cd /opt/app &&
source venv/bin/activate &&
python manage.py migrate
# 支持:管道、重定向、环境变量、多命令
# 3. raw - 最底层,绕过Ansible模块系统
- name: 在没有Python的系统上运行命令
ansible.builtin.raw:
cmd: yum install -y python3
# 用于:网络设备、安装Python、特殊情况
注:不推荐这种用法,因为他没有幂等性
如何安全使用命令模块
重要原则:尽量使用专用模块,命令模块是最后的选择!
bash
# ❌ 不好的做法:非幂等的shell命令
- name: 添加用户(非幂等)
ansible.builtin.shell:
cmd: useradd -m appuser
# 问题:第二次运行会失败(用户已存在)
# ✅ 好的做法:使用专用模块
- name: 确保用户存在(幂等)
ansible.builtin.user:
name: appuser
state: present
# 优点:可以安全地多次运行
# ⚠️ 必要时:使命令模块尽量幂等
- name: 初始化数据库(如果不存在)
ansible.builtin.command:
cmd: /opt/bin/initdb.sh
creates: /var/lib/mysql/ibdata1
# creates参数:文件存在则跳过
- name: 清理临时文件(如果存在)
ansible.builtin.command:
cmd: rm -rf /tmp/oldcache
removes: /tmp/oldcache
# removes参数:文件不存在则跳过
五、YAML 语法细节:写出优雅的 Playbook
1. 注释的写法
bash
---
# 这是整个Playbook的标题
# 部署生产环境博客系统
- name: 配置数据库服务器
# 这个Play会先执行
hosts: db_servers
vars:
db_name: blog_prod # 生产环境数据库名
db_user: blog_admin # 数据库管理员用户
tasks:
- name: 安装MySQL服务器
ansible.builtin.dnf:
name: mysql-server
state: latest # 使用最新版本
2. 字符串的多种写法
bash
# 普通字符串(大多数情况)
name: 我的应用配置
path: /opt/myapp
# 带特殊字符需要引号
error_message: "错误:文件 'config.yaml' 不存在"
sql_query: 'SELECT * FROM users WHERE status="active"'
# 多行字符串的两种方式
config_content: |
server {
listen 80;
server_name example.com;
root /var/www/html;
} # 保留换行符
description: >
这是一个很长的描述,
会被折叠成一行,
在空格处换行只是为了可读性。
3. 列表和字典的格式
bash
# 列表的推荐写法(垂直)
packages:
- nginx
- php-fpm
- mysql-client
- python3-pip
# 字典的推荐写法(垂直)
app_config:
name: "博客系统"
version: "2.1.0"
port: 8080
debug: false
# 不推荐的紧凑写法(除非必要)
packages: [nginx, php-fpm, mysql-client, python3-pip]
app_config: {name: "博客系统", version: "2.1.0", port: 8080, debug: false}
4. 任务格式的选择
bash
# ❌ 不推荐的简写格式(旧式)
tasks:
- name: 启动服务
ansible.builtin.service: name=nginx state=started enabled=true
# ✅ 推荐的完整格式(易读易维护)
tasks:
- name: 启动并启用Nginx服务
ansible.builtin.service:
name: nginx
state: started
enabled: true
# 可以轻松添加更多参数
sleep: 5 # 重启后等待时间