跳到主要内容

大规模批量操作

问题

需要对 500 台服务器批量执行操作(如安全补丁、配置变更),如何安全高效地执行?

答案

核心原则

批量操作安全红线
  1. 灰度执行:先 1 台 → 10% → 50% → 100%,每步验证
  2. 可回滚:每个操作都准备好回滚方案
  3. 有限并发:不要同时操作所有机器
  4. 有审批:变更必须经过审批流程

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 台服务器批量操作出问题怎么办?

答案

  1. 立即停止后续批次:Ansible max_fail_percentage 或手动 Ctrl+C 停止
  2. 评估影响范围:确认已执行的批次中有多少台失败
  3. 回滚已操作的机器
    # yum 回滚
    yum history undo last
    # 或 Ansible 执行回滚 playbook
  4. 修复问题:分析失败原因,修改脚本/playbook
  5. 重新灰度执行:修复后从小批次重新开始

关键是每批操作后都要验证,发现问题时影响面还在可控范围内。

相关链接