Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

KVM 防止“单个虚拟机拖死整台宿主机”

这是一个非常核心、非常“生产级”的问题

一句话先给结论:

KVM 防止“单个虚拟机拖死整台宿主机”的手段,本质是: 用 Linux 内核的「资源隔离 + 调度 + 强制上限」去约束 QEMU 进程。

下面从 设计思想 -> 核心机制 -> 实战配置 -> 典型事故 -> 面试总结 五个层次,把这个问题讲透。


一、问题本质(先想清楚)

在宿主机眼里,每个虚拟机 = 一个(或多个)QEMU 进程

如果不限制:

  • CPU 打满 -> Host 卡死
  • 内存吃光 -> OOM -> 全部服务崩
  • I/O 狂刷 -> 全盘抖
  • 网络风暴 -> 宿主机丢包

所以目标是:

让 VM“最多把自己玩死”,但永远拖不垮宿主机


二、KVM 防护的总体设计思想

QEMU 进程
 ├── CPU:cgroup + 调度器
 ├── 内存:hard limit + OOM 控制
 ├── I/O:blkio / io controller
 ├── 网络:qdisc / virtio-net
 └── 故障:自动隔离 / kill

KVM 不自己造轮子,而是全面复用 Linux 内核能力


三、CPU 防护(最重要、最容易忽略)

1️⃣ vCPU ≠ 物理 CPU

  • vCPU 是 线程
  • 调度由 Linux CFS 调度器 控制

防护机制

机制 作用
vCPU 上限 限制最大并发
CPU pinning 防止抢占
CPU share / quota 限速

2️⃣ CPU 上限(必须配置)

libvirt XML 示例

<vcpu placement='static'>4</vcpu>

<cputune>
  <shares>1024</shares>
  <quota>400000</quota>   <!-- 4 核 -->
  <period>100000</period>
</cputune>

效果:

  • VM CPU 打满
  • Host 仍然流畅

3️⃣ CPU Pinning(生产强烈推荐)

<cputune>
  <vcpupin vcpu='0' cpuset='2'/>
  <vcpupin vcpu='1' cpuset='3'/>
</cputune>

👉 防止 VM 抢占宿主机关键核


四、内存防护(最致命)

90% 的“整机被拖死”来自内存失控


1️⃣ 内存硬限制(不是建议,是必须)

<memory unit='MiB'>8192</memory>
<currentMemory unit='MiB'>8192</currentMemory>

结果

  • VM 内存永远不会超过 8G
  • Host 不会被吃空

2️⃣ 禁止 overcommit(关键)

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

👉 防止所有 VM 加起来“纸面内存 > 实际内存”


3️⃣ OOM 优先级(救宿主机)

echo -1000 > /proc/$(pidof qemu-system-x86_64)/oom_score_adj
  • VM OOM 优先
  • Host 永远最后死

4️⃣ Balloon(动态回收)

<memballoon model='virtio'/>
  • 回收空闲内存
  • 防止虚拟机假占用

五、磁盘 I/O 防护(最容易被忽视)

一个 fsync 风暴 = 整机卡死


1️⃣ blkio 限速

<blkio>
  <weight>500</weight>
</blkio>

或:

<disk>
  <iotune>
    <read_bytes_sec>10485760</read_bytes_sec>
    <write_bytes_sec>10485760</write_bytes_sec>
  </iotune>
</disk>

👉 VM 最多 10MB/s


2️⃣ 强制 virtio + io_uring

  • 禁止 IDE
  • 禁止 qcow2 on busy host(生产建议 LVM / raw)

六、网络防护(防广播风暴)

1️⃣ 虚拟网卡限速

<interface>
  <bandwidth>
    <inbound average='100000'/>
    <outbound average='100000'/>
  </bandwidth>
</interface>

2️⃣ Bridge 层防护

tc qdisc add dev br0 root tbf rate 100mbit burst 32k latency 400ms

七、调度与优先级(宿主机永远优先)

renice -10 $(pidof qemu-system-x86_64)

或 systemd:

[Service]
CPUWeight=100
MemoryMax=8G
IOWeight=100

八、libvirt 的“最后一道保险”

自动 kill

  • VM 超限
  • Host 内存不足
  • libvirt 优先杀 VM

Watchdog

<watchdog model='i6300esb' action='reset'/>

九、真实生产事故案例(你一定会遇到)

❌ 未限内存

  • 一个 VM OOM
  • Host swap 爆
  • SSH 卡死
  • 所有 VM 挂

✅ 正确配置

  • VM 被 kill
  • Host 无感知
  • 其他 VM 正常

十、生产级「防拖死」清单(必做)

  • ✅ vCPU 不超卖
  • ✅ 内存 hard limit
  • ✅ 禁止内存 overcommit
  • ✅ blkio 限速
  • ✅ 网络限速
  • ✅ CPU pinning
  • ✅ OOM 优先级
  • ✅ Watchdog

十一、总结

KVM 通过把虚拟机映射为受 cgroup 管控的 QEMU 进程,结合 CPU、内存、I/O、网络的硬限制与调度机制,确保单个虚拟机资源失控只会影响自身,而不会拖垮宿主机。