VCPU Scheduling: VM CPU Management (Artikel 406)
Beherrschung der virtuellen CPU-Verwaltung unter Linux. Erfahren Sie alles über VCPU-Scheduling, CPU-Overcommitment und die Vermeidung von Latenzen in Multi-VM-Umgebungen.
# VCPU Scheduling: Das Orchester der virtuellen Kerne
TL;DR / Management Summary Ein Prozessor in einer VM ist keine echte Hardware, sondern ein Thread auf dem Host-System. Der VCPU-Scheduler des Kernels muss entscheiden, welcher dieser Gast-Threads auf welchem echten CPU-Kern rechnen darf. Ein Senior Admin muss das Phänomen der CPU Steal Time verstehen, das richtige Overcommitment-Verhältnis wählen und wissen, wann er Kerne fest an VMs bindet (Pinning), um “Ready-Wait” Latenzen in hochverdichteten Clustern zu vermeiden.
# 1. Einführung & Architektur
Vom Gast-Prozess zum Host-Thread.
Für den Linux-Host ist jede VCPU einer VM (z.B. QEMU/KVM) ein ganz normaler User-Space Prozess (oder Thread).
# Die Scheduling-Schichten (Mermaid)
graph TD
subgraph "Guest VM"
A[Guest Process A] --> B[VCPU 0]
C[Guest Process B] --> D[VCPU 1]
end
subgraph "KVM Hypervisor"
B --> E[QEMU Thread PID 101]
D --> F[QEMU Thread PID 102]
end
subgraph "Host Hardware"
G[Physical Core 0]
H[Physical Core 1]
I[Host Scheduler: CFS]
end
E --> I
F --> I
I --> G
I --> H
# 2. CPU Overcommitment
Mehr verkaufen als man hat.
In der Cloud-Welt ist es üblich, mehr VCPUs an Gäste zu vergeben, als physische Kerne vorhanden sind.
- Standard (Enterprise): 1:2 bis 1:4 (z.B. 16 physische Kerne bedienen 64 VCPUs).
- Kritische Lasten: 1:1 (Kein Overcommitment).
# 3. Die wichtigste Metrik: CPU Steal Time
Wenn der Host die Zeit klaut.
Steal Time (%st) ist die Zeit, in der eine VM eigentlich rechnen wollte, der Host-Scheduler ihr aber keinen physischen Kern zugewiesen hat.
# Monitoring im Gast
top
# Achten Sie in der CPU-Zeile auf den Wert '%st'.
# Alles über 5-10% dauerhaft deutet auf einen überlasteten Host hin.
# 4. Day-2 Operations: VCPU Pinning
Garantierte Rechenkraft.
Um Latenzen zu minimieren, können wir VCPU-Threads fest an physische Kerne binden.
# Beispiel: Pinning via Libvirt
<!-- In der virsh XML einer VM -->
<cputune>
<vcpupin vcpu='0' cpuset='2'/>
<vcpupin vcpu='1' cpuset='3'/>
</cputune>
- Vorteil: Keine Cache-Verluste (Artikel 381).
- Nachteil: Flexibilität des Schedulers sinkt massiv.
# 5. Troubleshooting & “War Stories”
Wenn die VM ‘hängt’.
# Story 1: “Das Co-Scheduling Dilemma”
Symptom: Eine VM mit 32 VCPUs ist auf einem 32-Kern Host extrem langsam, obwohl die Last im Gast nur bei 10% liegt. Ursache: Der Scheduler versucht oft, alle VCPUs einer VM gleichzeitig auf physische Kerne zu legen (Gang Scheduling). Wenn Hintergrundprozesse auf dem Host auch nur einen Kern belegen, muss die gesamte 32-VCPU VM warten. Lösung: Nutzen Sie kleinere VMs (z.B. 4 oder 8 VCPUs). Mehrere kleine VMs lassen sich für den Host-Scheduler deutlich effizienter jonglieren als eine riesige “Monster-VM”.
# Story 2: “Das hängende Backup”
Symptom: Während des Host-Backups (Kompression) steigen die Antwortzeiten aller VMs massiv an.
Ursache: Der Backup-Prozess nutzt alle freien CPU-Zyklen mit der gleichen Priorität wie die VMs.
Lösung: Nutzen Sie Slices (Artikel 374) oder nice, um dem Hypervisor-Prozess (QEMU) eine höhere Priorität zu geben als den Wartungs-Skripten.
# 6. Fazit & Empfehlung
- Wahl: Nutzen Sie das 1:1 Pinning nur für Datenbanken oder Echtzeit-Apps.
- Wartung: Überwachen Sie die Steal-Time in Ihren VMs. Sie ist der ehrlichste Indikator für Hardware-Engpässe.
- Design: Bauen Sie Ihre Infrastruktur aus vielen kleinen statt wenigen riesigen VMs auf.
# Anhang: Cheatsheet
| Aufgabe | Befehl / Ort |
|---|---|
| Steal Time prüfen | top oder iostat |
| VCPU zu PID Map | virsh vcpupin <name> |
| CPU Topologie Host | lscpu -e |
| Host Last prüfen | htop (Achtung auf QEMU PIDs) |
| Scheduler Latenz | perf sched latency |
| VM Last begrenzen | virsh schedinfo <name> --set cpu_shares=1024 |
| CPU Typ setzen | host (für maximale Features) |
| Hyper-Threading Check | cat /sys/devices/system/cpu/smt/active |
| Kern-Isolierung | isolcpus (Boot-Parameter) |
| XML Editor | virsh edit <name> |