Ansible 自动化运维实战:用 Playbook 批量管理与配置服务器

在运维规模从"几台机器"膨胀到"几十上百台"之后,靠 SSH 一台台登录敲命令很快就会触及人力天花板。Ansible 是目前最流行的无代理(agentless)自动化运维工具之一:它不需要在被控端安装任何客户端,仅依赖 SSH 和 Python 就能完成配置管理、应用部署、批量命令执行等任务。本文从核心概念讲到可落地的实战 Playbook,帮助你把重复的运维动作沉淀成可复用、可审计的代码。

一、为什么选 Ansible

市面上的配置管理工具有 SaltStack、Puppet、Chef 等,但 Ansible 凭借"无代理 + YAML 易读 + 社区庞大"的特点,成为很多团队的第一选择。

特性Ansible传统脚本 / 手动 SSH
被控端依赖仅需 SSH + Python无统一标准,易出错
可读性YAML 声明式,接近自然语言Shell 脚本逻辑分散
幂等性内置,重复执行结果一致需自己处理
批量能力Inventory 分组,并行执行循环 SSH,慢且难管理
学习成本低,半天可上手视个人而定

幂等性(idempotence)是 Ansible 的灵魂:同一个 Playbook 无论执行一次还是一百次,系统最终状态都一致,不会重复创建用户或重复写入文件。

二、架构与核心概念

Ansible 采用控制节点(Control Node)→ 被控节点(Managed Node) 的模型:

  • Inventory(清单):记录所有被管主机的文件,可按环境/角色分组。
  • Module(模块):真正干活的最小单元,如 copyyumservice。Ansible 把模块推送到远端执行后自行清理。
  • Playbook(剧本):用 YAML 描述"要在哪些主机上、按什么顺序、做什么事"的编排文件。
  • Role(角色):把 Playbook 按功能拆分重用的目录结构。
  • Fact(事实):执行前自动收集的远端主机信息(OS、IP、内存等)。

三、安装控制节点

以 CentOS / Rocky 为例:

# 控制节点(推荐 Python 3.9+)
pip3 install ansible

# 验证
ansible --version

# 被控节点只需保证:
# 1. 开启 SSH 且控制节点能免密登录
# 2. 已安装 Python 3

四、Inventory:管理你的主机清单

静态清单可以用 INI 或 YAML 格式。YAML 更清晰,推荐新项目使用:

# inventory.yml
all:
  children:
    web:
      hosts:
        192.168.10.11:
        192.168.10.12:
    db:
      hosts:
        192.168.20.21:
  vars:
    ansible_user: deploy
    ansible_ssh_private_key_file: ~/.ssh/id_rsa

测试连通性:

ansible all -i inventory.yml -m ping
# 192.168.10.11 | SUCCESS => {"changed": false, "ping": "pong"}

五、Ad-hoc:一行命令批量执行

不需要写 Playbook 时,ad-hoc 命令最适合临时操作:

# 查看所有主机负载
ansible all -i inventory.yml -a "uptime"

# 批量安装 nginx
ansible web -i inventory.yml -m yum -a "name=nginx state=present" -b

# 启动并设置开机自启
ansible web -i inventory.yml -m service -a "name=nginx state=started enabled=yes" -b

-b 表示以 sudo 提权执行,-m 指定模块,-a 传模块参数。

六、Playbook:把运维动作写成代码

下面是一个批量部署 Nginx 并写入自定义首页的完整 Playbook:

# deploy_nginx.yml
- name: 部署并配置 Nginx
  hosts: web
  become: yes
  vars:
    site_title: "Ansible Managed Site"
  tasks:
    - name: 安装 Nginx
      yum:
        name: nginx
        state: present

    - name: 写入首页
      template:
        src: index.html.j2
        dest: /usr/share/nginx/html/index.html
      notify: 重启 Nginx

    - name: 确保 Nginx 运行
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: 重启 Nginx
      service:
        name: nginx
        state: restarted

配套模板 index.html.j2

{{ site_title }}

由 Ansible 于 {{ ansible_date_time.date }} 自动部署

执行并默认开启 dry-run(不真正改动):

# 预演,确认影响范围
ansible-playbook deploy_nginx.yml -i inventory.yml --check

# 正式执行
ansible-playbook deploy_nginx.yml -i inventory.yml

notify + handlers 实现了"配置变化才重启服务"的优雅逻辑,避免无谓重启。

七、变量、循环与条件

真实场景往往需要批量与判断。下面示例批量创建用户并仅对 web 组做额外配置:

- name: 演示变量与循环
  hosts: all
  become: yes
  vars:
    users:
      - alice
      - bob
  tasks:
    - name: 批量创建用户
      user:
        name: "{{ item }}"
        state: present
        groups: wheel
      loop: "{{ users }}"

    - name: 仅 web 组安装监控 agent
      yum:
        name: node_exporter
        state: present
      when: "'web' in group_names"

八、Role:让项目可维护、可复用

当 Playbook 变长,请用 Role 拆分。标准 Role 目录:

roles/
  nginx/
    tasks/main.yml
    handlers/main.yml
    templates/index.html.j2
    vars/main.yml
    defaults/main.yml
    meta/main.yml

roles/nginx/tasks/main.yml

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

- name: 渲染配置
  template:
    src: index.html.j2
    dest: /usr/share/nginx/html/index.html
  notify: 重启 Nginx

顶层调用:

- hosts: web
  become: yes
  roles:
    - nginx

Role 可以从 Ansible Galaxy 拉取社区成熟方案:ansible-galaxy install geerlingguy.nginx

九、安全:用 ansible-vault 管理密钥

永远不要把密码明文写进仓库。用 vault 加密敏感变量:

# 创建加密变量文件
ansible-vault create group_vars/all/vault.yml

# 编辑
ansible-vault edit group_vars/all/vault.yml

# 执行时提供密码
ansible-playbook site.yml --ask-vault-pass

vault.yml 示例:

vault_db_password: "S3cret@2026"

在 Playbook 中引用:"{{ vault_db_password }}"

十、生产环境最佳实践

  1. --check 后执行:正式变更前务必 dry-run,确认影响的主机与动作。
  2. 标签(tags)控制执行范围:给任务打 tags: config,用 --tags config 只跑配置类任务。
  3. 版本化 Inventory:把 inventory 和 Playbook 一起纳入 Git,变更可追溯。
  4. 小步快跑:大变更拆成多个 Playbook 分批灰度,先 1 台验证再全量。
  5. 利用 Facts 做差异化:通过 ansible_distributionansible_memtotal_mb 等事实编写跨平台任务。
  6. 限制并发forks 参数控制并行数,超大集群可配合 serial 滚动执行避免雪崩。

十一、常见问题排查

现象原因解决办法
UNREACHABLESSH 不通 / 密钥错误检查 `ansible_user`、`ansible_ssh_private_key_file` 与免密登录
Python 缺失报错被控端无 Python安装 `python3` 或用 `raw` 模块先装
权限不足未提权加 `become: yes` 或命令补 `-b`
模板渲染失败变量未定义用 `default()` 兜底:`{{ vardefault('x') }}`
任务卡住远端命令交互式等待模块参数加 `creates`/`removes` 或避免交互式命令

结语

Ansible 把"运维经验"变成了可版本化、可复用的代码,是 DevOps 流水线中连接"构建"与"稳定运行"的关键一环。它与前文介绍的 GitHub Actions 持续集成天然互补:CI 负责把代码构建打包,Ansible 负责把产物稳妥地铺到每一台服务器。从今天的一个 Nginx Playbook 起步,逐步把环境初始化、应用发布、配置巡检都纳入自动化,你的运维效率会发生质变。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部