Ansible部署、核心概念与操作指南

Ansible部署、核心概念与操作指南

一、Ansible 简介

Ansible 是一款开源的自动化运维工具,基于 Python 开发,无需在受管节点安装客户端,通过 SSH 协议实现远程控制。其核心优势包括:

  • 无代理架构:受管节点无需部署额外软件
  • 模块化设计:通过丰富的模块实现各类运维任务
  • 支持 declarative 语法:Playbook 采用 YAML 格式,易读易写
  • 幂等性:重复执行同一操作不会产生意外结果

二、Ansible 部署过程

2.1 环境要求

  • 控制节点(Ansible 主机):Python 3.6+、SSH 客户端
  • 受管节点:SSH 服务开启、Python 2.7 或 3.5+、sudo 权限(可选)
  • 网络:控制节点与受管节点网络互通,支持 SSH 连接

2.2 控制节点安装(以 CentOS 为例)

方式 1:YUM 安装(推荐)
bash 复制代码
# 安装 EPEL 源(CentOS 默认无 Ansible 仓库)
sudo yum install -y epel-release

# 安装 Ansible
sudo yum install -y ansible

# 验证安装
ansible --version
方式 2:pip 安装
bash 复制代码
# 安装 pip
sudo yum install -y python3-pip

# 安装 Ansible
pip3 install ansible

# 添加环境变量(若未自动添加)
echo "export PATH=\$PATH:/usr/local/bin" >> ~/.bashrc
source ~/.bashrc

# 验证安装
ansible --version

2.3 免密登录配置(可选但推荐)

Ansible 默认使用 SSH 连接受管节点,配置免密登录可避免重复输入密码:

bash 复制代码
# 控制节点生成 SSH 密钥对(若已存在可跳过)
ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa

# 分发公钥到受管节点(替换为实际主机名/IP)
ssh-copy-id root@node1
ssh-copy-id root@node2

2.4 目录结构说明

安装完成后,Ansible 核心目录如下:

bash 复制代码
# 查看 Ansible 安装文件分布
rpm -ql ansible

关键目录说明:

  • /etc/ansible/:主配置目录(默认配置文件、主机清单)
  • /usr/bin/:执行文件(ansible、ansible-playbook 等)
  • /usr/lib/pythonX.X/site-packages/ansible/:依赖库与模块
  • /usr/share/ansible/plugins/:插件目录
  • /usr/share/doc/ansible/:帮助文档

三、核心概念

3.1 主机清单(Inventory)

定义 Ansible 管理的主机集合,支持静态清单(文本文件)和动态清单(脚本生成)。

3.1.1 静态清单格式(INI 格式)

创建清单文件 inventory

ini 复制代码
# 单个主机(IP 或主机名)
web1.example.com
192.0.2.42

# 主机组定义
[webservers]
web1.example.com
web2.example.com
192.168.3.7

[dbservers]
db1.example.com
db2.example.com
192.0.2.42
192.0.2.43

# 地理位置分组
[eastdc]
web1.example.com
db1.example.com

[westdc]
web2.example.com
db2.example.com

# 组嵌套(子组必须已定义)
[dc:children]
eastdc
westdc

# 范围简写(支持数字/字母范围)
[priv]
192.168.[4:7].[0:255]  # 192.168.4.0-192.168.7.255

[hosts]
host[01:20].example.com  # host01 ~ host20

[servers]
server[a:c].example.com  # servera ~ serverc
3.1.2 内置主机组
  • all:包含所有主机
  • ungrouped:未归属任何组的主机
3.1.3 清单验证命令
bash 复制代码
# 查看单个主机
ansible --list-hosts -i inventory web1.example.com

# 查看主机组
ansible --list-hosts -i inventory webservers

# 查看所有主机
ansible --list-hosts -i inventory all

# 树形结构显示清单
ansible-inventory -i inventory --graph

# YAML 格式导出清单
ansible-inventory -i inventory --list -y

3.2 配置文件(ansible.cfg)

控制 Ansible 行为的配置文件,支持多级别优先级(从高到低):

  1. 环境变量 ANSIBLE_CONFIG 指定的文件
  2. 当前目录下的 ./ansible.cfg
  3. 用户家目录下的 ~/.ansible.cfg
  4. 系统默认配置 /etc/ansible/ansible.cfg
常用配置示例(./ansible.cfg
ini 复制代码
[defaults]
# 清单文件路径
inventory = ./inventory
# 远程登录用户
remote_user = laogao
# 并发执行主机数
forks = 10
# 禁用 SSH 主机密钥检查
host_key_checking = False
# 日志文件路径
log_path = /var/log/ansible.log
# 默认模块
module_name = command

[privilege_escalation]
# 启用权限提升(sudo)
become = True
# 提升到 root 用户
become_user = root
# 提权方式
become_method = sudo
# 不提示输入 sudo 密码
become_ask_pass = False
配置验证命令
bash 复制代码
# 查看当前生效的配置文件
ansible --version | grep 'config file'

# 查看所有配置项
ansible-config list

# 查看生效的配置
ansible-config dump

# 查看配置文件内容
ansible-config view

3.3 模块(Modules)

Ansible 的最小功能单元,用于执行具体任务(如文件操作、软件安装、服务管理等)。

常用模块分类
模块类型 代表模块 功能描述
文件操作 copy、file、lineinfile 复制文件、设置文件属性、修改文件内容
软件包 yum、apt、pip 管理系统软件包
服务管理 service、systemd 启动 / 停止 / 重启服务
系统管理 user、group、reboot 管理用户组、重启系统
命令执行 command、shell、raw 执行命令(command 不支持管道 / 重定向)
模块文档查询
bash 复制代码
# 查看模块列表
ansible-doc -l

# 查看指定模块详情(如 copy 模块)
ansible-doc copy

# 查看模块使用示例
ansible-doc -s copy

3.4 Ad-Hoc 命令

临时执行的单个任务命令,无需编写 Playbook,适用于快速测试或简单操作。

命令语法
bash 复制代码
ansible <host-pattern> -m <module> [-a <module-arguments>] [-i <inventory>]
  • <host-pattern>:主机 / 主机组(如 allwebservers
  • -m:指定模块(默认 command 模块)
  • -a:模块参数
  • -i:指定清单文件
常用示例
bash 复制代码
# 1. 查看所有受管节点主机名(默认 command 模块)
ansible all -a "hostname"

# 2. 检查操作系统版本
ansible all -a "cat /etc/os-release"

# 3. 查看内存使用情况
ansible all -a "free -h"

# 4. 统计 /etc 目录文件数(需 shell 模块支持管道)
ansible all -m shell -a "ls -l /etc | wc -l"

# 5. 安装 httpd 软件(yum 模块)
ansible webservers -m yum -a "name=httpd state=present"

# 6. 启动并设置 httpd 开机自启(service 模块)
ansible webservers -m service -a "name=httpd state=started enabled=yes"

# 7. 复制本地文件到远程(copy 模块)
ansible all -m copy -a "src=/tmp/local.txt dest=/opt/remote.txt mode=0644"

# 8. 创建用户(user 模块)
ansible all -m user -a "name=newuser uid=1001 state=present"
执行结果颜色说明
  • 绿色:目标主机已为预期状态,无需修改
  • 黄色:命令执行后状态变更,已设置为预期状态
  • 红色:执行过程出错,任务中止

3.5 Playbook

Ansible 的核心功能,用于编排多个任务,支持复杂的运维流程自动化。Playbook 采用 YAML 格式,具有可读性强、可复用的特点。

YAML 语法规则
  1. 缩进敏感:同一级别元素缩进一致(推荐 2 个空格)
  2. 键值对:key: value(冒号后必须加空格)
  3. 列表:用 - 开头表示
  4. 注释:# 开头
  5. 字符串:可不用引号,特殊字符(如空格、换行)需用引号包裹
  6. 多行字符串:| 保留换行,> 折叠换行
Playbook 基本结构
yaml 复制代码
# 示例:部署 Web 服务
- name: 部署 HTTP 服务  # Play 名称
  hosts: webservers     # 目标主机组
  become: True          # 启用权限提升
  tasks:                # 任务列表
    - name: 安装 httpd 和 firewalld  # 任务 1 名称
      yum:               # 模块名
        name:            # 模块参数
          - httpd
          - firewalld
        state: latest    # 确保为最新版本

    - name: 创建测试页面  # 任务 2 名称
      copy:
        content: "Welcome to Ansible Web!\n"
        dest: /var/www/html/index.html

    - name: 启动 firewalld 并放行 HTTP 服务  # 任务 3 名称
      firewalld:
        service: http
        permanent: yes
        state: enabled
        immediate: yes

    - name: 启动 httpd 并设置开机自启  # 任务 4 名称
      service:
        name: httpd
        state: started
        enabled: yes
Playbook 执行命令
bash 复制代码
# 1. 直接执行
ansible-playbook playbook.yaml

# 2. 语法检查(不执行任务)
ansible-playbook --syntax-check playbook.yaml

# 3. 空运行(模拟执行,不修改系统)
ansible-playbook -C playbook.yaml

# 4. 提高输出详细程度(-v 到 -vvvv)
ansible-playbook -v playbook.yaml

# 5. 指定清单文件
ansible-playbook -i inventory playbook.yaml

3.6 变量(Variables)

用于存储可复用数据,简化 Playbook 维护。变量支持多级别定义,优先级从高到低为:

  1. 命令行变量(-e 参数)
  2. Playbook 任务级变量
  3. Playbook Play 级变量
  4. 主机变量(host_vars)
  5. 主机组变量(group_vars)
  6. 清单文件变量
变量定义方式
方式 1:命令行定义
bash 复制代码
# 传递变量 package=httpd 并安装
ansible all -e "package=httpd" -m yum -a "name={{ package }} state=present"
方式 2:Play 级变量(vars 关键字)
yaml 复制代码
- name: 测试变量
  hosts: node1
  vars:
    user: joe
    home_dir: /home/joe
  tasks:
    - name: 创建用户 {{ user }}
      user:
        name: "{{ user }}"
        home: "{{ home_dir }}"
        state: present
方式 3:变量文件(vars_files 关键字)

创建变量文件 vars/user.yaml

yaml 复制代码
user: laowang
home_dir: /home/laowang

在 Playbook 中引用:

yaml 复制代码
- name: 测试变量文件
  hosts: node1
  vars_files:
    - vars/user.yaml
  tasks:
    - name: 创建用户 {{ user }}
      user:
        name: "{{ user }}"
        home: "{{ home_dir }}"
        state: present
方式 4:主机 / 组变量(目录结构)

推荐方式,在项目目录下创建 host_varsgroup_vars 目录:

plaintext 复制代码
project/
├── ansible.cfg
├── inventory
├── group_vars/
│   └── webservers.yaml  # 主机组变量
├── host_vars/
│   └── node1.yaml       # 主机变量
└── playbook.yaml

group_vars/webservers.yaml

yaml 复制代码
package: httpd
service: httpd

host_vars/node1.yaml

yaml 复制代码
package: mariadb-server  # 覆盖组变量
变量引用规则
  • 变量用 {``{ 变量名 }} 引用

  • 若变量作为值的第一个元素,需用引号包裹:

    yaml 复制代码
    # 错误示例
    name: {{ user }}
    # 正确示例
    name: "{{ user }}"
数组变量
yaml 复制代码
- name: 测试数组变量
  hosts: node1
  vars:
    users:
      - name: joe
        uid: 1001
        home: /home/joe
      - name: jane
        uid: 1002
        home: /home/jane
  tasks:
    - name: 创建用户 {{ item.name }}
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        home: "{{ item.home }}"
        state: present
      loop: "{{ users }}"  # 循环数组

3.7 事实(Facts)

Ansible 自动从受管节点收集的系统信息(如主机名、IP 地址、内核版本等),可作为变量直接使用。

查看 Facts
bash 复制代码
# 查看所有 Facts
ansible node1 -m setup

# 过滤特定 Facts(如默认 IPv4 地址)
ansible node1 -m setup -a "filter=ansible_default_ipv4"
常用 Facts 示例
Facts 变量 描述
ansible_facts['hostname'] 短主机名
ansible_facts['fqdn'] 完全限定域名
ansible_facts['default_ipv4']['address'] 默认 IPv4 地址
ansible_facts['kernel'] 内核版本
ansible_facts['memory_mb']['total'] 总内存(MB)
ansible_facts['distribution'] 操作系统发行版
在 Playbook 中使用 Facts
yaml 复制代码
- name: 使用 Facts 配置 Nginx
  hosts: webservers
  tasks:
    - name: 配置 Nginx 监听地址
      lineinfile:
        path: /etc/nginx/nginx.conf
        regexp: '^listen'
        line: "listen {{ ansible_facts['default_ipv4']['address'] }}:80;"
关闭 Facts 收集(加快执行速度)
yaml 复制代码
- name: 关闭 Facts 收集
  hosts: webservers
  gather_facts: no  # 关闭自动收集
  tasks:
    # 手动收集特定 Facts(如需)
    - name: 收集网络相关 Facts
      setup:
        gather_subset: network

3.8 敏感数据管理(Ansible Vault)

用于加密存储敏感数据(如密码、API 密钥),避免明文泄露。

常用命令
bash 复制代码
# 1. 创建加密文件
ansible-vault create secret.yaml
# 输入密码后,编辑文件内容(YAML 格式):
# password: Huawei@123
# db_user: root

# 2. 查看加密文件
ansible-vault view secret.yaml
# 或通过密码文件自动输入密码
ansible-vault view --vault-password-file=pass.txt secret.yaml

# 3. 编辑加密文件
ansible-vault edit secret.yaml

# 4. 加密现有文件
ansible-vault encrypt plain.yaml

# 5. 解密文件
ansible-vault decrypt secret.yaml

# 6. 修改加密文件密码
ansible-vault rekey secret.yaml
在 Playbook 中使用加密文件
yaml 复制代码
- name: 部署数据库并配置密码
  hosts: dbservers
  vars_files:
    - secret.yaml  # 引用加密文件
  tasks:
    - name: 安装 mariadb-server
      yum:
        name: mariadb-server
        state: present

    - name: 设置数据库 root 密码
      mysql_user:
        name: root
        password: "{{ password }}"  # 引用加密变量
        host: '%'
        priv: '*.*:ALL'
        state: present
执行带加密文件的 Playbook
bash 复制代码
# 交互输入密码
ansible-playbook playbook.yaml --ask-vault-pass

# 通过密码文件输入
ansible-playbook playbook.yaml --vault-password-file=pass.txt

# 在 ansible.cfg 中配置密码文件路径(永久生效)
echo "vault_password_file = ./pass.txt" >> ansible.cfg
ansible-playbook playbook.yaml

四、常用文件操作模块实战

4.1 file 模块(文件 / 目录管理)

yaml 复制代码
- name: 文件操作示例
  hosts: all
  tasks:
    # 1. 创建文件并设置权限
    - name: 创建测试文件
      file:
        path: /tmp/testfile
        owner: root
        group: root
        mode: 0644  # 权限(必须带前导 0)
        state: touch

    # 2. 创建目录(递归)
    - name: 创建 /webdev 目录
      file:
        path: /webdev
        owner: apache
        group: apache
        mode: 0755
        state: directory

    # 3. 删除文件
    - name: 删除测试文件
      file:
        path: /tmp/testfile
        state: absent

4.2 copy 模块(文件复制)

yaml 复制代码
- name: 复制文件示例
  hosts: webservers
  tasks:
    # 1. 复制本地文件到远程
    - name: 复制 Nginx 配置文件
      copy:
        src: /etc/nginx/nginx.conf  # 本地文件路径
        dest: /etc/nginx/nginx.conf  # 远程文件路径
        owner: root
        group: root
        mode: 0644
        backup: yes  # 覆盖前备份原文件(后缀为时间戳)

    # 2. 直接写入内容到远程文件
    - name: 创建自定义 index.html
      copy:
        content: |
          <html>
            <head><title>Ansible Test</title></head>
            <body><h1>Hello from {{ ansible_facts['hostname'] }}</h1></body>
          </html>
        dest: /var/www/html/index.html

4.3 lineinfile 模块(单行文本修改)

yaml 复制代码
- name: 单行文本操作示例
  hosts: webservers
  tasks:
    # 1. 确保文件中存在特定行
    - name: 添加时区配置
      lineinfile:
        path: /etc/profile
        line: "export TZ=Asia/Shanghai"
        state: present

    # 2. 在指定行前插入
    - name: 在 Listen 80 前插入 Listen 8080
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        line: "Listen 8080"
        insertbefore: '^Listen 80'
        state: present

    # 3. 替换匹配的行
    - name: 注释掉 Listen 80
      lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen 80'
        line: '#Listen 80'
        state: present

4.4 blockinfile 模块(多行文本块操作)

yaml 复制代码
- name: 多行文本操作示例
  hosts: webservers
  tasks:
    # 1. 向文件添加多行文本块
    - name: 配置 Apache 虚拟主机
      blockinfile:
        path: /etc/httpd/conf/httpd.conf
        block: |
          <VirtualHost *:80>
              ServerName web.example.com
              DocumentRoot /var/www/example
              ErrorLog /var/log/httpd/example_error.log
              CustomLog /var/log/httpd/example_access.log combined
          </VirtualHost>
        state: present
        marker: "# {mark} ANSIBLE MANAGED BLOCK - VirtualHost"  # 标记注释

4.5 fetch 模块(从远程获取文件)

yaml 复制代码
- name: 从远程获取文件示例
  hosts: dbservers
  tasks:
    # 收集远程主机的日志文件到控制节点
    - name: 获取 MariaDB 日志
      fetch:
        src: /var/log/mariadb/mariadb.log  # 远程文件路径(必须是文件)
        dest: /tmp/backup/  # 控制节点存储路径(会自动创建主机名子目录)
        flat: no  # 保留目录结构(默认 no)
相关推荐
明航咨询_贾老师2 天前
RHCA Ansible高级自动化(DO374)认证信息整理
运维·自动化·ansible·rhca·红帽认证
有毒的教程6 天前
Ansible批量操作自动化完整教程:批量部署服务、配置同步、软件更新实战
运维·自动化·ansible
Hy行者勇哥11 天前
用Cursor智能编写Ansible/Terraform脚本,打通CI/CD链路
ci/cd·ansible·terraform
芷栀夏13 天前
飞牛NAS怎么部署Immich?家庭照片自动备份与远程访问教程
服务器·nginx·ansible
悠然南风24 天前
Ansible常见模块总结及LDAP Role 编写与调试
ansible
祺风挽楠1 个月前
ansible编辑
网络·ansible
芳心粽伙饭1 个月前
Ansible课后作业
ansible
烁3471 个月前
Ansible初识
ansible
烁3471 个月前
Ansible安装部署调试
ansible
烁3471 个月前
Ansible命令
ansible