大规模批量操作
问题
需要对 500 台服务器批量执行操作(如安全补丁、配置变更),如何安全高效地执行?
答案
核心原则
批量操作安全红线
- 灰度执行:先 1 台 → 10% → 50% → 100%,每步验证
- 可回滚:每个操作都准备好回滚方案
- 有限并发:不要同时操作所有机器
- 有审批:变更必须经过审批流程
Ansible 分批执行
# playbook-patch.yml
---
- name: 安全补丁批量更新
hosts: all
serial: "10%" # 每批处理 10% 的主机
max_fail_percentage: 5 # 超过 5% 失败则停止
pre_tasks:
- name: 从负载均衡摘除
uri:
url: "http://lb-api/deregister/{{ inventory_hostname }}"
method: POST
delegate_to: localhost
- name: 等待连接排空
pause:
seconds: 30
tasks:
- name: 更新安全补丁
yum:
name: '*'
state: latest
security: yes
register: patch_result
- name: 需要重启时重启
reboot:
reboot_timeout: 300
when: patch_result.changed
- name: 等待服务恢复
wait_for:
port: 8080
delay: 10
timeout: 120
post_tasks:
- name: 健康检查
uri:
url: "http://{{ inventory_hostname }}:8080/health"
status_code: 200
retries: 5
delay: 10
- name: 注册回负载均衡
uri:
url: "http://lb-api/register/{{ inventory_hostname }}"
method: POST
delegate_to: localhost
# 执行方式:先在一台测试
ansible-playbook -i inventory playbook-patch.yml --limit "test-server-01"
# 确认无问题后灰度执行
ansible-playbook -i inventory playbook-patch.yml --limit "canary-group"
# 全量执行
ansible-playbook -i inventory playbook-patch.yml
Shell 并发控制
#!/bin/bash
# 简单的并发控制批量执行脚本
SERVERS_FILE="servers.txt" # 服务器列表
MAX_PARALLEL=10 # 最大并发数
BATCH_SIZE=50 # 每批数量
TOTAL=$(wc -l < "$SERVERS_FILE")
BATCH=0
while IFS= read -r server; do
((BATCH++))
# 并发执行
(
echo "[$(date)] 开始: $server"
ssh "$server" "yum update -y --security" > "/tmp/patch_${server}.log" 2>&1
if [ $? -eq 0 ]; then
echo "[$(date)] 成功: $server"
else
echo "[$(date)] 失败: $server" >&2
fi
) &
# 控制并发数
if (( $(jobs -r | wc -l) >= MAX_PARALLEL )); then
wait -n # 等待任一子进程结束
fi
# 每批次暂停确认
if (( BATCH % BATCH_SIZE == 0 )); then
wait # 等待当前批次全部完成
echo "=== 已完成 $BATCH / $TOTAL,按 Enter 继续下一批 ==="
read -r
fi
done < "$SERVERS_FILE"
wait
echo "=== 全部完成 ==="
操作记录与审计
# 变更记录模板
## 变更单:SEC-2024-0115
- 变更内容:安全补丁更新(CVE-2024-xxxx)
- 影响范围:全部 Web 服务器(500 台)
- 执行方式:Ansible 分批(10% 灰度)
- 回滚方案:yum history undo
- 审批人:张三
- 执行人:李四
- 执行时间:2024-01-15 03:00 ~ 06:00
常见面试问题
Q1: 500 台服务器批量操作出问题怎么办?
答案:
- 立即停止后续批次:Ansible
max_fail_percentage或手动 Ctrl+C 停止 - 评估影响范围:确认已执行的批次中有多少台失败
- 回滚已操作的机器:
# yum 回滚
yum history undo last
# 或 Ansible 执行回滚 playbook - 修复问题:分析失败原因,修改脚本/playbook
- 重新灰度执行:修复后从小批次重新开始
关键是每批操作后都要验证,发现问题时影响面还在可控范围内。