Ansible课程

一、Ansible 基础概念

1. 是什么

Ansible 是开源自动化运维工具 ,由红帽收购;基于 Python 开发,无 Agent(无客户端),采用 SSH 协议通信,不需要在被管理机器安装代理程序。

对比 SaltStack(可选 agent)、Puppet(C/S 架构)

2. 核心特性

  • 无 Agent,仅主控机安装 ansible
  • 模块化设计,所有操作依靠模块实现
  • 支持 YAML 编写 Playbook,可读性强
  • 支持临时命令(Ad-hoc)+ 批量脚本(Playbook)
  • 幂等性:重复执行不会产生副作用(理想模块)
  • 支持 Linux/Windows/ 网络设备、云主机 (AWS/Aliyun)

3. 架构组成

  1. 控制节点(主控):安装 ansible,发起任务
  2. 被管理节点(被控主机):只需开启 ssh
  3. Inventory(主机清单):定义管理哪些机器
  4. Modules(模块):执行最小单元(文件、服务、yum 等)
  5. Plugins(插件):扩展功能(连接、回调、过滤)
  6. Playbooks:YAML 任务剧本,编排多个模块
  7. Roles:Playbook 规范化目录结构,实现复用

二、安装与基础环境

安装方式

复制代码
# CentOS/RHEL
yum install ansible
# Ubuntu
apt install ansible
# pip安装(新版本)
pip install ansible

查看版本

复制代码
ansible --version

默认配置文件路径:

  • 主配置:/etc/ansible/ansible.cfg
  • 默认主机清单:/etc/ansible/hosts

最佳实践:项目内自定义 ansible.cfg,优先读取当前目录配置,不修改全局配置。

三、Inventory 主机清单

1. 静态 Inventory(ini 格式,最常用)

复制代码
# 单个主机
192.168.1.100
# 分组
[web]
192.168.1.101 ansible_user=root ansible_port=22
192.168.1.102 ansible_user=root ansible_ssh_pass=123456

[db]
192.168.1.103

# 组嵌套
[all_server:children]
web
db

常用内置变量:

  • ansible_user:ssh 登录用户
  • ansible_port:ssh 端口
  • ansible_ssh_pass:密码(生产建议密钥登录)
  • ansible_private_key_file:私钥路径

2. 动态 Inventory

从云平台、CMDB API 动态获取主机列表,输出 JSON 格式。

常用匹配规则

  • all:所有主机

  • * 通配符

  • : 或;:& 交集;:! 排除

    ansible web:db -m ping
    ansible web:&db -m ping
    ansible all:!db -m ping

四、Ad-hoc 临时命令

语法:

复制代码
ansible 主机组 -m 模块名 -a "模块参数"

高频示例

复制代码
# 连通性测试 ping模块
ansible web -m ping

# 执行shell命令
ansible web -m shell -a "df -h"

# 复制文件
ansible web -m copy -a "src=/tmp/a.txt dest=/tmp/"

# 创建目录
ansible web -m file -a "path=/data state=directory"

# 安装软件
ansible web -m yum -a "name=nginx state=present"

# 启动服务
ansible web -m service -a "name=nginx state=started enabled=yes"

shell vs command 模块区别

  • command:默认模块,不支持管道、重定向、变量,安全性高
  • shell:调用 /bin/sh,支持管道|>&&

五、模块(核心!)

常用内置模块清单

模块 作用
ping 测试连通性
command 执行简单命令(无 shell 特性)
shell 执行 shell 命令,支持管道
copy 主控→被控 推送文件
fetch 被控→主控 拉取文件(只能单个文件)
file 创建 / 删除文件、目录、修改权限
yum/apt 软件包管理
service/systemd 管理系统服务
user/group 用户、用户组管理
lineinfile 修改单行文本(替换、插入)
blockinfile 插入 / 修改一段多行文本
mount 挂载磁盘
cron 定时任务
template 模板渲染(支持 jinja2)
get_url 被控主机下载网络文件

查看模块文档:ansible-doc 模块名

六、Playbook 剧本 YAML 语法

基础语法要点

  1. YAML 缩进必须空格,不能 tab
  2. --- 开头,#注释
  3. key: value 冒号后必须空格

最简 Playbook 示例 site.yml

复制代码
---
- name: 部署nginx
  hosts: web
  become: true          # 开启sudo提权
  gather_facts: true    # 收集被控主机信息(facts变量)

  tasks:
    - name: 安装nginx
      yum:
        name: nginx
        state: present

    - name: 启动并开机自启
      service:
        name: nginx
        state: started
        enabled: yes

运行命令:

复制代码
ansible-playbook site.yml
# 模拟执行,不真实操作
ansible-playbook --check site.yml
# 指定密钥
ansible-playbook --private-key=/root/id_rsa site.yml

Playbook 核心关键字

  1. hosts:目标主机组
  2. become: yes:sudo 提权(等价于 -b 参数)
  3. gather_facts:是否收集主机系统信息
  4. tasks:任务列表
  5. handlers:触发器,只有被 notify 触发才执行(常用于重载服务)
  6. vars:定义变量
  7. vars_files:引入外部变量文件
  8. roles:调用角色

Handlers 触发器示例

复制代码
tasks:
  - name: 修改nginx配置
    copy:
      src: nginx.conf
      dest: /etc/nginx/nginx.conf
    notify: restart nginx

handlers:
  - name: restart nginx
    service:
      name: nginx
      state: restarted

Template 极简总结(含示例 + 渲染效果)

核心要点

  1. template 模块 :基于 Jinja2 渲染模板,实现差异化配置,模板后缀习惯 .j2
  2. copy vs template
    • copy:直接复制,不解析变量
    • template:先渲染变量、判断、循环,再下发
  3. Jinja2 标记
    • {``{ 变量 }} 输出值
    • {% if/for %} 逻辑控制
    • {# 注释 #} 最终文件不会出现
  4. Role 规范:templates/ → template;files/ → copy
  5. 参数:backup: true 更新前备份原配置

示例

1. 模板文件 nginx.conf.j2

复制代码
worker_processes {{ ansible_processor_vcpus }};
listen {{ http_port | default(80) }};
{# 环境判断 #}
{% if env == "prod" %}
keepalive_timeout 60;
{% else %}
keepalive_timeout 10;
{% endif %}

2. Playbook 调用

复制代码
vars:
  env: prod
  http_port: 8080

tasks:
  - name: 下发nginx配置
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      mode: '0644'
      backup: true

✅ 渲染后被控机器最终文件效果

复制代码
worker_processes 2;
listen 8080;

keepalive_timeout 60;

说明: ansible_processor_vcpus 取自 facts(本机 CPU 核心数); env=prod 命中 if 分支;端口使用变量 8080。

七、Ansible 变量 Variable

7.1 变量作用

用来存放动态信息(主机 IP、用户名、软件版本、端口、路径等),统一一处定义,多处引用;修改变量即可批量变更配置,避免硬编码。 引用语法:{``{ 变量名 }}

注意:YAML 中如果{``{ }}开头,建议加引号防止语法解析异常:"{``{ pkg_name }}"

7.2 变量的分类 + 定义方式(按出现位置划分

1. Inventory 清单变量

可以给单台主机 或者整个主机组定义变量

复制代码
# 主机变量(只生效这一台)
[web]
192.168.1.100 ansible_user=root pkg=nginx

# 组变量(组内所有主机生效)
[web:vars]
service_port=80
env=prod

2. Play 级别变量(写在 playbook 中)

方式① vars 直接定义
复制代码
- hosts: web
  vars:
    pkg_name: nginx
    listen_port: 80
方式② vars_files 引入外部变量文件

适合变量很多时拆分,单独写 yml 存放变量:

复制代码
- hosts: web
  vars_files:
    - vars/common.yml
    - vars/db.yml

3. Role 角色变量(工程化使用)

role 目录下两个目录,优先级不同:

  • defaults/main.yml角色默认变量,优先级最低,允许外部覆盖
  • vars/main.yml:角色内置变量,优先级高于 defaults

4. 任务级变量(task 内 vars)

只在当前这一个 task 生效,局部变量

复制代码
tasks:
  - name: 安装软件
    yum:
      name: "{{ pack }}"
      state: present
    vars:
      pack: nginx

5. 命令行传入变量(最高优先级)

使用 -e / --extra-vars,临时覆盖所有地方定义的变量

复制代码
# 单个变量
ansible-playbook deploy.yml -e "pkg_name=httpd"
# 多个变量
ansible-playbook deploy.yml -e "pkg_name=httpd;port=8080"
# 加载外部变量文件
ansible-playbook deploy.yml -e @var.json

6. Facts 内置自动变量(特殊变量)

gather_facts: true ,Ansible 自动采集被控主机信息,存入变量,无需手动定义。 常见 facts:

  • ansible_os_family:系统系列(RedHat/Debian)
  • ansible_default_ipv4.address:默认网卡 IP
  • ansible_memtotal_mb:总内存
  • ansible_processor_vcpus:CPU 核心数

优化:不需要系统信息时 gather_facts: false,减少执行耗时

7.3 变量优先级【重中之重,面试高频】

规则:范围越小、越临时定义,优先级越高;高优先级覆盖低优先级 从低 → 高排序:

  1. role defaults/main.yml(最低)
  2. Inventory 组变量
  3. Inventory 主机变量
  4. Play 中 vars /vars_files
  5. role vars/main.yml
  6. task 内部 vars
  7. 命令行 -e 传入变量(最高)

Facts 不属于上述优先级体系,是系统采集的只读信息,不能直接覆盖。

7.4 特殊变量 hostvars /groups/inventory_hostname

  1. inventory_hostname:当前执行任务的主机在 inventory 里的名称
  2. groups['web']:获取 web 组下所有主机列表
  3. hostvars['192.168.1.100']['ansible_user']:读取另外一台主机的变量 常用于多主机之间互相引用信息(例如配置集群,获取其他节点 IP)

7.5 变量加密 ansible-vault

变量文件如果存放数据库密码、密钥等敏感信息,明文不安全。

复制代码
# 加密文件
ansible-vault encrypt secret.yml
# 编辑加密文件
ansible-vault edit secret.yml
# 解密
ansible-vault decrypt secret.yml
# 运行playbook时输入密码
ansible-playbook deploy.yml --ask-vault-pass

7.6 Jinja2 和变量配合

template 模块加载 .j2 模板文件,支持变量渲染、判断、循环 nginx.conf.j2 示例:

复制代码
worker_processes {{ ansible_processor_vcpus }};
listen {{ listen_port }};

八、条件判断 & 循环

1. when 条件

复制代码
- name: CentOS安装nginx
  yum: name=nginx state=present
  when: ansible_os_family == "RedHat"

支持多条件 and / or

2. 循环 with_items(新版推荐 loop)

复制代码
tasks:
  - name: 创建多个目录
    file:
      path: "{{ item }}"
      state: directory
    loop:
      - /data
      - /logs

九、Ansible 常用参数汇总

复制代码
-i  指定inventory文件
-m  指定模块
-a  模块参数
-b  --become  sudo提权
-K  --ask-become-pass 输入sudo密码
-C  --check 模拟运行(干跑)
-v / -vv / -vvv 输出详细日志
-e  传入额外变量
--limit 限定主机 ansible-playbook site.yml --limit 192.168.1.101

十、易混淆知识点总结

  1. copy vs template copy:原样传输文件;template:Jinja2 渲染变量
  2. fetch vs copy copy:主控→被控;fetch:被控→主控(仅支持单个文件)
  3. handlers:只有 notify 触发,且所有任务执行完成后统一执行
  4. 幂等性:尽量使用官方模块;shell 命令很难做到幂等
  5. 静态 inventory vs 动态 inventory:静态适合固定服务器,动态适配云环境

十一、完整操作示例:

1.安装

复制代码
yum install -i ansible

2.编辑inventory清单

复制代码
[web]
192.168.118.101
192.168.118.102

[web:vars]
env=prod
  1. vars.yml(外部变量)

    http_port: 80
    software: nginx

  2. nginx.conf.j2 模板

    worker_processes {{ ansible_processor_vcpus }};
    events {
    worker_connections 1024;
    }
    http {
    server {
    listen {{ http_port }};
    {# 判断环境 #}
    {% if env == "prod" %}
    server_name prod.test.com;
    {% else %}
    server_name test.test.com;
    {% endif %}
    root /usr/share/nginx/html;
    }
    }

渲染完成后被控端生成效果

复制代码
worker_processes 2;
events {
    worker_connections 1024;
}
http {
    server {
        listen 80;
        server_name prod.test.com;
        root /usr/share/nginx/html;
    }
}
  1. index.html 静态文件

    Hello Ansible Demo

  2. deploy.yml 主剧本playbook


    • name: 批量部署nginx
      hosts: web
      become: true
      vars_files:

      • vars.yml

      tasks:

      • name: 安装nginx
        yum:
        name: "{{ software }}"
        state: present

      • name: 推送nginx模板配置
        template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        mode: '0644'
        backup: true
        notify: 重启nginx

      • name: 推送首页静态文件
        copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html

      handlers:

      • name: 重启nginx
        service:
        name: nginx
        state: restarted
        enabled: yes
  3. 执行命令

    模拟运行,不真实修改

    ansible-playbook deploy.yml --check

    正式执行

    ansible-playbook deploy.yml

    临时修改变量覆盖配置

    ansible-playbook deploy.yml -e "http_port=8080"

  4. Ad-hoc 测试连通性(前置验证)

    ansible web -m ping

相关推荐
至乐活着3 天前
Ansible自动化运维实战:从零部署高可用Nginx+静态网站集群
ansible·自动化运维·devops·playbook·配置管理
John Song6 天前
ansible-playbook常用的检查命令
windows·ansible
明航咨询_贾老师8 天前
RHCA Ansible高级自动化(DO374)认证信息整理
运维·自动化·ansible·rhca·红帽认证
有毒的教程12 天前
Ansible批量操作自动化完整教程:批量部署服务、配置同步、软件更新实战
运维·自动化·ansible
Hy行者勇哥17 天前
用Cursor智能编写Ansible/Terraform脚本,打通CI/CD链路
ci/cd·ansible·terraform
芷栀夏19 天前
飞牛NAS怎么部署Immich?家庭照片自动备份与远程访问教程
服务器·nginx·ansible
悠然南风1 个月前
Ansible常见模块总结及LDAP Role 编写与调试
ansible
祺风挽楠1 个月前
ansible编辑
网络·ansible
芳心粽伙饭1 个月前
Ansible课后作业
ansible