Ansible 无人值守为服务器打补丁

作者:JunLan 发布时间: 2025-12-17 阅读量:58 评论数:0

Ansible

一、概述

1.1 背景介绍

每个季度的安全补丁更新是运维团队的噩梦。上个季度我们还在用 SSH 跳板机 + xshell 批量执行脚本的方式给服务器打补丁,500 台机器分 10 批次,整整熬了三个通宵。中间还出了两次事故:一次是补丁依赖冲突导致某台数据库服务器重启失败,另一次是并发太高把内网带宽打满了。

痛定思痛,我们决定用 Ansible 重构整个补丁管理流程。这套方案跑了两个季度,现在 500 台服务器的补丁更新,从晚上 10 点开始,第二天早上 6 点收工,全程无人值守。这篇文章把踩过的坑和最终方案都记录下来。

1.2 技术特点

  • 幂等性保障 :Ansible 的 yum/apt 模块天然支持幂等操作,重复执行不会造成问题,中断后可以安全重试
  • 滚动更新 :通过 serial 参数控制并发数,避免同时重启太多机器影响业务
  • 自动回滚 :结合健康检查,发现异常自动停止后续批次,保留现场等待人工介入
  • 详细日志 :每台机器的执行结果都有记录,事后审计和故障定位都很方便

1.3 适用场景

  • 场景一:季度/月度安全补丁批量更新,需要在维护窗口内完成大量服务器的系统升级
  • 场景二:紧急漏洞修复,比如 log4j 这种 0day,需要快速在全网推送修复补丁
  • 场景三:内核升级,需要有序重启服务器并验证业务恢复状态

1.4 环境要求

组件 版本要求 说明
Ansible 控制节点 CentOS 7+ / Ubuntu 18.04+ 建议使用专用的运维跳板机
Ansible 2.9+ (推荐 2.12+) 2.12 版本的性能优化明显
Python 3.6+ 目标机器需要安装 Python
目标服务器 CentOS 7/8、Ubuntu 18/20/22 混合环境需要区分 playbook
网络 控制节点到目标机器 SSH 可达 建议配置 SSH 密钥认证

二、详细步骤

2.1 准备工作

◆ 2.1.1 系统检查

# 检查 Ansible 版本
ansible --version

# 输出示例:
# ansible [core 2.14.3]
# python version = 3.9.16

# 检查控制节点到目标机器的连通性(抽样测试几台)
ansible -i inventory/prod.ini webservers -m ping --limit'web-001,web-002,web-003'

# 检查目标机器的磁盘空间(补丁包需要空间)
ansible -i inventory/prod.ini all -m shell -a "df -h / | tail -1 | awk '{print \$5}'" --limit'web-001'

◆ 2.1.2 安装依赖

# CentOS/RHEL 安装 Ansible
sudo yum install -y epel-release
sudo yum install -y ansible

# Ubuntu/Debian 安装 Ansible
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible

# 安装额外的 collection(用于更丰富的模块支持)
ansible-galaxy collection install ansible.posix
ansible-galaxy collection install community.general

◆ 2.1.3 配置 Ansible

# 创建项目目录结构
mkdir -p ~/ansible-patching/{inventory,group_vars,roles,logs}
cd ~/ansible-patching

# 生成 ansible.cfg
cat > ansible.cfg << 'EOF'
[defaults]
inventory = ./inventory/hosts.ini
remote_user = ops
private_key_file = ~/.ssh/ops_key
host_key_checking = False
timeout = 30
forks = 20
log_path = ./logs/ansible.log
callback_whitelist = profile_tasks

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

[ssh_connection]
pipelining = True
control_path = /tmp/ansible-%%h-%%p-%%r
EOF

2.2 核心配置

◆ 2.2.1 主机清单配置

# inventory/hosts.ini
# 按照业务分组,方便灰度发布

[webservers]
web-[001:100].prod.internal

[appservers]
app-[001:150].prod.internal

[dbservers]
db-[001:050].prod.internal

[cacheservers]
redis-[001:030].prod.internal
memcache-[001:020].prod.internal

# 按照机房/可用区分组
[dc1]
web-[001:050].prod.internal
app-[001:075].prod.internal

[dc2]
web-[051:100].prod.internal
app-[076:150].prod.internal

# 定义更新批次(第一批是金丝雀,数量少)
[canary]
web-001.prod.internal
app-001.prod.internal
redis-001.prod.internal

[batch1]
web-[002:020].prod.internal
app-[002:030].prod.internal

[batch2]
web-[021:050].prod.internal
app-[031:075].prod.internal

# ... 后续批次类似

说明 :主机清单的设计很关键。我们按照三个维度分组:业务类型、机房位置、更新批次。这样在执行时可以灵活控制范围,比如只更新某个机房,或者只更新某类服务器。

◆ 2.2.2 变量配置

# group_vars/all.yml
---
# 补丁更新相关配置
patching:
# 是否允许重启
allow_reboot:true
# 重启前等待时间(秒)
reboot_delay:30
# 重启超时时间(秒)
reboot_timeout:600
# 更新后健康检查等待时间
health_check_delay:60
# 排除的包(某些包不想自动更新)
exclude_packages:
-kernel*
-docker*
# 仅安全更新
security_only:true

# 通知配置
notification:
webhook_url:"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
enabled:true
# group_vars/dbservers.yml
---
# 数据库服务器特殊配置
patching:
allow_reboot:false# 数据库服务器默认不自动重启
exclude_packages:
-kernel*
-mysql*
-mariadb*

参数说明

  • allow_reboot :是否允许自动重启。数据库这类有状态服务建议设为 false,手动处理
  • reboot_timeout :重启超时时间,老机器启动慢的话需要调大
  • exclude_packages :排除列表,避免误更新关键组件
  • security_only :只安装安全补丁,不做全量更新

◆ 2.2.3 核心 Playbook

# playbooks/patching.yml
---
-name:系统补丁更新-预检查
hosts:"{{ target_hosts | default('all') }}"
gather_facts:yes
serial:"{{ batch_size | default(50) }}"

tasks:
-name:检查磁盘空间
assert:
that:
-ansible_mounts|selectattr('mount','equalto','/')|map(attribute='size_available')|first|int>1073741824
fail_msg:"根分区剩余空间不足 1GB,跳过此主机"
tags:precheck

-name:检查系统负载
assert:
that:
-ansible_processor_vcpus>0
-(ansible_load_average.1/ansible_processor_vcpus)<2.0
fail_msg:"系统负载过高,跳过此主机"
tags:precheck

-name:记录更新前的包版本
shell:|
        rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}\n' | sort > /tmp/packages_before_{{ ansible_date_time.date }}.txt
when:ansible_os_family=="RedHat"
tags:precheck

-name:系统补丁更新-执行更新
hosts:"{{ target_hosts | default('all') }}"
gather_facts:yes
serial:"{{ batch_size | default(50) }}"
max_fail_percentage:10

pre_tasks:
-name:发送开始通知
uri:
url:"{{ notification.webhook_url }}"
method:POST
body_format:json
body:
msgtype:"text"
text:
content:"补丁更新开始: {{ inventory_hostname }} (批次 {{ ansible_play_batch }})"
delegate_to:localhost
when:notification.enabled|default(false)
ignore_errors:yes
run_once:yes

tasks:
-name:更新YUM缓存
yum:
update_cache:yes
when:ansible_os_family=="RedHat"

-name:安装安全补丁(RHEL/CentOS)
yum:
name:'*'
state:latest
security:"{{ patching.security_only | default(true) }}"
exclude:"{{ patching.exclude_packages | default([]) }}"
register:yum_result
when:ansible_os_family=="RedHat"

-name:更新APT缓存
apt:
update_cache:yes
cache_valid_time:3600
when:ansible_os_family=="Debian"

-name:安装安全补丁(Ubuntu/Debian)
apt:
upgrade:dist
update_cache:yes
register:apt_result
when:ansible_os_family=="Debian"

-name:检查是否需要重启
stat:
path:/var/run/reboot-required
register:reboot_required_file
when:ansible_os_family=="Debian"

-name:检查是否需要重启(RHEL)
command:needs-restarting-r
register:needs_restarting
failed_when:false
changed_when:false
when:ansible_os_family=="RedHat"

-name:设置重启标志
set_fact:
needs_reboot:>-
          {{ (ansible_os_family == "Debian" and reboot_required_file.stat.exists | default(false)) or
             (ansible_os_family == "RedHat" and needs_restarting.rc == 1) }}

-name:重启服务器
reboot:
reboot_timeout:"{{ patching.reboot_timeout | default(600) }}"
pre_reboot_delay:"{{ patching.reboot_delay | default(30) }}"
post_reboot_delay:30
msg:"Ansible 补丁更新后重启"
when:
-needs_reboot|default(false)
-patching.allow_reboot|default(true)

-name:等待服务恢复
wait_for:
port:"{{ item }}"
timeout:120
loop:"{{ service_ports | default([22]) }}"
when:needs_reboot|default(false)

post_tasks:
-name:记录更新后的包版本
shell:|
        rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}\n' | sort > /tmp/packages_after_{{ ansible_date_time.date }}.txt
        diff /tmp/packages_before_{{ ansible_date_time.date }}.txt /tmp/packages_after_{{ ansible_date_time.date }}.txt > /tmp/packages_diff_{{ ansible_date_time.date }}.txt || true
when:ansible_os_family=="RedHat"

-name:健康检查
uri:
url:"http://localhost:{{ health_check_port | default(8080) }}/health"
status_code:200
timeout:30
register:health_check
retries:3
delay:10
until:health_check.status==200
when:health_check_portisdefined
ignore_errors:yes

-name:发送完成通知
uri:
url:"{{ notification.webhook_url }}"
method:POST
body_format:json
body:
msgtype:"text"
text:
content:"补丁更新完成: {{ inventory_hostname }} - 状态: {{ 'SUCCESS' if not (health_check.failed | default(false)) else 'FAILED' }}"
delegate_to:localhost
when:notification.enabled|default(false)
ignore_errors:yes

2.3 启动和验证

◆ 2.3.1 执行补丁更新

# 先在金丝雀环境测试
ansible-playbook playbooks/patching.yml -e "target_hosts=canary" -e "batch_size=1" --check

# 确认无误后正式执行金丝雀批次
ansible-playbook playbooks/patching.yml -e "target_hosts=canary" -e "batch_size=1"

# 金丝雀通过后,分批次执行
ansible-playbook playbooks/patching.yml -e "target_hosts=batch1" -e "batch_size=10"
ansible-playbook playbooks/patching.yml -e "target_hosts=batch2" -e "batch_size=20"

# 或者一次性执行全部,由 serial 控制并发
ansible-playbook playbooks/patching.yml -e "target_hosts=all" -e "batch_size=30"

◆ 2.3.2 功能验证

# 查看执行日志
tail -f logs/ansible.log

# 检查更新结果汇总
ansible -i inventory/hosts.ini all -m shell -a "cat /tmp/packages_diff_*.txt 2>/dev/null | head -20" --limit'web-001'

# 检查服务状态
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl is-active nginx"

# 预期输出:每台机器都返回 active

三、示例代码和配置

3.1 完整配置示例

◆ 3.1.1 无人值守调度脚本

#!/bin/bash
# 文件路径:/opt/ansible-patching/run_patching.sh
# 功能:无人值守补丁更新调度脚本

set -e

WORK_DIR="/opt/ansible-patching"
LOG_DIR="${WORK_DIR}/logs"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${LOG_DIR}/patching_${DATE}.log"

cd${WORK_DIR}

# 函数:发送通知
send_notification() {
local message=$1
local webhook_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"

    curl -s -X POST ${webhook_url} \
        -H 'Content-Type: application/json' \
        -d "{\"msgtype\": \"text\", \"text\": {\"content\": \"${message}\"}}" \
        > /dev/null 2>&1 || true
}

# 函数:执行单个批次
run_batch() {
local batch_name=$1
local batch_size=$2

echo"[$(date)] 开始执行批次: ${batch_name}" | tee -a ${LOG_FILE}
    send_notification "[补丁更新] 开始执行批次: ${batch_name}"

if ansible-playbook playbooks/patching.yml \
        -e "target_hosts=${batch_name}" \
        -e "batch_size=${batch_size}" \
        >> ${LOG_FILE} 2>&1; then
echo"[$(date)] 批次 ${batch_name} 执行成功" | tee -a ${LOG_FILE}
        send_notification "[补丁更新] 批次 ${batch_name} 执行成功"
return 0
else
echo"[$(date)] 批次 ${batch_name} 执行失败" | tee -a ${LOG_FILE}
        send_notification "[补丁更新] 批次 ${batch_name} 执行失败,请检查"
return 1
fi
}

# 主流程
main() {
    send_notification "[补丁更新] 开始执行,预计耗时 6-8 小时"

# 金丝雀批次
if ! run_batch "canary" 1; then
        send_notification "[补丁更新] 金丝雀批次失败,终止后续更新"
exit 1
fi

# 等待 10 分钟观察金丝雀
echo"[$(date)] 等待 10 分钟观察金丝雀环境..." | tee -a ${LOG_FILE}
sleep 600

# 后续批次
local batches=("batch1:10""batch2:20""batch3:30""batch4:50""batch5:50")

for batch_config in"${batches[@]}"; do
        batch_name="${batch_config%%:*}"
        batch_size="${batch_config##*:}"

if ! run_batch "${batch_name}""${batch_size}"; then
            send_notification "[补丁更新] 批次 ${batch_name} 失败,终止后续更新"
exit 1
fi

# 批次间间隔 5 分钟
echo"[$(date)] 批次间隔等待 5 分钟..." | tee -a ${LOG_FILE}
sleep 300
done

    send_notification "[补丁更新] 全部完成!请检查各服务状态"
}

main "$@"

◆ 3.1.2 定时任务配置

# /etc/cron.d/ansible-patching
# 每月第一个周六晚上 22:00 执行补丁更新
0 22 1-7 * 6 root /opt/ansible-patching/run_patching.sh

3.2 实际应用案例

◆ 案例一:紧急漏洞修复

场景描述 :2024 年某天早上收到安全团队通知,某个 glibc 漏洞需要紧急修复,要求当天完成全网更新。

实现代码

# playbooks/emergency_patch.yml
---
-name:紧急补丁修复
hosts:"{{ target_hosts | default('all') }}"
gather_facts:yes
serial:100# 紧急情况提高并发

tasks:
-name:仅更新指定包
yum:
name:"{{ emergency_packages }}"
state:latest
when:ansible_os_family=="RedHat"

-name:验证补丁版本
shell:"rpm -q {{ item }}"
loop:"{{ emergency_packages }}"
register:version_check
when:ansible_os_family=="RedHat"

-name:显示更新后版本
debug:
msg:"{{ version_check.results | map(attribute='stdout') | list }}"

运行命令

ansible-playbook playbooks/emergency_patch.yml \
  -e "target_hosts=all" \
  -e '{"emergency_packages": ["glibc", "glibc-common"]}' \
  --forks 100

运行结果

PLAY RECAP *********************************************************************
web-001.prod.internal      : ok=4    changed=1    unreachable=0    failed=0    skipped=0
web-002.prod.internal      : ok=4    changed=1    unreachable=0    failed=0    skipped=0
...
500 台服务器全部更新完成,耗时 45 分钟

◆ 案例二:内核升级与滚动重启

场景描述 :需要升级内核修复某个性能问题,但必须保证业务不中断,采用滚动重启方式。

实现步骤

  1. 1. 首先修改配置,允许内核更新和自动重启
  2. 2. 将主机按照业务分组,确保每组重启时有其他组提供服务
  3. 3. 使用 serial: 1 逐台执行,配合负载均衡摘除
# playbooks/kernel_upgrade.yml
---
-name:内核升级-滚动更新
hosts:"{{ target_hosts }}"
gather_facts:yes
serial:1# 逐台执行

tasks:
-name:从负载均衡摘除
uri:
url:"http://{{ lb_api }}/api/v1/upstream/{{ inventory_hostname }}/down"
method:POST
delegate_to:localhost
when:lb_apiisdefined

-name:等待连接排空
wait_for:
timeout:60

-name:升级内核
yum:
name:kernel
state:latest
register:kernel_update

-name:重启服务器
reboot:
reboot_timeout:900
msg:"Ansible 内核升级重启"
when:kernel_update.changed

-name:验证内核版本
shell:uname-r
register:kernel_version

-name:重新加入负载均衡
uri:
url:"http://{{ lb_api }}/api/v1/upstream/{{ inventory_hostname }}/up"
method:POST
delegate_to:localhost
when:lb_apiisdefined

-name:等待流量恢复
wait_for:
timeout:30

四、最佳实践和注意事项

4.1 最佳实践

◆ 4.1.1 性能优化

  • 开启 SSH Pipelining :减少 SSH 连接次数,大幅提升执行速度

    # ansible.cfg
    [ssh_connection]
    pipelining = True
    
  • 调整 forks 数量 :根据控制节点性能和网络情况调整并发数

  • 4 核 8G 的机器,forks 设置 50-100 比较合适

    • 网络带宽充足时可以适当调高
    • 更新包比较大时要降低,避免打满带宽
  • 使用 Mitogen 加速 :Mitogen 是一个 Ansible 加速插件,实测能提升 2-5 倍速度

    pip install mitogen
    # ansible.cfg 添加
    [defaults]
    strategy_plugins = /path/to/mitogen/ansible_mitogen/plugins/strategy
    strategy = mitogen_linear
    

◆ 4.1.2 安全加固

  • 使用 Vault 加密敏感信息

    # 创建加密的变量文件
    ansible-vault create group_vars/all/vault.yml
    # 内容示例
    vault_webhook_key: "your-secret-key"
    vault_ssh_password: "your-password"
    
  • 限制 sudo 权限 :运维账号的 sudoers 配置只开放必要权限

    # /etc/sudoers.d/ops
    ops ALL=(root) NOPASSWD: /usr/bin/yum, /usr/bin/apt, /usr/sbin/reboot, /usr/bin/systemctl
    
  • 审计日志 :所有操作都要有日志记录,方便事后追溯

◆ 4.1.3 高可用配置

  • 多控制节点 :部署多个 Ansible 控制节点,避免单点故障
  • AWX/Tower :生产环境建议使用 AWX 或 Ansible Tower,提供 Web 界面、权限控制、执行历史等功能
  • 备份 Playbook :将 Playbook 代码托管到 Git,做好版本管理

4.2 注意事项

◆ 4.2.1 配置注意事项

警告 :补丁更新可能导致服务中断,务必在维护窗口执行,并提前做好回滚准备!

  • 注意事项一:数据库、消息队列等有状态服务,建议单独处理,不要混在批量更新里
  • 注意事项二:更新前一定要检查磁盘空间,空间不足会导致更新失败甚至系统损坏
  • 注意事项三:生产环境务必先在金丝雀/预发布环境验证,确认无问题再推全量

◆ 4.2.2 常见错误

错误现象 原因分析 解决方案
SSH 连接超时 目标机器 SSHD 服务异常或网络不通 检查网络连通性和 SSHD 服务状态
sudo 密码错误 密码过期或权限配置问题 检查 sudoers 配置,考虑使用 NOPASSWD
yum lock 错误 其他进程占用 yum 锁 kill 掉占用进程或等待其完成
重启后连接失败 启动时间过长或启动失败 增加 reboot_timeout,检查启动日志
包依赖冲突 第三方源与官方源冲突 使用 exclude 排除问题包,手动处理

◆ 4.2.3 兼容性问题

  • 版本兼容 :CentOS 7 和 CentOS 8 的包管理命令有差异(yum vs dnf),Ansible 的 yum 模块会自动处理
  • 平台兼容 :混合环境(RHEL + Ubuntu)需要用 when 条件判断,或者拆分成多个 playbook
  • 组件依赖 :某些包更新后可能需要重启服务才能生效,需要在 playbook 中处理

五、故障排查和监控

5.1 故障排查

◆ 5.1.1 日志查看

# 查看 Ansible 执行日志
tail -f /opt/ansible-patching/logs/ansible.log

# 查看详细输出(调试用)
ansible-playbook playbooks/patching.yml -vvv

# 查看目标机器的 yum 日志
ssh web-001 "tail -100 /var/log/yum.log"

# 查看系统日志(排查重启问题)
ssh web-001 "journalctl -b -1 --no-pager | tail -100"

◆ 5.1.2 常见问题排查

问题一:部分主机执行失败但没有详细错误信息

# 单独对失败主机执行,增加详细输出
ansible-playbook playbooks/patching.yml -e "target_hosts=web-001" -vvv

解决方案

  1. 1. 查看 -vvv 输出找到具体错误
  2. 2. SSH 到目标机器手动执行命令验证
  3. 3. 检查目标机器的系统日志

问题二:重启后服务没有自动恢复

# 检查服务状态
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl status nginx"

# 检查服务是否设置了开机自启
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl is-enabled nginx"

解决方案 :确保关键服务都设置了 enable,在 playbook 中增加服务状态检查

问题三:某些包被跳过没有更新

  • 症状 :yum 报告某些包没有更新,但实际上有新版本
  • 排查 :检查 exclude 配置和 yum 仓库配置
  • 解决 :确认包名没有被意外排除,检查仓库优先级

◆ 5.1.3 调试模式

# 开启 Ansible 调试模式
export ANSIBLE_DEBUG=1
ansible-playbook playbooks/patching.yml -vvv

# 使用 --step 逐步执行
ansible-playbook playbooks/patching.yml --step

# 从某个任务开始执行(之前任务跳过)
ansible-playbook playbooks/patching.yml --start-at-task="重启服务器"

5.2 性能监控

◆ 5.2.1 关键指标监控

# 监控 Ansible 控制节点资源
top -p $(pgrep -f ansible)

# 监控网络带宽使用
iftop -i eth0

# 监控执行进度
watch -n 5 'grep -c "ok=" /opt/ansible-patching/logs/ansible.log'

◆ 5.2.2 监控指标说明

指标名称 正常范围 告警阈值 说明
批次成功率 100% < 95% 单批次失败率超过 5% 需要人工介入
单机执行时间 3-10 分钟 > 30 分钟 执行时间过长可能有问题
控制节点 CPU < 50% > 80% CPU 过高需要降低 forks
网络带宽 < 70% > 90% 带宽打满需要降低并发

◆ 5.2.3 监控告警配置

# Prometheus 告警规则示例
groups:
-name:ansible-patching
rules:
-alert:PatchingBatchFailed
expr:ansible_batch_failed_hosts>0
for:5m
labels:
severity:critical
annotations:
summary:"补丁更新批次失败"
description:"批次 {{ $labels.batch }} 有 {{ $value }} 台主机失败"

5.3 备份与恢复

◆ 5.3.1 备份策略

#!/bin/bash
# 补丁更新前的快照备份脚本

HOSTS_FILE=$1
DATE=$(date +%Y%m%d)

# 对虚拟机创建快照(需要 vCenter API 或 cloud provider API)
whileread host; do
echo"Creating snapshot for ${host}..."
# VMware 示例
# govc vm.snapshot.create -vm="${host}" "pre-patching-${DATE}"

# AWS 示例
# aws ec2 create-snapshot --volume-id $(get_volume_id ${host}) --description "pre-patching-${DATE}"
done < ${HOSTS_FILE}

◆ 5.3.2 恢复流程

  1. 1. 停止服务ansible -i inventory/hosts.ini target_host -m service -a "name=nginx state=stopped"
  2. 2. 恢复快照 :通过虚拟化平台或云平台恢复到补丁前的快照
  3. 3. 验证完整性 :启动服务器,检查服务状态和数据完整性
  4. 4. 重启服务ansible -i inventory/hosts.ini target_host -m service -a "name=nginx state=started"

六、总结

6.1 技术要点回顾

  • 要点一 :合理设计主机清单分组,支持灵活的灰度发布策略
  • 要点二 :使用 serial 和 max_fail_percentage 控制更新节奏和容错
  • 要点三 :更新前后做好检查和记录,便于追溯和回滚
  • 要点四 :区分处理有状态和无状态服务,数据库等关键服务单独处理

6.2 进阶学习方向

  1. 1. AWX/Ansible Tower :生产环境建议使用,提供更好的可视化和权限管理
  1. 2. Ansible Collections :学习使用官方和社区的 Collection,避免重复造轮子
  1. 3. 配合 CI/CD 流水线 :将补丁更新集成到 GitOps 流程中
  • 学习资源:Jenkins/GitLab CI 与 Ansible 集成
    • 实践建议:补丁更新 playbook 提交到 Git,通过 MR 审批后自动执行

6.3 参考资料

  • Ansible 官方文档 - 最权威的参考
  • Red Hat 补丁管理最佳实践 - 企业级方案参考
  • Ansible for DevOps - 推荐书籍
  • r/ansible - 社区讨论

附录

A. 命令速查表

# 测试连通性
ansible all -m ping

# 检查模式(不实际执行)
ansible-playbook playbook.yml --check

# 指定主机执行
ansible-playbook playbook.yml --limit"web-001,web-002"

# 查看将要执行的主机
ansible-playbook playbook.yml --list-hosts

# 查看将要执行的任务
ansible-playbook playbook.yml --list-tasks

# 从指定任务开始
ansible-playbook playbook.yml --start-at-task="任务名"

# 使用 vault 密码文件
ansible-playbook playbook.yml --vault-password-file=.vault_pass

B. 配置参数详解

参数 说明 建议值
forks 并发执行数 20-50
serial 批次大小 10-50
max_fail_percentage 最大失败百分比 5-10
timeout SSH 连接超时 30
pipelining SSH 管道模式 True
host_key_checking 主机密钥检查 False(内网环境)

C. 术语表

术语 英文 解释
幂等性 Idempotency 多次执行结果相同,不会产生副作用
金丝雀发布 Canary Release 先在小范围验证,通过后再全量推送
滚动更新 Rolling Update 分批次逐步更新,保证服务不中断
控制节点 Control Node 运行 Ansible 命令的机器
管理节点 Managed Node 被 Ansible 管理的目标机器

评论