运维自动化工具 Ansible

运维自动化工具 Ansible

环境:Ubuntu 24.04 / Rocky Linux 10


目录

  1. [Ansible 概述](#Ansible 概述)
  2. 安装与配置
  3. [主机清单 Inventory](#主机清单 Inventory)
  4. 常用模块详解
  5. [Playbook 基础](#Playbook 基础)
  6. [Playbook 进阶](#Playbook 进阶)
  7. [Roles 角色](#Roles 角色)
  8. 最佳实践与总结
  9. 综合实践案例

1. Ansible 概述

  • 开发语言:Python

  • 架构:无代理(agentless),基于 SSH 通信

  • 核心组件

    • 控制节点(安装 Ansible 的主机)
    • 被管节点(通过 SSH 管理)
    • 主机清单(Inventory)
    • 模块(Modules)
    • Playbook(YAML 格式的任务编排)
    • Roles(角色,用于代码复用)
  • 优势

    • 无需在被管节点安装额外软件
    • 学习曲线低,YAML 语法简单
    • 幂等性:多次执行结果一致
    • 丰富的内置模块
  • 劣势

    • 大规模节点(>1000)时 SSH 效率较低,需优化(如开启 pipelining、使用更快的连接方式)

2. 安装与配置

2.1 环境准备(以 Ubuntu 24.04 为例)

bash 复制代码
# 设置主机名解析
cat >> /etc/hosts <<EOF
10.0.0.13 ubuntu24-13
10.0.0.12 rocky10-12
10.0.0.16 ubuntu24-16
EOF

# Ubuntu 更换阿里源(可选)
sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
apt update

2.2 安装 Ansible

Ubuntu(二进制安装)
bash 复制代码
apt install -y software-properties-common
add-apt-repository --yes --update ppa:ansible/ansible
apt install -y ansible
ansible --version
Rocky Linux(EPEL 源)
bash 复制代码
yum install epel-release -y
yum install ansible -y
ansible --version
其他安装方式
  • pip 安装(推荐虚拟环境)
  • 源码安装(从 GitHub 克隆)

2.3 配置文件优先级

  1. 环境变量 ANSIBLE_CONFIG 指定的文件
  2. 当前目录下的 ansible.cfg
  3. 用户家目录下的 ~/.ansible.cfg
  4. 系统默认 /etc/ansible/ansible.cfg

生成基础配置文件:

bash 复制代码
ansible-config init --disabled > ansible.cfg

关键配置项示例(ansible.cfg):

ini 复制代码
[defaults]
inventory = /etc/ansible/hosts
remote_tmp = ~/.ansible/tmp
forks = 5
host_key_checking = False
log_path = /var/log/ansible.log
module_name = command
interpreter_python = /usr/bin/python3

[privilege_escalation]
become = False
become_method = sudo
become_user = root

[ssh_connection]
pipelining = True   # 提高大规模执行效率

3. 主机清单 Inventory

3.1 文件格式(INI / YAML)

ini 复制代码
# INI 格式示例
[web]
10.0.0.12
10.0.0.13

[db]
10.0.0.16

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa

[web:vars]
http_port=80

3.2 常用连接参数

参数 说明
ansible_host 目标主机地址
ansible_port SSH 端口(默认22)
ansible_user 连接用户
ansible_ssh_pass SSH 密码(不安全,建议使用密钥)
ansible_ssh_private_key_file 私钥路径
ansible_python_interpreter Python 解释器路径
ansible_connection 连接类型(ssh / local / paramiko)

3.3 主机匹配模式

bash 复制代码
ansible all -m ping
ansible 'web:db' -m ping          # 并集
ansible 'web:&db' -m ping          # 交集
ansible 'web:!db' -m ping          # 差集
ansible all -l 10.0.0.13 -m ping   # 限制单台

3.4 配置 SSH 免密认证

bash 复制代码
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
ssh-copy-id root@10.0.0.12
ssh-copy-id root@10.0.0.13
ssh-copy-id root@10.0.0.16

4. 常用模块详解

查询模块帮助:ansible-doc -l 列出所有模块,ansible-doc <模块名> 查看详细用法。

4.1 命令执行类

模块 说明 示例
command 默认模块,不支持管道、重定向 ansible all -a "uptime"
shell 支持 shell 特性 ansible all -m shell -a "echo $HOSTNAME"
script 在远程执行本地脚本 ansible all -m script -a "/tmp/test.sh"

4.2 文件操作类

模块 说明 示例
copy 复制文件到远程 ansible all -m copy -a "src=/etc/hosts dest=/tmp/"
fetch 从远程拉取文件到本地 ansible all -m fetch -a "src=/var/log/syslog dest=./logs/"
file 管理文件属性、创建软链接、删除 ansible all -m file -a "path=/tmp/test state=directory"
lineinfile 确保文件中某行存在/不存在 ansible all -m lineinfile -a "path=/etc/profile regexp='^export HISTSIZE' line='export HISTSIZE=1000'"
replace 正则替换文件内容 ansible all -m replace -a "path=/etc/fstab regexp='^(.*)' replace='#\1'"

4.3 系统管理类

模块 说明 示例
user 管理用户 ansible all -m user -a "name=app state=present groups=wheel"
group 管理组 ansible all -m group -a "name=app system=yes"
hostname 设置主机名 ansible all -m hostname -a "name=node1"
cron 管理定时任务 ansible all -m cron -a "name='sync time' minute=*/5 job='/usr/sbin/ntpdate time1.aliyun.com'"
setup 收集主机 facts ansible all -m setup -a "filter=ansible_default_ipv4"

4.4 软件包管理

模块 适用系统 示例
apt Debian/Ubuntu ansible ubuntu -m apt -a "name=nginx state=present update_cache=yes"
yum RHEL/CentOS/Rocky ansible rocky -m yum -a "name=nginx state=latest"
service 管理服务 ansible all -m service -a "name=nginx state=started enabled=yes"

4.5 解压缩

模块 说明 示例
unarchive 解压文件到远程 ansible all -m unarchive -a "src=/tmp/pkg.tar.gz dest=/opt/ copy=no"

4.6 调试

模块 说明 示例
debug 打印变量或消息 ansible all -m debug -a "msg='Hello World'"

5. Playbook 基础

5.1 YAML 语法要点

  • 缩进使用空格(通常2个),禁止使用 Tab
  • 键值对:key: value
  • 列表:- item1(前导空格 + 短横 + 空格)
  • 文件开头可选 ---

5.2 Playbook 基本结构

yaml 复制代码
---
- hosts: web
  remote_user: root
  gather_facts: yes
  vars:
    package: nginx
  tasks:
    - name: install nginx
      apt:
        name: "{{ package }}"
        state: present
    - name: start nginx
      service:
        name: nginx
        state: started
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

5.3 执行 Playbook

bash 复制代码
# 语法检查
ansible-playbook site.yml --syntax-check

# 模拟执行(dry run)
ansible-playbook site.yml -C

# 实际执行
ansible-playbook site.yml

# 查看主机/任务列表
ansible-playbook site.yml --list-hosts
ansible-playbook site.yml --list-tasks

# 指定 tags
ansible-playbook site.yml --tags "install"

# 从特定任务开始
ansible-playbook site.yml --start-at-task="start nginx"

5.4 异常处理

yaml 复制代码
- name: 可能失败的命令
  shell: /bin/false
  ignore_errors: yes

5.5 Handlers(任务触发)

  • 仅在被 notify 时执行,且只执行一次(即使被多个任务 notify)
yaml 复制代码
tasks:
  - name: update config
    copy:
      src: nginx.conf
      dest: /etc/nginx/nginx.conf
    notify: restart nginx

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

5.6 Tags(标签)

yaml 复制代码
tasks:
  - name: install package
    apt:
      name: nginx
    tags: [install, web]

  - name: configure nginx
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf
    tags: configure

执行指定标签:ansible-playbook site.yml --tags "install"


6. Playbook 进阶

6.1 变量

变量定义位置(优先级从低到高)
  1. facts(自动收集的主机信息)
  2. inventory 主机变量
  3. inventory 组变量
  4. playbook 中 vars 定义的变量
  5. vars_files 引入的变量文件
  6. 命令行 -e 传入的变量(最高)
示例
yaml 复制代码
# playbook 内定义
vars:
  http_port: 80

# 变量文件 vars.yml
---
db_host: 10.0.0.16
db_port: 3306

# 引入变量文件
vars_files:
  - vars.yml

# 命令行覆盖
ansible-playbook site.yml -e "http_port=8080"
注册变量(register)
yaml 复制代码
- name: get date
  command: date
  register: date_output

- name: show date
  debug:
    msg: "{{ date_output.stdout }}"

6.2 模板(Template)

  • 使用 Jinja2 语法,文件后缀 .j2
  • 通过 template 模块渲染并复制到远程
jinja2 复制代码
# nginx.conf.j2
server {
    listen {{ http_port }};
    server_name {{ ansible_fqdn }};
    root /var/www/html;
}
yaml 复制代码
- name: deploy nginx config
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

6.3 条件判断(when)

yaml 复制代码
- name: install nginx on Debian
  apt:
    name: nginx
  when: ansible_os_family == "Debian"

- name: install nginx on RedHat
  yum:
    name: nginx
  when: ansible_os_family == "RedHat"

# 多条件
when:
  - ansible_distribution == "CentOS"
  - ansible_distribution_major_version == "7"

6.4 循环(loop)

yaml 复制代码
- name: create users
  user:
    name: "{{ item }}"
    state: present
  loop:
    - alice
    - bob

# 循环字典列表
- name: add users with groups
  user:
    name: "{{ item.name }}"
    group: "{{ item.group }}"
  loop:
    - { name: 'alice', group: 'developers' }
    - { name: 'bob', group: 'ops' }

6.5 并发控制(serial)

yaml 复制代码
- hosts: webservers
  serial: 2      # 每次只更新2台
  tasks:
    - name: rolling update
      shell: systemctl restart nginx

7. Roles 角色

7.1 Role 目录结构

复制代码
roles/
└── role_name/              # 角色名
    ├── tasks/              # 必须,主任务文件 main.yml
    ├── handlers/           # 处理器,main.yml
    ├── templates/          # Jinja2 模板
    ├── files/              # 静态文件
    ├── vars/               # 高优先级变量,main.yml
    ├── defaults/           # 默认变量(最低优先级),main.yml
    ├── meta/               # 依赖关系,main.yml
    └── README.md

7.2 创建角色

bash 复制代码
ansible-galaxy init roles/role_name

7.3 使用角色

yaml 复制代码
# playbook.yml
- hosts: web
  roles:
    - role: nginx
      nginx_port: 8080
    - role: php
      when: ansible_os_family == "Debian"

7.4 角色任务拆分示例

yaml 复制代码
# roles/nginx/tasks/main.yml
---
- include_tasks: install.yml
- include_tasks: config.yml
- include_tasks: service.yml

8. 最佳实践与总结

8.1 核心原则

  • 幂等性:多次执行结果一致,模块应设计为幂等
  • 使用变量:避免硬编码,提高复用性
  • 模板化配置:利用 Jinja2 动态生成配置
  • Role 化:将功能封装成角色,便于复用
  • 版本控制:所有 Playbook 和 Roles 应纳入 Git

8.2 调试技巧

  • -v-vv-vvv 增加输出详细程度
  • --check 模拟运行
  • --diff 显示文件变更差异
  • debug 模块打印变量

8.3 安全建议

  • 使用 SSH 密钥而非密码

  • 敏感信息使用 Ansible Vault 加密

    bash 复制代码
    ansible-vault create secret.yml
    ansible-playbook --ask-vault-pass site.yml

9. 综合实践案例

案例1:Nginx 自动化部署(基础 Playbook)

yaml 复制代码
---
- hosts: web
  become: yes
  vars:
    nginx_port: 80
  tasks:
    - name: install nginx
      apt:
        name: nginx
        state: present
      when: ansible_os_family == "Debian"

    - name: ensure nginx started
      service:
        name: nginx
        state: started
        enabled: yes

案例2:多虚拟主机(Template + 循环)

yaml 复制代码
# vars:
vhosts:
  - server_name: www.example.com
    root: /var/www/example
  - server_name: api.example.com
    root: /var/www/api

# template vhost.conf.j2
{% for vhost in vhosts %}
server {
    listen 80;
    server_name {{ vhost.server_name }};
    root {{ vhost.root }};
}
{% endfor %}

案例3:LNMP 环境 Role 化

目录结构:

复制代码
lnmp/
├── site.yml
└── roles/
    ├── nginx/
    ├── php/
    ├── mysql/
    └── wordpress/

site.yml 内容:

yaml 复制代码
- hosts: web
  roles:
    - nginx
    - php
- hosts: db
  roles:
    - mysql
- hosts: web
  roles:
    - wordpress
相关推荐
小码吃趴菜2 小时前
服务器预约系统linux小项目-第二节课
linux·运维·服务器
盛世宏博北京2 小时前
6. 物联网环境监测新标杆:POE供电以太网温湿度变送器技术详解
大数据·运维·网络·以太网·poe·温湿度变送器
_OP_CHEN2 小时前
【Linux网络编程】(二)计算机网络概念进阶:彻底搞懂协议本质、传输流程与封装分用
linux·运维·服务器·网络·网络协议·计算机网络·c/c++
arvin_xiaoting2 小时前
AI Agent 实战:用飞书任务卡片让后台任务「可见」
人工智能·自动化·llm·飞书·ai agent·openclaw·任务卡片
勇闯逆流河2 小时前
【Linux】linux进程概念(fork,进程状态,僵尸进程,孤儿进程)
linux·运维·服务器·开发语言·c++
牛十二2 小时前
宝塔安装openclaw+企业微信操作手册
linux·运维·服务器
rpa研究爱好者2 小时前
灵梭RPA轻松实现手机自动化操作
智能手机·自动化·rpa
开开心心_Every2 小时前
免费抽奖软件支持内定名单+防重复中奖
linux·运维·服务器·edge·pdf·c5全栈·c4python
feng68_2 小时前
Discuz! X5 高性能+高可用
linux·运维·服务器·前端·后端·高性能·高可用