1. 项目背景与问题描述
上周五晚上10点23分,我们托管在PVE虚拟化平台上的9台关键业务服务器突然集体宕机。监控系统显示所有虚拟机同时失去响应,控制台无法连接,SSH访问中断。最诡异的是——这些服务器虽然都是虚拟机,但分布在3台不同的物理宿主机上。
关键现象:所有虚拟机CPU负载瞬间飙升到100%,内存使用率异常增高,但网络和存储IO却几乎归零。
2. 故障排查过程实录
2.1 第一阶段:基础检查
首先通过IPMI连接物理宿主机,发现:
- 宿主机本身运行正常
top命令显示qemu进程占用大量CPUdmesg中出现大量KVM相关警告:
code复制[98532.411753] kvm [pid]: vCPU0 stuck for 205s!
2.2 第二阶段:存储系统排查
检查Ceph集群状态:
bash复制ceph -s
输出显示所有OSD都处于active+clean状态,但延迟异常增高:
code复制client io 1800ms+ delayed
2.3 第三阶段:网络诊断
通过tcpdump抓取管理网卡流量:
bash复制tcpdump -i vmbr0 port 22 -w ssh.pcap
发现大量TCP重传和Dup ACK,指向网络拥塞。
3. 根本原因分析
3.1 时间同步风暴
最终定位到根本原因:NTP服务异常导致的时间同步风暴。具体表现为:
- 所有虚拟机突然检测到系统时间偏差超过500秒
- 触发glibc的
futex时间补偿机制 - 补偿过程产生大量CPU计算需求
- KVM的CPU调度器进入死锁状态
3.2 PVE特定问题
PVE的默认配置加剧了这个问题:
ini复制# /etc/pve/qemu-server/XXX.conf
args: -rtc driftfix=slew
当时间偏差超过阈值时,slew模式会导致更剧烈的补偿行为。
4. 解决方案与实施
4.1 紧急恢复步骤
- 批量关闭受影响虚拟机:
bash复制for vm in {101..109}; do qm stop $vm --force; done
- 修复宿主机NTP配置:
bash复制systemctl stop chronyd
chronyd -q 'server ntp.aliyun.com iburst'
- 调整虚拟机配置:
bash复制qm set 101 -args "-rtc base=utc,driftfix=none"
4.2 长期预防措施
- 硬件时钟同步方案:
mermaid复制graph TD
A[物理宿主机] -->|chrony| B(原子钟)
A -->|PTP| C(交换机时钟)
D[虚拟机] -->|QEMU Guest Agent| A
- 监控策略优化:
- 添加对
/proc/sys/kernel/watchdog_thresh的监控 - 设置虚拟机时间偏差告警阈值(建议<200ms)
5. 经验总结与避坑指南
5.1 关键教训
-
不要依赖虚拟机自身的时间同步:实测发现Windows VM的时间漂移可达2秒/小时
-
警惕级联故障:我们案例中,一个NTP服务器故障引发了存储、计算、网络的多重问题
5.2 PVE最佳实践
- 内存分配策略:
bash复制# 避免内存气球过度收缩
qm set 101 -balloon 0
- CPU热插拔配置:
ini复制hotplug: cpu,memory,disk,network
- 监控关键指标:
code复制PVE_METRIC="kvm_exit_io|kvm_exit_mmio"
vmstat 1 | grep -E "$PVE_METRIC"
6. 故障复盘时间线
| 时间 | 事件 | 影响时长 |
|---|---|---|
| 22:23 | 首次告警触发 | 0 |
| 22:30 | 存储延迟超阈值 | 7分钟 |
| 22:45 | 第一台宿主机告警 | 22分钟 |
| 23:10 | 定位时间同步问题 | 47分钟 |
| 23:40 | 全部业务恢复 | 77分钟 |
这次事故教会我们:虚拟化环境的问题往往比物理环境更隐蔽。建议所有使用PVE的管理员:
- 定期检查
/var/log/pve/tasks/日志 - 为关键虚拟机配置HA
- 建立跨物理机的故障隔离域
