Ansible批量更新多台服务器系统补丁

多台Linux服务器需要打补丁时,逐台登录执行命令既慢又容易漏。
用Ansible批量更新多台服务器系统补丁,可以把"登录、检查、升级、重启"这套动作一次性发到所有机器。
本文面向零基础用户,从Inventory配置讲到Playbook执行,最后给出验证方法,照着做就能完成一轮补丁更新。

开始之前:控制机、被管机和免密登录

Ansible采用无Agent架构,只需要一台控制机(安装Ansible的机器)和若干被管机(要打补丁的服务器)。
控制机通过SSH连接被管机执行任务,所以第一步是把SSH打通。

控制机上安装Ansible,不同发行版命令略有差异,建议以官方文档为准:

# Debian/Ubuntu
apt update && apt install -y ansible

# RHEL/CentOS/Rocky/AlmaLinux
dnf install -y epel-release && dnf install -y ansible

安装后确认版本:

ansible --version

接着配置免密登录。
如果控制机还没有密钥对,先生成:

ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519

把公钥分发到每台被管机(首次仍需输入密码):

ssh-copy-id root@192.168.1.101

多台机器可以写个循环,或者直接用Ansible的authorized_key模块。
免密成功后,用ssh root@192.168.1.101能直接进入,说明通道正常。

编写Inventory:告诉Ansible要管哪些机器

Inventory是主机清单文件,默认路径/etc/ansible/hosts,也可以自己指定。
建议在项目目录下建一个,方便版本管理:

[web]
192.168.1.101
192.168.1.102

[db]
192.168.1.201

[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3

ansible_python_interpreter建议显式指定,避免被管机上Python路径不一致导致模块执行失败。
保存为inventory.ini后,先做一次连通性测试:

ansible -i inventory.ini all -m ping

如果每台都返回pong,说明控制机和被管机之间的连接、认证、Python环境都正常。这一步是后续所有操作的前提,不要跳过。

用临时命令先做一次快速更新

如果只是想快速跑一轮补丁,不打算写成固定脚本,可以用ansible临时命令。
按被管机发行版选择包管理器。

Debian/Ubuntu系:

ansible -i inventory.ini all -m apt -a "update_cache=yes upgrade=dist" --become

RHEL/CentOS/Rocky/AlmaLinux系:

ansible -i inventory.ini all -m dnf -a "name=* state=latest" --become

--become表示提权执行,对应sudo
如果被管机用普通用户登录,需要该用户有sudo权限,并在Inventory或命令行里提供--ask-become-pass

临时命令适合验证流程是否跑得通,缺点是无法控制"更新前检查、更新后重启、失败重试"这类顺序逻辑。
真正生产环境更推荐Playbook。

写成Playbook:把补丁更新流程固定下来

Playbook是YAML格式的任务剧本,可以把多个步骤编排在一起。
下面这份适合Debian/Ubuntu系,包含更新缓存、升级、清理和条件重启:

---
- name: 批量更新系统补丁
  hosts: all
  become: true
  serial: 2
  tasks:
    - name: 更新apt缓存
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: 执行安全升级
      apt:
        upgrade: dist
      register: upgrade_result

    - name: 清理无用包
      apt:
        autoremove: yes
        autoclean: yes

    - name: 需要时重启
      reboot:
        msg: "Ansible触发的补丁更新重启"
        reboot_timeout: 600
      when: upgrade_result.changed

serial: 2表示一次只处理2台,避免所有机器同时重启导致服务整体中断。when: upgrade_result.changed保证没有实际更新时不触发重启。

RHEL系把apt模块换成dnfyum即可:

- name: 执行系统升级
  dnf:
    name: "*"
    state: latest
  register: upgrade_result

保存为patch.yml后执行:

ansible-playbook -i inventory.ini patch.yml

执行过程中Ansible会输出每台机器的任务状态,ok表示无变化,changed表示有改动,failed表示出错。先在小批量机器上跑通,再扩大范围。

常见报错和处理思路

补丁更新过程中最常遇到的几类问题:

  • SSH连接失败:先单独ssh到目标机确认,再检查Inventory里的IP、端口、用户名和密钥路径。
  • sudo权限不足:被管机用户需要在/etc/sudoers/etc/sudoers.d/里有对应权限,否则--become会失败。
  • 包管理器被锁:报错常见"Could not get lock",说明有另一个apt/dnf进程在运行,等它结束或排查是否有自动更新任务。
  • 内核更新后未重启:补丁装上了但内核还是旧的,需要重启才生效。Playbook里的reboot任务就是处理这种情况。
  • Python缺失:部分精简系统没有python3,Ansible无法执行模块,需要先装上。

遇到failed时,加上-vvv可以看详细输出:

ansible-playbook -i inventory.ini patch.yml -vvv

确认补丁是否真的生效

更新跑完不等于补丁生效,需要验证。
可以从几个角度检查:

  • 查看内核版本:ansible -i inventory.ini all -m shell -a "uname -r"
  • 列出可升级包:ansible -i inventory.ini all -m shell -a "apt list --upgradable"(Debian系)或dnf check-update(RHEL系)
  • 检查是否需要重启:ansible -i inventory.ini all -m shell -a "test -f /var/run/reboot-required && echo YES || echo NO"

如果可升级列表为空、且重启标记为NO,说明这一轮补丁已经装好。每台机器都确认一遍,比只看Playbook回显更可靠。

几个容易踩的坑

第一,不要在业务高峰期执行重启类更新,尤其是数据库和网关机器,serial参数要调小。

第二,区分安全更新和全量更新
全量dist-upgrade可能带入新特性甚至不兼容变更,生产环境建议先评估,必要时只跑安全源。

第三,保留回滚准备
重要机器更新前做快照或备份关键配置,出问题能快速恢复。

第四,Inventory里的主机名和实际一致
用IP和主机名混用容易导致SSH指纹或证书校验失败,统一一种方式更省心。

多台服务器打补丁的核心思路就是:把登录、更新、重启、验证这几步交给Ansible统一执行。
先在测试机跑通Playbook,再分批推到生产,配合serialwhen控制节奏,就能把重复劳动变成一次可复用的操作。

分享到:
上一篇
Grafana自定义仪表盘,可视化服务器指标
下一篇
Shell脚本自动检测网站连通性
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意