跳转至

590_Ansible自动化运维

一句话概述:Ansible 是 Red Hat 开源的 IT 自动化工具,通过 SSH 无需安装 Agent,用 YAML 编写 Playbook 来批量管理服务器配置、应用部署和任务编排,是运维自动化的标准工具。

核心知识点表

概念白话解释
Inventory清单,定义要管理的服务器列表和分组
Playbook剧本,用 YAML 写的自动化任务脚本
Task任务,Playbook 中的一个操作步骤
Module模块,执行具体操作的工具(如安装软件、复制文件)
Role角色,把相关的任务、变量、文件打包成可复用的单元
Idempotent幂等性,跑多少次结果都一样(已经安装的不会重复安装)
Ad-hoc临时命令,不写 Playbook 直接执行一条命令

安装配置

安装 Ansible

# 方法1:pip 安装(推荐)
pip install ansible                    # 安装完整包
# 或
pip install ansible-core               # 安装最小包

# 方法2:Ubuntu/Debian
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible               # 安装

# 方法3:CentOS/RHEL
sudo yum install epel-release
sudo yum install ansible

# 验证安装
ansible --version                      # 查看版本(当前 v13.x / core 2.20.x)

配置 Inventory(服务器清单)

# /etc/ansible/hosts 或项目目录下的 inventory 文件

# === 简单格式 ===
[webservers]                           # 组名
web1.example.com                       # 服务器地址
web2.example.com
192.168.1.100                          # 也可以用 IP

[databases]
db1.example.com ansible_port=2222      # 自定义 SSH 端口
db2.example.com ansible_user=deploy    # 自定义 SSH 用户

[production:children]                  # 组的组
webservers
databases

[all:vars]                             # 全局变量
ansible_python_interpreter=/usr/bin/python3

配置 SSH 免密登录

# 生成密钥(如果没有)
ssh-keygen -t ed25519                  # 生成 SSH 密钥对

# 复制公钥到目标服务器
ssh-copy-id user@web1.example.com      # 每台服务器都要执行
ssh-copy-id user@web2.example.com

# 测试连接
ansible all -m ping                    # ping 所有服务器
# 期望输出:web1.example.com | SUCCESS => {"ping": "pong"}

基本使用

Ad-hoc 命令(临时命令)

# 语法:ansible <主机/组> -m <模块> -a "<参数>"

# ping 所有服务器
ansible all -m ping                    # 测试连接

# 查看所有服务器的磁盘使用
ansible all -m shell -a "df -h"        # 执行 Shell 命令

# 安装软件包
ansible webservers -m apt -a "name=nginx state=present" -b  # -b = sudo

# 重启服务
ansible webservers -m service -a "name=nginx state=restarted" -b

# 复制文件到所有服务器
ansible all -m copy -a "src=./app.conf dest=/etc/app.conf" -b

# 创建用户
ansible all -m user -a "name=deploy state=present" -b

编写 Playbook

# deploy.yml — 部署 Nginx 的 Playbook
---
- name: 部署 Nginx Web 服务器           # Play 名称
  hosts: webservers                     # 目标主机组
  become: true                          # 使用 sudo

  vars:                                 # 变量定义
    app_port: 8080

  tasks:
    - name: 安装 Nginx                  # 任务1
      apt:                              # 使用 apt 模块
        name: nginx                     # 包名
        state: present                  # 确保已安装
        update_cache: yes               # 先更新包索引

    - name: 复制 Nginx 配置文件          # 任务2
      template:                         # 使用 template 模块
        src: nginx.conf.j2             # 本地模板文件
        dest: /etc/nginx/sites-available/default  # 目标路径
      notify: 重启 Nginx                # 配置变更时触发 handler

    - name: 确保 Nginx 运行中           # 任务3
      service:                          # 使用 service 模块
        name: nginx
        state: started                  # 确保已启动
        enabled: yes                    # 开机自启

  handlers:                             # 处理器(被 notify 触发)
    - name: 重启 Nginx
      service:
        name: nginx
        state: restarted
# 运行 Playbook
ansible-playbook deploy.yml            # 执行
ansible-playbook deploy.yml --check    # 预检(不实际执行)
ansible-playbook deploy.yml --diff     # 显示文件变更差异
ansible-playbook deploy.yml -l web1    # 只对 web1 执行

Jinja2 模板

# templates/nginx.conf.j2
server {
    listen {{ app_port }};             # 使用 Ansible 变量
    server_name {{ ansible_hostname }};  # 使用 Facts 变量

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
    }
}

高级用法

Role(角色)

# 创建 Role 目录结构
ansible-galaxy init roles/nginx        # 自动生成结构

# roles/nginx/
# ├── tasks/main.yml     → 任务
# ├── handlers/main.yml  → 处理器
# ├── templates/          → 模板文件
# ├── files/              → 静态文件
# ├── vars/main.yml       → 变量
# └── defaults/main.yml   → 默认变量
# roles/nginx/tasks/main.yml
---
- name: 安装 Nginx
  apt: name=nginx state=present update_cache=yes

- name: 部署配置
  template: src=nginx.conf.j2 dest=/etc/nginx/sites-available/default
  notify: restart nginx

- name: 启动 Nginx
  service: name=nginx state=started enabled=yes
# 使用 Role 的 Playbook
---
- hosts: webservers
  become: true
  roles:
    - nginx                            # 引用 nginx role
    - { role: app, app_port: 3000 }    # 带参数的 role

变量优先级

# 从低到高的优先级:
# 1. defaults/main.yml(Role 默认值)
# 2. group_vars/all.yml(全局变量)
# 3. group_vars/webservers.yml(组变量)
# 4. host_vars/web1.yml(主机变量)
# 5. Playbook vars
# 6. 命令行 -e "var=value"(最高优先级)

# group_vars/all.yml
---
ntp_server: time.google.com
timezone: Asia/Shanghai

# group_vars/production.yml
---
env: production
debug: false

条件和循环

tasks:
  # 条件执行
  - name: 只在 Ubuntu 上执行
    apt: name=nginx state=present
    when: ansible_os_family == "Debian"  # 条件判断

  # 循环安装多个包
  - name: 安装多个包
    apt:
      name: "{{ item }}"               # 循环变量
      state: present
    loop:                               # 循环列表
      - nginx
      - git
      - htop
      - curl

  # 注册变量
  - name: 检查服务状态
    command: systemctl is-active nginx
    register: nginx_status              # 保存结果
    ignore_errors: yes

  - name: 启动 Nginx(如果未运行)
    service: name=nginx state=started
    when: nginx_status.rc != 0          # 根据上一步结果判断

Ansible Vault(加密敏感数据)

# 加密文件
ansible-vault encrypt group_vars/production.yml  # 加密

# 解密文件
ansible-vault decrypt group_vars/production.yml  # 解密

# 编辑加密文件
ansible-vault edit group_vars/production.yml     # 编辑

# 运行时提供密码
ansible-playbook site.yml --ask-vault-pass       # 提示输入密码
ansible-playbook site.yml --vault-password-file=.vault_pass  # 密码文件

常见报错

报错信息原因解决方案
UNREACHABLESSH 连接失败检查 SSH 密钥和网络连通性
Permission denied权限不足添加 become: true 或检查 sudo 权限
Module not found模块未安装ansible-galaxy collection install xxx
Syntax error in playbookYAML 格式错误ansible-playbook --syntax-check
variable undefined变量未定义检查变量名拼写和作用域
Python not found远程主机无 Python设置 ansible_python_interpreter

速查表

# === 常用命令 ===
ansible all -m ping                    # 测试连接
ansible all -m shell -a "uptime"       # 执行命令
ansible-playbook playbook.yml          # 运行 Playbook
ansible-playbook playbook.yml --check  # 预检模式
ansible-galaxy init roles/myrole       # 创建 Role
ansible-vault encrypt file.yml         # 加密文件

# === 常用模块 ===
apt/yum     # 包管理
service     # 服务管理
copy        # 复制文件
template    # 模板渲染
file        # 文件/目录管理
user/group  # 用户/组管理
shell/command # 执行命令
git         # Git 操作
docker_container # Docker 容器

同类对比

特性AnsiblePuppetChefSaltStack
语言YAMLRuby DSLRubyYAML/Python
Agent无需需要需要可选
通信方式SSHHTTPSHTTPSZeroMQ
学习曲线
适合场景通用大规模大规模大规模
社区最大

选型建议:入门自动化运维首选 Ansible(无 Agent、YAML 简单易学);大规模基础设施管理考虑 Puppet 或 SaltStack。Ansible 是目前最流行的配置管理工具。