Ansible

第 1 章:Ansible 入门认知

1.1 什么是 Ansible?

  • 通俗解释:Ansible 是一款 "批量运维工具",可以让你在一台管理机上,同时操控几十、几百台服务器,不用逐台登录操作。
  • 核心优势(小白友好):
    • 无代理:被管理节点不用装额外软件,靠 SSH 就能通信;
    • 简单:不用写复杂代码,用 "命令" 或 "配置文件" 就能实现批量操作;
    • 强大:支持安装软件、执行命令、分发文件、定时任务等几乎所有运维场景。

1.2 Ansible 能做什么?(实际场景)

  • 批量安装 Nginx、MySQL 等软件;
  • 批量执行命令(如查看所有服务器磁盘使用率);
  • 批量分发配置文件(如给所有 Web 服务器发 Nginx 配置);
  • 批量启动 / 重启服务(如所有服务器重启防火墙);
  • 批量创建用户、授权(如给所有节点创建运维用户)。

1.3 Ansible 核心概念(不用死记,后续慢慢理解)

  • 管理端(控制节点):你操作的那台机器(比如你的电脑或一台专门的运维机);
  • 被管理节点(被控节点):需要被批量管理的服务器(比如 Web 服务器、数据库服务器);
  • 主机清单:一个配置文件,记录所有被管理节点的 IP / 主机名,还能分组(如 Web 组、数据库组);
  • 模块:Ansible 内置的 "工具函数",比如 yum 模块用来装软件、copy 模块用来传文件;
  • Playbook:"剧本",把多个操作按顺序写在一个文件里,执行一次就能完成一系列任务(如 "装 Nginx → 传配置 → 启动服务")。

第 2 章:管理端安装与环境配置(1 课时)

2.1 安装 Ansible(CentOS 系统)

Ansible 不在 CentOS 官方默认源里,需要先装 "扩展源(EPEL)",再装 Ansible。

步骤 1:安装 EPEL 源

打开管理端的终端,执行以下命令(复制粘贴即可):

bash

运行

复制代码
# CentOS 7 执行
yum install -y epel-release

# CentOS 8 执行(如果提示找不到包,再执行这个)
dnf install -y epel-release
  • 解释:yum 是 CentOS 的软件安装工具,-y 表示 "所有提示都选 yes",不用手动确认。
步骤 2:安装 Ansible

bash

运行

复制代码
# CentOS 7 执行
yum install -y ansible

# CentOS 8 执行
dnf install -y ansible
步骤 3:验证安装成功

执行以下命令,能看到版本号就说明安装成功:

bash

运行

复制代码
ansible --version
  • 成功示例输出(版本号可能不同,正常): plaintext

    复制代码
    ansible 2.9.27
      config file = /etc/ansible/ansible.cfg
      configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
      ansible python module location = /usr/lib/python2.7/site-packages/ansible
      executable location = /usr/bin/ansible
      python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

2.2 认识 Ansible 默认目录

安装后,Ansible 会自动创建以下目录,核心文件就两个:

plaintext

复制代码
/etc/ansible/  # Ansible 主目录
├── ansible.cfg  # 全局配置文件(默认不用改!)
├── hosts        # 主机清单(核心!记录被管理节点)
└── roles/       # 角色目录(后续进阶用)

2.3 配置主机清单(hosts 文件)

主机清单是 Ansible 识别 "要管理哪些服务器" 的配置文件,必须手动编辑。

步骤 1:编辑 hosts 文件

bash

运行

复制代码
vi /etc/ansible/hosts
  • 解释:vi 是 Linux 自带的文本编辑器,按 i 进入 "编辑模式"。
步骤 2:添加被管理节点(示例)

假设你有 2 台被管理节点:

  • Web 服务器:192.168.10.14
  • 数据库服务器:192.168.10.15

在 hosts 文件末尾添加以下内容(按 i 后复制粘贴):

ini

复制代码
# 这是注释(# 开头的行是注释,Ansible 会忽略)
# 分组:Web 服务器组(组名自定义,比如 webservers)
[webservers]
192.168.10.14  # 被管理节点的 IP 地址

# 分组:数据库服务器组
[dbservers]
192.168.10.15  # 另一台被管理节点的 IP 地址

# 分组:所有服务器(嵌套组,包含上面两个组)
[all_servers:children]
webservers
dbservers
  • 编辑完后,按 Esc 键,输入 :wq(冒号 + wq),回车保存退出。
步骤 3:验证主机清单

执行以下命令,查看 Ansible 是否能识别配置的节点:

bash

运行

复制代码
# 查看所有被管理节点
ansible all --list-hosts

# 查看 webservers 组的节点
ansible webservers --list-hosts
  • 成功示例(能看到配置的 IP 就是对的): plaintext

    复制代码
    hosts (2):
      192.168.10.14
      192.168.10.15

2.4 配置免密 SSH 登录(核心!必须做)

Ansible 靠 SSH 通信,若每次操作都要输密码,非常麻烦。配置 "免密登录" 后,管理端能直接登录被管理节点,无需输入密码。

核心原理
  • 管理端生成一对 "钥匙":公钥(可以给别人)和私钥(自己留着,不能泄露);
  • 把管理端的 "公钥" 拷贝到所有被管理节点;
  • 后续管理端登录被管理节点时,被管理节点用 "公钥" 验证管理端的 "私钥",验证通过就不用输密码。
步骤 1:管理端生成密钥对

在管理端终端执行以下命令,按 3 次回车(不用输入任何内容):

bash

运行

复制代码
ssh-keygen -t rsa
  • 执行后,会在 ~/.ssh/ 目录下生成两个文件:
    • id_rsa:私钥(自己留着,千万别删!);
    • id_rsa.pub:公钥(要拷贝到被管理节点)。
步骤 2:拷贝公钥到被管理节点

首先安装 sshpass 工具(用于非交互输入密码,避免手动输密码):

bash

运行

复制代码
yum install -y sshpass

然后执行以下命令,把公钥拷贝到被管理节点(替换成你的被管理节点 IP 和 root 密码):

bash

运行

复制代码
# 拷贝到 webservers 组的 192.168.10.14(密码替换成你的被管理节点 root 密码)
sshpass -p '你的被管理节点密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.10.14

# 拷贝到 dbservers 组的 192.168.10.15
sshpass -p '你的被管理节点密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.10.15
  • 成功提示:Number of key(s) added: 1(表示公钥拷贝成功)。
步骤 3:验证免密登录

在管理端执行以下命令,不用输密码能登录就说明成功:

bash

运行

复制代码
# 登录 192.168.10.14
ssh root@192.168.10.14

# 登录成功后,输入 exit 退出
exit

2.5 测试 Ansible 连通性(最后一步)

执行以下命令,测试管理端是否能正常连接所有被管理节点:

bash

运行

复制代码
# 测试所有节点(ping 模块:类似网络 ping,测试连通性)
ansible all -m ping
  • 成功示例(每个节点都显示 SUCCESSping: pong):

    plaintext

    复制代码
    192.168.10.14 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    192.168.10.15 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
  • 若失败:回到前面步骤,检查免密配置或主机清单是否正确。

第 3 章:Ansible 命令基础

3.1 命令格式(核心!记牢)

Ansible 命令的通用格式:

bash

运行

复制代码
ansible [目标节点/组] -m [模块名] -a [模块参数] [可选参数]
  • 通俗解释:
    • [目标节点/组]:要操作的服务器(比如 all 所有节点、webservers 组);
    • -m [模块名]:用哪个 "工具"(比如 ping 模块测试连通、yum 模块装软件);
    • -a [模块参数]:工具的具体操作(比如 yum 模块的参数是 "装 nginx");
    • 可选参数:比如 -u 指定登录用户、-vvv 查看详细日志(排障用)。

3.2 常用可选参数(小白必备)

参数 作用 示例
-u 用户名 指定远程登录用户(默认是 root) -u admin
-k 提示输入远程用户密码(免密失败时用) -k
-vvv 详细输出日志(排障神器,能看到执行过程) -vvv
-i 清单路径 指定自定义主机清单(默认是 /etc/ansible/hosts) -i ./my_hosts

3.3 实战:执行简单命令

示例 1:查看所有节点的系统版本

bash

运行

复制代码
# 用 command 模块(默认模块,可省略 -m command),执行命令 cat /etc/redhat-release
ansible all -a "cat /etc/redhat-release"
  • 输出:每个节点的系统版本(比如 CentOS Linux release 7.9.2009 (Core))。
示例 2:查看 webservers 组节点的磁盘使用率

bash

运行

复制代码
ansible webservers -a "df -h"
  • 解释:df -h 是 Linux 查看磁盘使用率的命令,Ansible 会在所有 web 节点执行这个命令并返回结果。
示例 3:给 dbservers 组节点创建一个目录

bash

运行

复制代码
ansible dbservers -a "mkdir -p /data/logs"
  • 解释:mkdir -p 是 Linux 创建目录(递归创建,父目录不存在也能创建),这里在数据库节点创建 /data/logs 目录。

3.4 命令执行结果解读

Ansible 执行命令后,每个节点的结果会显示 3 种状态:

  • SUCCESS:执行成功;
  • CHANGED:执行后节点状态发生变化(比如创建了目录、安装了软件);
  • FAILED:执行失败(会显示错误原因,比如命令写错、权限不足)。

第 4 章:常用模块

Ansible 有几百个模块,但小白掌握以下 8 个核心模块,就能应对 90% 的运维场景!每个模块都带 "通俗解释 + 实战示例"。

4.1 ping 模块:测试连通性(最常用)

  • 作用:测试管理端与被管理节点的网络和 SSH 连通性(类似网络 ping);
  • 特点:无参数,执行后返回 pong 就是成功。

示例:

bash

运行

复制代码
# 测试所有节点连通性
ansible all -m ping

# 测试单个节点(192.168.10.14),并输出详细日志
ansible 192.168.10.14 -m ping -vvv

4.2 command 模块:执行简单 Linux 命令

  • 作用:在被管理节点执行 Linux 命令;
  • 缺点:不支持管道(|)、重定向(>/>>)、通配符(*);
  • 场景:执行简单命令(如查看目录、创建文件)。

示例:

bash

运行

复制代码
# 1. 查看所有节点的 /tmp 目录内容
ansible all -m command -a "ls /tmp"

# 2. 重启所有节点的 sshd 服务
ansible all -m command -a "systemctl restart sshd"

# 3. 查看节点的 CPU 使用率
ansible webservers -m command -a "top -bn1 | grep 'Cpu(s)'"
  • 注意:如果命令带空格,必须用双引号包裹(比如 ls /tmp 没问题,ls "/my dir" 带空格需引号)。

4.3 shell 模块:执行复杂 Linux 命令

  • 作用:和 command 模块一样执行命令,但支持管道、重定向、通配符;
  • 场景:执行复杂命令(如过滤日志、统计数据)。

示例:

bash

运行

复制代码
# 1. 查看所有节点的 nginx 进程(支持管道 |)
ansible webservers -m shell -a "ps aux | grep nginx | grep -v grep"

# 2. 把系统负载写入文件(支持重定向 >>)
ansible all -m shell -a "uptime >> /tmp/system_load.log"

# 3. 统计 /var/log 目录下的日志文件数(支持通配符 *.log)
ansible dbservers -m shell -a "ls -l /var/log/*.log | wc -l"
  • 小白提示:分不清 commandshell 时,直接用 shell 模块(兼容性更强)。

4.4 yum 模块:安装 / 卸载 RPM 软件

  • 作用:在 CentOS 系统上安装、卸载、更新软件(自动处理依赖,比手动执行 yum install 安全);
  • 核心参数:
    • name:软件包名(必填);
    • state:状态(present= 安装,absent= 卸载,latest= 更新到最新版)。

示例:

bash

运行

复制代码
# 1. 给 webservers 组节点安装 nginx
ansible webservers -m yum -a "name=nginx state=present"

# 2. 给 dbservers 组节点安装 mariadb-server 并更新到最新版
ansible dbservers -m yum -a "name=mariadb-server state=latest"

# 3. 卸载所有节点的 httpd(Apache 服务)
ansible all -m yum -a "name=httpd state=absent"
  • 解释:state=present 表示 "确保软件已安装",如果已经安装,不会重复安装。

4.5 copy 模块:本地文件拷贝到远程节点

  • 作用:把管理端的文件 / 目录,批量拷贝到被管理节点;
  • 核心参数:
    • src:本地文件 / 目录路径(必填);
    • dest:远程节点的目标路径(必填);
    • mode:文件权限(如 755 执行权限、644 只读权限);
    • owner/group:文件所有者 / 所属组。

示例:

bash

运行

复制代码
# 1. 把管理端的 /etc/hosts 拷贝到所有节点的 /tmp/ 目录(保留权限)
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts mode=644 owner=root group=root"

# 2. 把管理端的本地脚本(./deploy.sh)拷贝到 web 节点,并添加执行权限
ansible webservers -m copy -a "src=./deploy.sh dest=/usr/local/bin/ mode=755"

# 3. 直接在远程节点创建文件并写入内容(不用本地文件)
ansible dbservers -m copy -a "content='DB_HOST=192.168.10.15' dest=/etc/my.cnf.d/custom.cnf"
  • 小白提示:mode=755 表示 "所有者可读写执行,其他人只读执行",脚本文件必须设为 755 才能运行。

4.6 service 模块:管理系统服务

  • 作用:启动、停止、重启系统服务(如 nginx、mariadb),支持开机自启;
  • 核心参数:
    • name:服务名(必填,如 nginxmariadb);
    • state:状态(started= 启动,stopped= 停止,restarted= 重启,reloaded= 重载配置);
    • enabled:是否开机自启(yes= 是,no= 否)。

示例:

bash

运行

复制代码
# 1. 启动 web 节点的 nginx 服务,并设置开机自启
ansible webservers -m service -a "name=nginx state=started enabled=yes"

# 2. 重启 db 节点的 mariadb 服务
ansible dbservers -m service -a "name=mariadb state=restarted"

# 3. 停止所有节点的 httpd 服务,并禁用开机自启
ansible all -m service -a "name=httpd state=stopped enabled=no"
  • 解释:enabled=yes 表示 "系统开机后自动启动该服务",避免服务器重启后服务停止。

4.7 file 模块:管理文件 / 目录属性

  • 作用:创建目录、删除文件、修改文件权限 / 所有者等;
  • 核心参数:
    • path:远程节点的文件 / 目录路径(必填);
    • state:状态(directory= 创建目录,absent= 删除文件 / 目录,file= 确保文件存在);
    • mode/owner/group:权限 / 所有者 / 所属组。

示例:

bash

运行

复制代码
# 1. 在所有节点创建 /data/backup 目录(递归创建父目录)
ansible all -m file -a "path=/data/backup state=directory mode=755"

# 2. 删除所有节点的 /tmp/old.log 文件
ansible all -m file -a "path=/tmp/old.log state=absent"

# 3. 修改 web 节点的 nginx 配置文件权限(只读)
ansible webservers -m file -a "path=/etc/nginx/nginx.conf mode=644 owner=root group=root"
  • 小白提示:state=directory 会自动创建父目录(比如 /data/backup 不存在时,会先创建 /data 再创建 /backup)。

4.8 user 模块:管理系统用户

  • 作用:创建用户、删除用户、修改用户密码、添加用户组等;
  • 核心参数:
    • name:用户名(必填);
    • state:状态(present= 创建,absent= 删除);
    • password:用户密码(需要用加密后的字符串,不能直接写明文);
    • groups:用户所属组;
    • shell:登录 shell(如 /bin/bash 允许登录,/sbin/nologin 禁止登录)。

示例:

bash

运行

复制代码
# 1. 给所有节点创建运维用户 ops(密码是加密后的 123456)
# 先在管理端生成密码加密串:python -c 'import crypt; print crypt.crypt("123456")'
ansible all -m user -a "name=ops password='$6$xG8rI$z6V3eG9Q4...' groups=wheel shell=/bin/bash"

# 2. 删除所有节点的 test 用户
ansible all -m user -a "name=test state=absent"

# 3. 给 db 节点创建 mysql 用户(禁止登录,仅用于运行服务)
ansible dbservers -m user -a "name=mysql state=present shell=/sbin/nologin"
  • 小白提示:密码不能直接写明文(比如 password=123456),必须用加密串!生成加密串的命令:python -c 'import crypt; print crypt.crypt("你的密码")',把输出的字符串作为 password 参数。

第 5 章:Playbook

5.1 什么是 Playbook?

  • 通俗解释:Playbook 是 "剧本",把多个模块按顺序写在一个 YAML 格式的文件里,执行一次剧本,就能自动完成一系列操作(比如 "装 Nginx → 传配置 → 启动服务 → 设置开机自启")。
  • 优势:可复用、可维护,适合复杂场景(比如批量部署 Web 服务)。

5.2 Playbook 基础语法(小白必记)

  • 文件名后缀:通常用 .yml.yaml(比如 deploy_nginx.yml);
  • 语法规则:
    • 缩进:用 2 个空格(不能用 Tab!),缩进决定层级关系;
    • 键值对:key: value(冒号后面必须加空格);
    • 列表:用 - 开头(比如 - name: 安装 nginx);
    • 注释:# 开头的行。

5.3 实战:编写 Playbook 批量部署 Nginx

目标:给 webservers 组所有节点部署 Nginx 服务,步骤:

  1. 安装 Nginx;
  2. 拷贝本地 Nginx 配置文件到远程;
  3. 启动 Nginx 服务并设置开机自启;
  4. 创建网站根目录。
步骤 1:准备本地 Nginx 配置文件

在管理端创建 nginx.conf 文件(简单配置示例):

bash

运行

复制代码
vi nginx.conf

添加以下内容:

nginx

复制代码
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

Esc:wq 保存退出。

步骤 2:编写 Playbook(deploy_nginx.yml)

bash

运行

复制代码
vi deploy_nginx.yml

添加以下内容(注意缩进用 2 个空格):

复制代码
# 剧本名称:批量部署 Nginx
- name: Deploy Nginx Service
  hosts: webservers  # 目标组:webservers
  remote_user: root  # 远程登录用户:root
  tasks:  # 任务列表(按顺序执行)
    # 任务 1:安装 Nginx
    - name: Install Nginx
      yum:
        name: nginx
        state: present

    # 任务 2:拷贝本地 Nginx 配置文件到远程
    - name: Copy Nginx config file
      copy:
        src: ./nginx.conf  # 本地配置文件路径
        dest: /etc/nginx/nginx.conf  # 远程目标路径
        mode: 644
        owner: root
        group: root

    # 任务 3:创建网站根目录
    - name: Create web root directory
      file:
        path: /usr/share/nginx/html
        state: directory
        mode: 755

    # 任务 4:启动 Nginx 并设置开机自启
    - name: Start and enable Nginx service
      service:
        name: nginx
        state: started
        enabled: yes

保存退出(Esc:wq)。

示例2:Playbook 稳定完成 HTTPD 服务的部署、配置和启动全流程


.命令行运行 Playbook
ansible-playbook test1.yaml # 运行 playbook
ansible-playbook test1.yaml --syntax-check # 检查语法
ansible-playbook test1.yaml --list-task # 查看任务列表
ansible-playbook test1.yaml --list-hosts # 查看影响的主机
ansible-playbook test1.yaml --start-at-task='install httpd' # 从指定任务开始执行

步骤 3:执行 Playbook

在管理端执行以下命令,运行剧本:

bash

运行

复制代码
ansible-playbook deploy_nginx.yml
  • 执行过程:Ansible 会按任务顺序,在所有 web 节点执行操作,每个任务会显示 OK(已完成)、CHANGED(已修改)或 FAILED(失败)。
  • 成功提示:最后一行显示 PLAY RECAP,所有节点的 failed=0 就是成功。
步骤 4:验证部署结果

执行以下命令,检查 Nginx 是否正常运行:

bash

运行

复制代码
# 查看 web 节点的 Nginx 状态
ansible webservers -a "systemctl status nginx"

# 访问 Nginx 首页(测试 80 端口是否通)
ansible webservers -m shell -a "curl http://localhost"
  • 若能看到 Nginx 的默认首页内容,说明部署成功!

第 6 章:常见问题排查(1 课时)

小白使用 Ansible 时,最容易遇到以下问题,掌握排查方法就能快速解决:

6.1 免密登录失败(Permission denied)

如果要使用 SSH****密码sudo****密码,可以使用以下选项:
ansible-playbook test1.yaml -k # 提示输入 SSH 密码
ansible-playbook test1.yaml -K # 提示输入 sudo 密码

报错示例

plaintext

复制代码
192.168.10.14 | UNREACHABLE! => {
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password)"
}
排查步骤
  1. 手动 SSH 测试:ssh root@192.168.10.14,看是否能登录;
  2. 若提示 publickey 失败:重新执行公钥分发命令(ssh-copy-id);
  3. 若提示 password 失败:
    • 检查被管理节点的 sshd_config 文件:PasswordAuthentication yes(是否启用密码登录);
    • 重启 SSH 服务:systemctl restart sshd
  4. 检查权限:被管理节点的 ~/.ssh 目录权限必须是 700authorized_keys 文件权限必须是 600(执行 chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys)。

6.2 模块执行失败(如 yum 安装失败)

报错示例

plaintext

复制代码
192.168.10.14 | FAILED! => {
    "msg": "No package matching 'nginx' found available, installed or updated"
}
排查步骤
  1. -vvv 查看详细日志:ansible webservers -m yum -a "name=nginx" -vvv
  2. 检查被管理节点的 yum 源是否正常:ansible webservers -m shell -a "yum repolist"
  3. 若 yum 源异常:重新安装 EPEL 源(yum install -y epel-release)。

6.3 Playbook 语法错误

报错示例

plaintext

复制代码
ERROR! Syntax Error while loading YAML.
  expected <block end>, but found '-'
排查步骤
  1. 检查缩进:是否用了 2 个空格(不能用 Tab);
  2. 检查冒号:key: value 冒号后面是否加了空格;
  3. 检查列表:- name: 任务名 前面是否有正确缩进;
  4. ansible-playbook --syntax-check deploy_nginx.yml 检查语法(不执行,只检查语法错误)。

6.4 被管理节点防火墙 / SELinux 拦截

现象
  • 手动 SSH 能登录,但 Ansible 执行命令超时或失败;
  • 安装 Nginx 后,无法访问 80 端口。
解决方法
  1. 临时关闭防火墙(测试用): bash

    运行

    复制代码
    ansible all -m command -a "systemctl stop firewalld"
  2. 临时关闭 SELinux(测试用): bash

    运行

    复制代码
    ansible all -m command -a "setenforce 0"
  3. 生产环境推荐:放行需要的端口(如 80、22),而非关闭防火墙。

第 7 章:课程总结与进阶方向

7.1 核心知识点总结

  1. Ansible 核心流程:管理端 → 主机清单 → 被管理节点(靠 SSH 通信);
  2. 命令格式:ansible 目标 -m 模块 -a 参数
  3. 8 个核心模块:pingcommandshellyumcopyservicefileuser
  4. Playbook:按顺序执行多个任务,适合复杂场景。

附录:常用命令速查(小白必备)

功能 命令示例
测试所有节点连通性 ansible all -m ping
批量安装 Nginx ansible webservers -m yum -a "name=nginx state=present"
批量启动 Nginx ansible webservers -m service -a "name=nginx state=started enabled=yes"
批量传文件 ansible all -m copy -a "src=./a.txt dest=/tmp/"
批量执行复杂命令 `ansible all -m shell -a "ps aux grep nginx"`
查看 Playbook 语法 ansible-playbook --syntax-check deploy.yml
执行 Playbook ansible-playbook deploy.yml
查看被管理节点列表 ansible all --list-hosts

第 8 章:变量

在 Ansible Playbook 中,变量是实现 "代码复用、灵活配置、环境适配" 的核心机制------ 通过将可变信息(如软件版本、文件路径、端口号、主机参数等)抽象为变量,无需修改 Playbook 核心逻辑,即可适配不同环境、主机组或需求,大幅提升 Playbook 的通用性和可维护性。

简单说:变量让 Playbook 从 "写死配置" 变成 "动态适配",避免重复编写相似 Playbook,同时降低修改成本(比如修改服务端口时,只需改变量值,无需遍历所有任务)。

8.1、变量的核心作用(结合实际场景)

8.1.1. 统一配置,减少重复编写

将多个任务共用的参数(如软件版本、文件路径、端口)定义为变量,集中管理,避免 "一处修改需改多处" 的麻烦。

示例场景:部署 HTTPD 时,统一指定服务端口、配置文件路径、安装版本:

yaml

复制代码
---
- name: Deploy HTTPD with variables
  hosts: webservers
  remote_user: root
  vars:  # 定义变量(集中管理)
    httpd_port: 8080  # 服务监听端口
    httpd_conf_src: /opt/httpd.conf  # 本地配置文件路径
    httpd_version: latest  # 安装版本
  tasks:
    - name: Install HTTPD
      yum:
        name: httpd
        state: "{{ httpd_version }}"  # 引用变量({{ 变量名 }} 语法)
    
    - name: Copy config file
      copy:
        src: "{{ httpd_conf_src }}"
        dest: /etc/httpd/conf/httpd.conf
    
    - name: Modify listen port (通过变量动态改配置)
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen'
        line: "Listen {{ httpd_port }}"  # 引用端口变量
  • 若后续需将端口改为 80,只需修改 httpd_port: 80,无需改所有关联任务。
8.1.2. 适配多环境 / 多主机组

不同环境(开发、测试、生产)或不同主机组(web、db)的配置可能不同,用变量可实现 "一套 Playbook 适配所有场景"。

示例场景:开发环境 HTTPD 用 8080 端口,生产环境用 80 端口:

yaml

复制代码
---
- name: Deploy HTTPD across environments
  hosts: "{{ target_hosts }}"  # 外部传入主机组变量
  remote_user: root
  vars:
    # 环境变量映射(按环境区分配置)
    env_config:
      dev:  # 开发环境
        httpd_port: 8080
        httpd_conf_src: /opt/dev_httpd.conf
      prod:  # 生产环境
        httpd_port: 80
        httpd_conf_src: /opt/prod_httpd.conf
  vars_files:
    - ./secret_vars.yml  # 从文件加载敏感变量(如密码,避免硬编码)
  tasks:
    - name: Install HTTPD
      yum: name=httpd state=latest
    
    - name: Copy environment-specific config
      copy:
        src: "{{ env_config[target_env].httpd_conf_src }}"  # 按环境取配置
        dest: /etc/httpd/conf/httpd.conf
    
    - name: Set listen port
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen'
        line: "Listen {{ env_config[target_env].httpd_port }}"
  • 执行时通过 -e 传入环境变量,适配不同场景:

    bash

    运行

    复制代码
    # 部署开发环境(webservers_dev 主机组)
    ansible-playbook deploy_httpd.yml -e "target_hosts=webservers_dev target_env=dev"
    
    # 部署生产环境(webservers_prod 主机组)
    ansible-playbook deploy_httpd.yml -e "target_hosts=webservers_prod target_env=prod"
8.1.3. 引用目标主机的系统信息(事实变量)

Ansible 的 setup 模块会自动采集目标主机的系统信息(如 IP、操作系统、磁盘路径、CPU 核心数),这些信息以 "事实变量"(ansible_*)形式存在,可直接在 Playbook 中引用,实现 "按主机状态动态配置"。

示例场景 :根据目标主机的操作系统,选择不同的 HTTPD 包名(如 Debian 系叫 apache2,RHEL 系叫 httpd):

yaml

复制代码
---
- name: Deploy HTTPD (cross-distribution)
  hosts: webservers
  gather_facts: true  # 必须开启(默认开启),才能采集事实变量
  remote_user: root
  tasks:
    - name: Install HTTPD on RHEL/CentOS
      yum: name=httpd state=latest
      when: ansible_os_family == "RedHat"  # 引用事实变量:判断操作系统家族
    
    - name: Install HTTPD on Debian/Ubuntu
      apt: name=apache2 state=latest update_cache=yes
      when: ansible_os_family == "Debian"  # 适配不同系统
  • 常用事实变量:ansible_all_ipv4_addresses(主机 IP)、ansible_distribution(操作系统名称)、ansible_mounts(磁盘挂载信息)等。
8.1.4. 接收外部输入(动态传参)

执行 Playbook 时,通过 -e--extra-vars)参数动态传入变量,无需修改 Playbook 即可灵活调整配置,适合临时变更需求。

示例场景:临时指定 HTTPD 版本进行安装:

yaml

复制代码
# playbook.yml
---
- name: Install specified HTTPD version
  hosts: webservers
  remote_user: root
  tasks:
    - name: Install HTTPD {{ httpd_version }}  # 引用外部传入的变量
      yum:
        name: "httpd-{{ httpd_version }}"  # 拼接变量(如 httpd-2.4.6)
        state: present
  • 执行时传入版本变量: bash

    运行

    复制代码
    # 安装 2.4.6 版本
    ansible-playbook playbook.yml -e "httpd_version=2.4.6"
    
    # 安装最新版本
    ansible-playbook playbook.yml -e "httpd_version=latest"
8.1.5. 存储敏感信息(安全管理)

通过变量文件(如 vars_files)或 Ansible Vault 存储密码、密钥等敏感信息,避免硬编码到 Playbook 中,提升安全性。

示例场景:存储数据库密码(非加密,适合测试环境):

yaml

复制代码
# secret_vars.yml(单独文件,不要提交到代码仓库)
db_user: root
db_password: "MySecurePass123"

# playbook.yml
---
- name: Connect to database
  hosts: dbservers
  remote_user: root
  vars_files:
    - ./secret_vars.yml  # 加载敏感变量
  tasks:
    - name: Test database connection
      command: "mysql -u {{ db_user }} -p{{ db_password }} -e 'select 1'"
  • 生产环境建议用 ansible-vault 加密敏感变量文件:

    bash

    运行

    复制代码
    # 加密文件
    ansible-vault encrypt secret_vars.yml
    
    # 执行时解密(需输入密码)
    ansible-playbook playbook.yml --ask-vault-pass

8.2、变量的优先级(避免冲突)

Ansible 变量有明确的优先级(从高到低),优先级高的变量会覆盖优先级低的,需注意避免冲突:

  1. 命令行传入的变量(-e 参数)→ 最高优先级;
  2. Playbook 中 vars_prompt(交互输入变量);
  3. Playbook 中 vars 定义的变量;
  4. 变量文件(vars_files);
  5. 事实变量(setup 模块采集的 ansible_*);
  6. Inventory 中定义的主机 / 主机组变量;
  7. Ansible 配置文件(ansible.cfg)中的变量 → 最低优先级。

8.3、变量的核心价值总结

作用 解决的问题 典型场景
统一配置 重复编写、多处修改麻烦 固定端口、文件路径、软件版本
多环境适配 一套 Playbook 适配开发 / 测试 / 生产 不同环境的配置文件、端口、主机组
动态引用主机信息 按主机状态差异化配置 跨操作系统安装、按硬件配置服务
外部动态传参 临时变更配置无需改 Playbook 临时指定软件版本、开关功能
敏感信息管理 避免密码硬编码导致泄露 数据库密码、API 密钥

简单说:变量是 Playbook 的 "灵活开关",用好变量能让你的 Playbook 从 "一次性脚本" 升级为 "可复用、可扩展的自动化工具"。如果需要具体学习 "变量的定义方式"(如 Inventory 变量、角色变量)或 "变量的高级用法"(如循环变量、注册变量),可以告诉我!

相关推荐
paopao_wu5 小时前
深度学习1:Python基础库NumPy与Matplotlib
python·深度学习·numpy
习习.y2 天前
KNN算法学习笔记
numpy
祁思妙想2 天前
数据分析三剑客:NumPy、Pandas、Matplotlib
数据分析·numpy·pandas
猪在黑魔纹里3 天前
解决VSCode无法高亮、解析numpy中的部分接口(如pi、deg2rad)
ide·vscode·python·numpy
九死九歌3 天前
【Sympydantic】使用sympydantic,利用pydantic告别numpy与pytorch编程中,tensor形状带来的烦人痛点!
开发语言·pytorch·python·机器学习·numpy·pydantic
qq19226384 天前
探索图像滤波去噪:MATLAB GUI的奇妙之旅
numpy
Python大数据分析@4 天前
Numpy基础20问
numpy
Cat God 0074 天前
CentOS 搭建 SFTP 服务器(二)
服务器·centos·numpy
fresh hacker5 天前
【Python数据分析】速通NumPy
开发语言·python·数据挖掘·数据分析·numpy