Skip to content

虚拟化技术

课程概述

本教程深入讲解操作系统虚拟化技术,从虚拟机到容器,从Hypervisor到cgroup/namespace,帮助你全面理解现代云计算和容器化技术的底层原理。

学习目标:

  • 理解虚拟化的类型与演进历史
  • 掌握KVM/QEMU架构与原理
  • 深入了解Hypervisor的实现机制
  • 学习Docker容器技术的内核基础
  • 掌握cgroup资源限制与namespace隔离
  • 理解虚拟化的性能优化技术

1. 虚拟化基础

1.1 虚拟化类型

┌─────────────────────────────────────────────────────────────┐
│              虚拟化技术分类                                   │
└─────────────────────────────────────────────────────────────┘

按虚拟化层次分类:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ 1. 硬件虚拟化(Full Virtualization)                          │
│    ┌─────────────────────────────────────────────────┐     │
│    │ VM1        VM2        VM3                       │     │
│    │ ┌──────┐  ┌──────┐  ┌──────┐                   │     │
│    │ │Guest │  │Guest │  │Guest │  用户态            │     │
│    │ │ OS   │  │ OS   │  │ OS   │                   │     │
│    │ └───┬──┘  └───┬──┘  └───┬──┘                   │     │
│    │     │         │         │                       │     │
│    │ ════╪═════════╪═════════╪═══════════════════    │     │
│    │     │         │         │      内核态           │     │
│    │     └─────────┴─────────┘                       │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  Hypervisor    │  (KVM/Xen/VMware)        │     │
│    │    │  (虚拟机监视器)  │                          │     │
│    │    └───────┬────────┘                          │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  Host OS       │                          │     │
│    │    └───────┬────────┘                          │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  硬件(x86/ARM)  │                          │     │
│    │    └────────────────┘                          │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 2. 操作系统虚拟化(OS-level Virtualization / Container)      │
│    ┌─────────────────────────────────────────────────┐     │
│    │ Container1 Container2 Container3                │     │
│    │ ┌──────┐  ┌──────┐  ┌──────┐    用户态         │     │
│    │ │ App1 │  │ App2 │  │ App3 │                   │     │
│    │ │ Libs │  │ Libs │  │ Libs │                   │     │
│    │ └───┬──┘  └───┬──┘  └───┬──┘                   │     │
│    │     │         │         │                       │     │
│    │ ════╪═════════╪═════════╪═══════════════════    │     │
│    │     │         │         │      内核态           │     │
│    │     └─────────┴─────────┘                       │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  Container     │  (Docker/LXC)            │     │
│    │    │  Runtime       │                          │     │
│    │    └───────┬────────┘                          │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  Host OS       │  (共享内核)              │     │
│    │    │  Linux Kernel  │                          │     │
│    │    └───────┬────────┘                          │     │
│    │            │                                    │     │
│    │    ┌───────▼────────┐                          │     │
│    │    │  硬件           │                          │     │
│    │    └────────────────┘                          │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 3. 半虚拟化(Paravirtualization)                             │
│    • Guest OS知道自己被虚拟化                               │
│    • 使用Hypercall代替特权指令                              │
│    • 性能更好,但需要修改Guest OS                            │
│    • 例: Xen PV, Hyper-V Enlightenments                    │
└─────────────────────────────────────────────────────────────┘

性能对比:
┌──────────────┬────────┬────────┬────────┬──────────────┐
│ 类型         │ 隔离性  │ 性能   │ 启动速度│ 资源开销     │
├──────────────┼────────┼────────┼────────┼──────────────┤
│ 全虚拟化     │ ★★★★★ │ ★★☆   │ 分钟级  │ 大(完整OS)   │
│ 半虚拟化     │ ★★★★  │ ★★★★  │ 分钟级  │ 较大         │
│ 容器         │ ★★★   │ ★★★★★ │ 秒级    │ 小(共享内核) │
└──────────────┴────────┴────────┴────────┴──────────────┘

1.2 CPU虚拟化

┌─────────────────────────────────────────────────────────────┐
│              CPU虚拟化技术演进                                │
└─────────────────────────────────────────────────────────────┘

x86特权级:
┌────────────────────────────────────────────────────┐
│         Ring 0 (最高特权)                           │
│         ┌──────────────┐                           │
│         │  内核        │                           │
│         └──────────────┘                           │
│         Ring 1, 2 (很少使用)                        │
│         ┌──────────────┐                           │
│         │              │                           │
│         └──────────────┘                           │
│         Ring 3 (用户态)                             │
│         ┌──────────────┐                           │
│         │  应用程序    │                           │
│         └──────────────┘                           │
└────────────────────────────────────────────────────┘

虚拟化挑战:
Guest OS期望运行在Ring 0,但实际运行在Ring 3
→ 敏感指令无法执行,导致Guest OS崩溃

解决方案演进:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ 1. 软件模拟(Binary Translation)                             │
│    ┌─────────────────────────────────────────────────┐     │
│    │ Guest OS执行特权指令                             │     │
│    │        │                                        │     │
│    │        ▼                                        │     │
│    │ ┌──────────────┐                               │     │
│    │ │ Trap to VMM  │  (陷入Hypervisor)             │     │
│    │ └──────┬───────┘                               │     │
│    │        │                                        │     │
│    │        ▼                                        │     │
│    │ ┌──────────────┐                               │     │
│    │ │ 二进制翻译    │  (将特权指令翻译成安全指令)    │     │
│    │ └──────┬───────┘                               │     │
│    │        │                                        │     │
│    │        ▼                                        │     │
│    │ ┌──────────────┐                               │     │
│    │ │ 执行翻译后指令│                               │     │
│    │ └──────────────┘                               │     │
│    │                                                │     │
│    │ 例: VMware Workstation早期版本                  │     │
│    │ 缺点: 性能损耗大(10-20%)                        │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 2. 硬件辅助虚拟化(Hardware-assisted Virtualization)         │
│    ┌─────────────────────────────────────────────────┐     │
│    │ Intel VT-x / AMD-V                              │     │
│    │                                                │     │
│    │ 新增CPU模式:                                    │     │
│    │ • VMX Root Mode (Hypervisor运行)              │     │
│    │ • VMX Non-Root Mode (Guest OS运行)            │     │
│    │                                                │     │
│    │ VMCS (Virtual Machine Control Structure)       │     │
│    │ ┌──────────────────────────────────────────┐   │     │
│    │ │ Guest State (虚拟CPU状态)                 │   │     │
│    │ │ • CS, EIP, CR0, CR3...                   │   │     │
│    │ │                                          │   │     │
│    │ │ Host State (宿主CPU状态)                  │   │     │
│    │ │ • 返回地址                                │   │     │
│    │ │                                          │   │     │
│    │ │ VM-Execution Controls                    │   │     │
│    │ │ • 哪些指令会导致VM Exit                   │   │     │
│    │ │                                          │   │     │
│    │ │ VM-Exit Information                      │   │     │
│    │ │ • 退出原因, 错误码                        │   │     │
│    │ └──────────────────────────────────────────┘   │     │
│    │                                                │     │
│    │ VM Entry: Host → Guest                         │     │
│    │ VM Exit:  Guest → Host (特权指令/中断)         │     │
│    │                                                │     │
│    │ 性能: 接近原生(1-5%损耗)                        │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 3. VCPU调度                                                 │
│    ┌─────────────────────────────────────────────────┐     │
│    │ 物理CPU: 4核                                    │     │
│    │ ┌─────┬─────┬─────┬─────┐                      │     │
│    │ │ CPU0│ CPU1│ CPU2│ CPU3│                      │     │
│    │ └──┬──┴──┬──┴──┬──┴──┬──┘                      │     │
│    │    │     │     │     │                         │     │
│    │    │     │     │     │  时间片轮转              │     │
│    │    │     │     │     │                         │     │
│    │ ┌──▼─────▼─────▼─────▼──┐                      │     │
│    │ │  Hypervisor Scheduler  │                     │     │
│    │ └──┬─────┬─────┬─────┬──┘                      │     │
│    │    │     │     │     │                         │     │
│    │    ▼     ▼     ▼     ▼                         │     │
│    │  VM1   VM2   VM3   VM4                         │     │
│    │  2VCPU 1VCPU 4VCPU 2VCPU                       │     │
│    │                                                │     │
│    │ 超配(Overcommit): VCPU总数 > 物理CPU数          │     │
│    └─────────────────────────────────────────────────┘     │
└─────────────────────────────────────────────────────────────┘

2. KVM虚拟化

2.1 KVM架构

┌─────────────────────────────────────────────────────────────┐
│              KVM (Kernel-based Virtual Machine)              │
└─────────────────────────────────────────────────────────────┘

KVM架构:
┌─────────────────────────────────────────────────────────────┐
│  用户空间                                                    │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  QEMU进程                                             │  │
│  │  ┌────────────────────────────────────────────────┐  │  │
│  │  │  虚拟机                                         │  │  │
│  │  │  ┌──────────┐  ┌──────────┐  ┌──────────┐     │  │  │
│  │  │  │ Guest    │  │ Guest    │  │ Guest    │     │  │  │
│  │  │  │ CPU      │  │ Memory   │  │ I/O      │     │  │  │
│  │  │  └────┬─────┘  └────┬─────┘  └────┬─────┘     │  │  │
│  │  │       │             │             │           │  │  │
│  │  └───────┼─────────────┼─────────────┼───────────┘  │  │
│  │          │             │             │              │  │
│  │  ┌───────▼─────────────▼─────────────▼───────────┐  │  │
│  │  │  QEMU Device Model                            │  │  │
│  │  │  • 虚拟网卡(virtio-net)                        │  │  │
│  │  │  • 虚拟硬盘(virtio-blk)                        │  │  │
│  │  │  • VGA显卡                                     │  │  │
│  │  └────────────────┬──────────────────────────────┘  │  │
│  │                   │                                  │  │
│  │                   │ ioctl(/dev/kvm)                  │  │
│  └───────────────────┼──────────────────────────────────┘  │
│                      │                                     │
│  ════════════════════▼══════════════════════════════════   │
│                                                             │
│  内核空间                                                    │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  KVM模块 (kvm.ko, kvm-intel.ko/kvm-amd.ko)          │  │
│  │  ┌────────────────────────────────────────────────┐  │  │
│  │  │  VM结构体                                       │  │  │
│  │  │  ┌──────────────────────────────────────────┐  │  │  │
│  │  │  │ VCPU 0                                   │  │  │  │
│  │  │  │ • VMCS (虚拟CPU状态)                     │  │  │  │
│  │  │  │ • 寄存器                                 │  │  │  │
│  │  │  │ • GDT/IDT                                │  │  │  │
│  │  │  └──────────────────────────────────────────┘  │  │  │
│  │  │  ┌──────────────────────────────────────────┐  │  │  │
│  │  │  │ VCPU 1                                   │  │  │  │
│  │  │  └──────────────────────────────────────────┘  │  │  │
│  │  │                                                │  │  │
│  │  │  ┌──────────────────────────────────────────┐  │  │  │
│  │  │  │ Guest Physical Memory                    │  │  │  │
│  │  │  │ (GPA → HPA映射, EPT/NPT页表)             │  │  │  │
│  │  │  └──────────────────────────────────────────┘  │  │  │
│  │  └────────────────────────────────────────────────┘  │  │
│  └──────────────────────────────────────────────────────┘  │
│                      │                                     │
│  ┌───────────────────▼──────────────────────────────────┐  │
│  │  Linux内核                                            │  │
│  │  • 进程调度                                           │  │
│  │  • 内存管理                                           │  │
│  │  • 设备驱动                                           │  │
│  └──────────────────────────────────────────────────────┘  │
│                      │                                     │
│  ════════════════════▼══════════════════════════════════   │
│                                                             │
│  硬件层                                                      │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Intel VT-x / AMD-V                                  │  │
│  │  EPT (Extended Page Tables)                          │  │
│  │  APIC虚拟化                                           │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

KVM vs QEMU:
┌─────────────────────────────────────────────────────────────┐
│ KVM:                                                        │
│ • 内核模块                                                  │
│ • 提供虚拟化能力(/dev/kvm)                                  │
│ • 处理CPU/内存虚拟化                                        │
│ • 不能单独使用                                              │
│                                                             │
│ QEMU:                                                       │
│ • 用户空间程序                                              │
│ • 设备模拟(网卡、硬盘、显卡等)                              │
│ • 可以纯软件模拟CPU(慢)                                     │
│ • 可以使用KVM加速                                           │
│                                                             │
│ KVM + QEMU = 完整的虚拟化解决方案                           │
└─────────────────────────────────────────────────────────────┘

2.2 内存虚拟化

┌─────────────────────────────────────────────────────────────┐
│              内存虚拟化 - 三层地址转换                        │
└─────────────────────────────────────────────────────────────┘

地址空间:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  Guest Virtual Address (GVA)                                │
│  ┌──────────────────────────────────────┐                  │
│  │ Guest进程看到的虚拟地址               │                  │
│  │ 例: 0x7fff1234                       │                  │
│  └────────────────┬─────────────────────┘                  │
│                   │ Guest页表(CR3)                          │
│                   ▼                                         │
│  Guest Physical Address (GPA)                               │
│  ┌──────────────────────────────────────┐                  │
│  │ Guest OS看到的"物理"地址              │                  │
│  │ 例: 0x10000000                       │                  │
│  └────────────────┬─────────────────────┘                  │
│                   │ EPT/NPT页表                             │
│                   ▼                                         │
│  Host Physical Address (HPA)                                │
│  ┌──────────────────────────────────────┐                  │
│  │ 真实的物理内存地址                    │                  │
│  │ 例: 0xA0000000                       │                  │
│  └──────────────────────────────────────┘                  │
└─────────────────────────────────────────────────────────────┘

影子页表(Shadow Page Table) - 传统方案:
┌─────────────────────────────────────────────────────────────┐
│  Guest页表           影子页表             物理内存          │
│  (GVA→GPA)          (GVA→HPA)                               │
│  ┌──────────┐      ┌──────────┐      ┌──────────┐         │
│  │ GVA: 0x0 │      │ GVA: 0x0 │      │          │         │
│  │  ↓       │      │  ↓       │      │          │         │
│  │ GPA:0x10 │─┐    │ HPA:0xA0 │───▶  │ HPA:0xA0 │         │
│  └──────────┘ │    └──────────┘      └──────────┘         │
│               │                                            │
│               │ VMM维护映射                                 │
│               │ (软件方式)                                  │
│               ▼                                            │
│         ┌──────────┐                                       │
│         │GPA→HPA表 │                                       │
│         └──────────┘                                       │
│                                                             │
│  问题:                                                      │
│  • Guest页表变化时需要同步影子页表                          │
│  • 开销大,每次TLB miss都要VMM介入                           │
└─────────────────────────────────────────────────────────────┘

EPT/NPT(硬件辅助) - 现代方案:
┌─────────────────────────────────────────────────────────────┐
│  Guest页表           EPT页表              物理内存          │
│  (GVA→GPA)          (GPA→HPA)                               │
│  ┌──────────┐      ┌──────────┐      ┌──────────┐         │
│  │ GVA: 0x0 │      │ GPA:0x10 │      │          │         │
│  │  ↓       │      │  ↓       │      │          │         │
│  │ GPA:0x10 │──▶   │ HPA:0xA0 │───▶  │ HPA:0xA0 │         │
│  └──────────┘      └──────────┘      └──────────┘         │
│       │                  │                                 │
│       │                  │                                 │
│       │  MMU硬件自动完成两级转换                            │
│       └──────────────────┘                                 │
│                                                             │
│  优点:                                                      │
│  • 硬件支持,无需VMM介入                                     │
│  • 性能接近原生                                             │
│  • Guest页表变化无需通知VMM                                 │
└─────────────────────────────────────────────────────────────┘

大页支持(Huge Pages):
┌─────────────────────────────────────────────────────────────┐
│  普通4KB页:                    大页2MB/1GB:                 │
│  ┌────────────────┐            ┌────────────────┐          │
│  │ 页表层级: 4级   │            │ 页表层级: 减少  │          │
│  │ TLB条目: 多     │            │ TLB条目: 少     │          │
│  │ TLB miss: 频繁  │            │ TLB miss: 减少  │          │
│  └────────────────┘            └────────────────┘          │
│                                                             │
│  配置大页:                                                   │
│  echo 1024 > /proc/sys/vm/nr_hugepages                      │
│  启动VM: -mem-path /dev/hugepages -mem-prealloc             │
│                                                             │
│  性能提升: 10-30% (内存密集型应用)                           │
└─────────────────────────────────────────────────────────────┘

2.3 I/O虚拟化

┌─────────────────────────────────────────────────────────────┐
│              I/O虚拟化技术                                    │
└─────────────────────────────────────────────────────────────┘

1. 设备模拟(Device Emulation):
   ┌──────────────────────────────────────────────────────┐
   │ Guest OS                                             │
   │ ┌────────────────────────┐                          │
   │ │ 驱动程序(e1000)        │                          │
   │ └────────┬───────────────┘                          │
   │          │ MMIO/PIO访问                             │
   │          ▼                                           │
   │ ════════════════════════════════════════════════     │
   │          │ VM Exit                                   │
   │          ▼                                           │
   │ ┌────────────────────────┐                          │
   │ │ QEMU设备模型           │                          │
   │ │ • 模拟寄存器           │                          │
   │ │ • 模拟DMA              │                          │
   │ │ • 转发给TAP设备        │                          │
   │ └────────┬───────────────┘                          │
   │          │                                           │
   │          ▼                                           │
   │ ┌────────────────────────┐                          │
   │ │ Host网卡               │                          │
   │ └────────────────────────┘                          │
   │                                                      │
   │ 缺点: 每次I/O都VM Exit,性能差                        │
   └──────────────────────────────────────────────────────┘

2. 半虚拟化(Para-virtualization - VirtIO):
   ┌──────────────────────────────────────────────────────┐
   │ Guest OS                                             │
   │ ┌────────────────────────┐                          │
   │ │ VirtIO驱动(前端)       │                          │
   │ │ • 知道自己被虚拟化     │                          │
   │ │ • 使用高效协议         │                          │
   │ └────────┬───────────────┘                          │
   │          │ VirtQueue                                │
   │          │ (共享内存环形队列)                        │
   │          ▼                                           │
   │ ┌────────────────────────┐                          │
   │ │ VirtIO后端(QEMU)       │                          │
   │ │ • 批量处理I/O请求      │                          │
   │ │ • 减少VM Exit          │                          │
   │ └────────┬───────────────┘                          │
   │          │                                           │
   │          ▼                                           │
   │ ┌────────────────────────┐                          │
   │ │ Host设备               │                          │
   │ └────────────────────────┘                          │
   │                                                      │
   │ VirtQueue结构:                                       │
   │ ┌──────────────────────────────────────────────┐    │
   │ │ Descriptor Table (描述I/O请求)                │    │
   │ │ ┌────┬────┬────┬────┐                        │    │
   │ │ │ D0 │ D1 │ D2 │ D3 │                        │    │
   │ │ └────┴────┴────┴────┘                        │    │
   │ │                                              │    │
   │ │ Available Ring (Guest提交请求)               │    │
   │ │ ┌───────────────────┐                        │    │
   │ │ │ idx: 2            │                        │    │
   │ │ │ ring: [0, 1, ...]│                        │    │
   │ │ └───────────────────┘                        │    │
   │ │                                              │    │
   │ │ Used Ring (Host返回结果)                     │    │
   │ │ ┌───────────────────┐                        │    │
   │ │ │ idx: 1            │                        │    │
   │ │ │ ring: [0, ...]    │                        │    │
   │ │ └───────────────────┘                        │    │
   │ └──────────────────────────────────────────────┘    │
   │                                                      │
   │ 性能提升: 2-3倍                                      │
   └──────────────────────────────────────────────────────┘

3. 直通(Device Passthrough - SR-IOV):
   ┌──────────────────────────────────────────────────────┐
   │ Guest OS1                Guest OS2                   │
   │ ┌──────────┐            ┌──────────┐                │
   │ │ VF驱动   │            │ VF驱动   │                │
   │ └────┬─────┘            └────┬─────┘                │
   │      │ 直接访问               │ 直接访问              │
   │ ═════▼══════════════════════▼═════════════════       │
   │                                                      │
   │ 物理网卡(支持SR-IOV)                                 │
   │ ┌────────────────────────────────────────────────┐  │
   │ │ PF (Physical Function)                         │  │
   │ │ ┌────────┐                                     │  │
   │ │ │ 管理接口│                                     │  │
   │ │ └────────┘                                     │  │
   │ │                                                │  │
   │ │ VF (Virtual Function)                          │  │
   │ │ ┌─────┐  ┌─────┐  ┌─────┐  ┌─────┐            │  │
   │ │ │ VF0 │  │ VF1 │  │ VF2 │  │ VF3 │            │  │
   │ │ └──┬──┘  └──┬──┘  └──┬──┘  └──┬──┘            │  │
   │ │    └────────┴────────┴────────┘               │  │
   │ │           (独立的DMA/中断)                      │  │
   │ └────────────────────────────────────────────────┘  │
   │                                                      │
   │ 优点:                                                │
   │ • 接近原生性能(95%+)                                 │
   │ • 无VM Exit开销                                      │
   │ • 硬件级隔离                                         │
   │                                                      │
   │ 缺点:                                                │
   │ • 需要硬件支持                                       │
   │ • VF数量有限                                         │
   │ • 迁移困难                                           │
   └──────────────────────────────────────────────────────┘

3. 容器技术

3.1 Namespace隔离

┌─────────────────────────────────────────────────────────────┐
│              Linux Namespace - 6种隔离                        │
└─────────────────────────────────────────────────────────────┘

1. PID Namespace (进程隔离)
   ┌─────────────────────────────────────────────────────┐
   │ Host:                Container:                      │
   │ ┌──────────┐        ┌──────────┐                    │
   │ │ PID 1    │        │ PID 1    │ (容器内init)       │
   │ │ systemd  │        │ /bin/sh  │                    │
   │ ├──────────┤        ├──────────┤                    │
   │ │ PID 1234 │        │ PID 2    │                    │
   │ │ sshd     │        │ nginx    │                    │
   │ ├──────────┤        └──────────┘                    │
   │ │ PID 5678 │←─映射─▶ 容器看不到Host进程              │
   │ │ dockerd  │                                         │
   │ └──────────┘                                         │
   │                                                     │
   │ 实现: /proc/sys/kernel/ns/pid                       │
   └─────────────────────────────────────────────────────┘

2. Network Namespace (网络隔离)
   ┌─────────────────────────────────────────────────────┐
   │ Host网络栈          Container网络栈                  │
   │ ┌──────────┐        ┌──────────┐                    │
   │ │ eth0     │        │ eth0     │ (veth pair)        │
   │ │ 192.168. │        │ 172.17.  │                    │
   │ │ 1.100    │        │ 0.2      │                    │
   │ ├──────────┤        ├──────────┤                    │
   │ │ 路由表   │        │ 路由表   │ (独立)             │
   │ ├──────────┤        ├──────────┤                    │
   │ │ iptables │        │ iptables │ (独立)             │
   │ └──────────┘        └──────────┘                    │
   │      │                    │                          │
   │      └────bridge(docker0)─┘                         │
   └─────────────────────────────────────────────────────┘

3. Mount Namespace (文件系统隔离)
   ┌─────────────────────────────────────────────────────┐
   │ Host:                Container:                      │
   │ /                    /                              │
   │ ├── bin              ├── bin                        │
   │ ├── etc              ├── etc   (独立的)             │
   │ ├── var              ├── var                        │
   │ └── home             └── home                       │
   │                                                     │
   │ 容器看到的是chroot后的根文件系统                     │
   └─────────────────────────────────────────────────────┘

4. UTS Namespace (主机名隔离)
   ┌─────────────────────────────────────────────────────┐
   │ Host: hostname = myhost                             │
   │ Container: hostname = container123                  │
   │                                                     │
   │ 独立的hostname和domainname                          │
   └─────────────────────────────────────────────────────┘

5. IPC Namespace (进程间通信隔离)
   ┌─────────────────────────────────────────────────────┐
   │ 隔离:                                                │
   │ • 消息队列 (msgqueue)                               │
   │ • 信号量 (semaphore)                                │
   │ • 共享内存 (shared memory)                          │
   │                                                     │
   │ 容器内进程无法访问Host的IPC对象                      │
   └─────────────────────────────────────────────────────┘

6. User Namespace (用户隔离)
   ┌─────────────────────────────────────────────────────┐
   │ Host UID 1000  ←映射→  Container UID 0 (root)       │
   │                                                     │
   │ 容器内root权限,但在Host上是普通用户                  │
   │ 增强安全性                                           │
   └─────────────────────────────────────────────────────┘

创建Namespace:
┌────────────────────────────────────────────────┐
│ /* C语言示例 */                                 │
│ #include <sched.h>                              │
│ #include <unistd.h>                             │
│                                                 │
│ int child_func(void *arg) {                     │
│     /* 在新namespace中运行 */                   │
│     execl("/bin/bash", "bash", NULL);           │
│     return 0;                                   │
│ }                                               │
│                                                 │
│ int main() {                                    │
│     char stack[4096];                           │
│                                                 │
│     clone(child_func,                           │
│           stack + sizeof(stack),                │
│           CLONE_NEWPID |  /* PID namespace */   │
│           CLONE_NEWNET |  /* Network ns */      │
│           CLONE_NEWNS  |  /* Mount ns */        │
│           CLONE_NEWUTS |  /* UTS ns */          │
│           CLONE_NEWIPC |  /* IPC ns */          │
│           CLONE_NEWUSER,  /* User ns */         │
│           NULL);                                │
│                                                 │
│     wait(NULL);                                 │
│     return 0;                                   │
│ }                                               │
└────────────────────────────────────────────────┘

3.2 Cgroup资源限制

┌─────────────────────────────────────────────────────────────┐
│              Cgroup (Control Groups) - 资源限制              │
└─────────────────────────────────────────────────────────────┘

Cgroup层级结构:
┌─────────────────────────────────────────────────────────────┐
│ /sys/fs/cgroup/                                             │
│ ├── cpu (CPU子系统)                                         │
│ │   ├── docker/                                            │
│ │   │   ├── container1/                                    │
│ │   │   │   ├── cpu.shares (相对权重)                      │
│ │   │   │   ├── cpu.cfs_quota_us (配额)                    │
│ │   │   │   └── cpu.cfs_period_us (周期)                   │
│ │   │   └── container2/                                    │
│ │   └── system.slice/                                      │
│ │                                                           │
│ ├── memory (内存子系统)                                     │
│ │   ├── docker/                                            │
│ │   │   ├── container1/                                    │
│ │   │   │   ├── memory.limit_in_bytes (上限)               │
│ │   │   │   ├── memory.usage_in_bytes (当前用量)           │
│ │   │   │   └── memory.oom_control (OOM控制)               │
│ │   │   └── container2/                                    │
│ │                                                           │
│ ├── blkio (块设备I/O)                                       │
│ │   ├── docker/                                            │
│ │   │   ├── container1/                                    │
│ │   │   │   ├── blkio.throttle.read_bps_device (读带宽)   │
│ │   │   │   └── blkio.throttle.write_bps_device (写带宽)  │
│ │                                                           │
│ ├── pids (进程数限制)                                       │
│ │   └── docker/container1/pids.max                         │
│ │                                                           │
│ └── devices (设备访问控制)                                  │
│     └── docker/container1/devices.list                      │
└─────────────────────────────────────────────────────────────┘

Cgroup子系统详解:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ 1. CPU子系统                                                │
│    ┌─────────────────────────────────────────────────┐     │
│    │ cpu.shares (权重)                                │     │
│    │ • 相对值,默认1024                                │     │
│    │ • Container A: 1024, Container B: 512           │     │
│    │ • 在CPU竞争时,A获得2/3,B获得1/3                  │     │
│    │                                                 │     │
│    │ cpu.cfs_quota_us / cpu.cfs_period_us (绝对限制) │     │
│    │ • quota=50000, period=100000                    │     │
│    │ • 50ms/100ms = 50% CPU                          │     │
│    │ • 等价于0.5个核                                  │     │
│    │                                                 │     │
│    │ cpuset.cpus (CPU亲和性)                          │     │
│    │ • 指定在哪些CPU上运行                            │     │
│    │ • 例: "0-3" 只能在CPU0-3上运行                  │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 2. Memory子系统                                             │
│    ┌─────────────────────────────────────────────────┐     │
│    │ memory.limit_in_bytes                            │     │
│    │ • 内存硬限制                                     │     │
│    │ • 超过限制触发OOM Killer                         │     │
│    │ • 例: 512MB = 536870912 bytes                   │     │
│    │                                                 │     │
│    │ memory.soft_limit_in_bytes                       │     │
│    │ • 内存软限制                                     │     │
│    │ • 内存压力大时尝试回收                           │     │
│    │                                                 │     │
│    │ memory.swappiness                                │     │
│    │ • 控制swap倾向(0-100)                            │     │
│    │ • 0: 尽量不swap                                  │     │
│    │ • 100: 积极swap                                  │     │
│    │                                                 │     │
│    │ memory.oom_control                               │     │
│    │ • 0: OOM时杀进程                                 │     │
│    │ • 1: OOM时暂停容器                               │     │
│    └─────────────────────────────────────────────────┘     │
│                                                             │
│ 3. BlkIO子系统                                              │
│    ┌─────────────────────────────────────────────────┐     │
│    │ blkio.weight (相对权重)                          │     │
│    │ • 范围10-1000,默认500                            │     │
│    │                                                 │     │
│    │ blkio.throttle.read_bps_device                   │     │
│    │ • 绝对读带宽限制                                 │     │
│    │ • 格式: "8:0 10485760" (10MB/s)                 │     │
│    │                                                 │     │
│    │ blkio.throttle.read_iops_device                  │     │
│    │ • 读IOPS限制                                     │     │
│    │ • 格式: "8:0 1000" (1000 IOPS)                  │     │
│    └─────────────────────────────────────────────────┘     │
└─────────────────────────────────────────────────────────────┘

实战示例:
bash
#!/bin/bash
# Cgroup资源限制示例

# 1. 创建cgroup
CGROUP_NAME="mycontainer"
CGROUP_PATH="/sys/fs/cgroup"

# CPU限制: 50%
mkdir -p $CGROUP_PATH/cpu/$CGROUP_NAME
echo 50000 > $CGROUP_PATH/cpu/$CGROUP_NAME/cpu.cfs_quota_us
echo 100000 > $CGROUP_PATH/cpu/$CGROUP_NAME/cpu.cfs_period_us

# 内存限制: 512MB
mkdir -p $CGROUP_PATH/memory/$CGROUP_NAME
echo 536870912 > $CGROUP_PATH/memory/$CGROUP_NAME/memory.limit_in_bytes

# BlkIO限制: 读10MB/s
mkdir -p $CGROUP_PATH/blkio/$CGROUP_NAME
echo "8:0 10485760" > $CGROUP_PATH/blkio/$CGROUP_NAME/blkio.throttle.read_bps_device

# 2. 将进程加入cgroup
PID=$$
echo $PID > $CGROUP_PATH/cpu/$CGROUP_NAME/cgroup.procs
echo $PID > $CGROUP_PATH/memory/$CGROUP_NAME/cgroup.procs
echo $PID > $CGROUP_PATH/blkio/$CGROUP_NAME/cgroup.procs

# 3. 查看资源使用
cat $CGROUP_PATH/cpu/$CGROUP_NAME/cpuacct.usage
cat $CGROUP_PATH/memory/$CGROUP_NAME/memory.usage_in_bytes
python
#!/usr/bin/env python3
"""
使用Docker API设置资源限制
"""
import docker

client = docker.from_env()

# 创建容器并设置资源限制
container = client.containers.run(
    "nginx:latest",
    detach=True,
    name="limited_nginx",

    # CPU限制
    cpu_period=100000,      # 100ms
    cpu_quota=50000,        # 50ms (50% CPU)
    cpuset_cpus="0-1",      # 只用CPU0和CPU1

    # 内存限制
    mem_limit="512m",       # 512MB硬限制
    mem_reservation="256m", # 256MB软限制
    memswap_limit="1g",     # swap + memory = 1GB

    # 块I/O限制
    blkio_weight=500,       # 权重
    device_read_bps=[
        {"Path": "/dev/sda", "Rate": 10485760}  # 10MB/s
    ],
    device_write_iops=[
        {"Path": "/dev/sda", "Rate": 1000}      # 1000 IOPS
    ],

    # 进程数限制
    pids_limit=100
)

print(f"Container created: {container.id}")

# 查看资源使用
stats = container.stats(stream=False)
print(f"CPU usage: {stats['cpu_stats']['cpu_usage']['total_usage']}")
print(f"Memory usage: {stats['memory_stats']['usage']}")

4. 容器网络

4.1 Docker网络模式

┌─────────────────────────────────────────────────────────────┐
│              Docker网络模式                                  │
└─────────────────────────────────────────────────────────────┘

1. Bridge模式(默认)
   ┌──────────────────────────────────────────────────────┐
   │ Host                                                 │
   │                                                      │
   │ ┌──────────┐          ┌──────────┐                  │
   │ │Container1│          │Container2│                  │
   │ │ eth0     │          │ eth0     │                  │
   │ │172.17.0.2│          │172.17.0.3│                  │
   │ └────┬─────┘          └────┬─────┘                  │
   │      │ veth pair           │ veth pair              │
   │      │                     │                        │
   │ ┌────▼─────────────────────▼─────┐                  │
   │ │ docker0 bridge                 │                  │
   │ │ 172.17.0.1                     │                  │
   │ └────────────┬───────────────────┘                  │
   │              │ NAT                                   │
   │              │                                       │
   │ ┌────────────▼───────────────────┐                  │
   │ │ eth0 (Host网卡)                │                  │
   │ │ 192.168.1.100                  │                  │
   │ └────────────────────────────────┘                  │
   │              │                                       │
   └──────────────┼───────────────────────────────────────┘

              Internet

   特点:
   • 容器有独立IP(docker0网段)
   • 通过NAT访问外网
   • 需要端口映射(-p 8080:80)

2. Host模式
   ┌──────────────────────────────────────────────────────┐
   │ Host                                                 │
   │                                                      │
   │ ┌──────────────────────────────────────────────┐    │
   │ │ Container (共享Host网络栈)                    │    │
   │ │ • 无独立IP                                    │    │
   │ │ • 直接使用Host端口                             │    │
   │ │ • 性能最好                                    │    │
   │ └──────────────────────────────────────────────┘    │
   │                       │                              │
   │ ┌─────────────────────▼──────────────────────────┐  │
   │ │ Host网络栈                                     │  │
   │ │ eth0: 192.168.1.100                            │  │
   │ └────────────────────────────────────────────────┘  │
   └──────────────────────────────────────────────────────┘

   使用: docker run --network=host nginx

3. Container模式
   ┌──────────────────────────────────────────────────────┐
   │ Container1            Container2                     │
   │ ┌──────────┐         (共享Container1网络)            │
   │ │ eth0     │         ┌──────────┐                    │
   │ │172.17.0.2│◀────────│ 共享网络  │                    │
   │ └──────────┘         └──────────┘                    │
   │                                                      │
   │ 使用场景: Kubernetes Pod (多容器共享网络)            │
   └──────────────────────────────────────────────────────┘

   使用: docker run --network=container:container1 app2

4. None模式
   ┌──────────────────────────────────────────────────────┐
   │ Container                                            │
   │ ┌────────────────────────────┐                       │
   │ │ 无网络配置                  │                       │
   │ │ 只有lo接口                  │                       │
   │ │ 用户自定义网络配置          │                       │
   │ └────────────────────────────┘                       │
   └──────────────────────────────────────────────────────┘

   使用: docker run --network=none myapp

4.2 Overlay网络

┌─────────────────────────────────────────────────────────────┐
│              Overlay网络(跨主机通信)                          │
└─────────────────────────────────────────────────────────────┘

VXLAN隧道:
┌─────────────────────────────────────────────────────────────┐
│ Host1 (192.168.1.10)          Host2 (192.168.1.20)         │
│                                                             │
│ Container A                   Container B                   │
│ ┌──────────┐                  ┌──────────┐                 │
│ │ 10.0.0.2 │                  │ 10.0.0.3 │                 │
│ └────┬─────┘                  └────┬─────┘                 │
│      │                             │                        │
│ ┌────▼────────┐              ┌────▼────────┐              │
│ │ veth pair   │              │ veth pair   │              │
│ └────┬────────┘              └────┬────────┘              │
│      │                             │                        │
│ ┌────▼────────┐              ┌────▼────────┐              │
│ │ br0 (bridge)│              │ br0 (bridge)│              │
│ └────┬────────┘              └────┬────────┘              │
│      │                             │                        │
│ ┌────▼────────┐              ┌────▼────────┐              │
│ │ vxlan0      │              │ vxlan0      │              │
│ │ VNI: 100    │              │ VNI: 100    │              │
│ └────┬────────┘              └────┬────────┘              │
│      │ VXLAN封装                   │ VXLAN封装             │
│      │                             │                        │
│ ┌────▼────────┐              ┌────▼────────┐              │
│ │ eth0        │              │ eth0        │              │
│ │192.168.1.10 │◀──UDP 4789──▶│192.168.1.20 │              │
│ └─────────────┘              └─────────────┘              │
└─────────────────────────────────────────────────────────────┘

VXLAN报文格式:
┌─────────────────────────────────────────────────────────────┐
│ Outer Ethernet Header                                       │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ Dst MAC | Src MAC | EtherType                        │    │
│ └─────────────────────────────────────────────────────┘    │
│                                                             │
│ Outer IP Header                                             │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ Src IP: 192.168.1.10 | Dst IP: 192.168.1.20         │    │
│ └─────────────────────────────────────────────────────┘    │
│                                                             │
│ Outer UDP Header                                            │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ Src Port: random | Dst Port: 4789                   │    │
│ └─────────────────────────────────────────────────────┘    │
│                                                             │
│ VXLAN Header                                                │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ VNI: 100 (24 bits)                                  │    │
│ └─────────────────────────────────────────────────────┘    │
│                                                             │
│ Inner Ethernet Header                                       │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ 容器A MAC | 容器B MAC                                │    │
│ └─────────────────────────────────────────────────────┘    │
│                                                             │
│ Inner IP Packet                                             │
│ ┌─────────────────────────────────────────────────────┐    │
│ │ Src: 10.0.0.2 | Dst: 10.0.0.3                       │    │
│ │ Payload                                             │    │
│ └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

5. 虚拟化性能优化

bash
#!/bin/bash
# 虚拟化性能调优脚本

echo "=== KVM性能优化 ==="

# 1. CPU优化
echo "1. CPU亲和性绑定"
virsh vcpupin myvm 0 0  # VCPU0绑定到物理CPU0
virsh vcpupin myvm 1 1  # VCPU1绑定到物理CPU1

# 2. 大页内存
echo "2. 启用大页"
echo 1024 > /proc/sys/vm/nr_hugepages
echo "vm.nr_hugepages = 1024" >> /etc/sysctl.conf

# 3. VirtIO驱动
echo "3. 确保使用VirtIO"
virsh dumpxml myvm | grep -i virtio

# 4. 多队列网卡
echo "4. 启用多队列VirtIO-net"
# 在VM配置中: <driver name='vhost' queues='4'/>

# 5. vhost-net内核加速
echo "5. 加载vhost_net模块"
modprobe vhost_net
lsmod | grep vhost

# 6. CPU cache tune
echo "6. 配置CPU cache-passthrough"
# <cpu mode='host-passthrough' check='none'>

echo ""
echo "=== 容器性能优化 ==="

# 1. 使用Overlay2存储驱动
echo "1. 检查存储驱动"
docker info | grep "Storage Driver"

# 2. 禁用swap
echo "2. 禁用swap"
swapoff -a

# 3. 调整vm参数
echo "3. 优化内存管理"
sysctl -w vm.swappiness=0
sysctl -w vm.overcommit_memory=1

# 4. 使用host网络模式(需要时)
echo "4. 高性能网络建议使用host模式"

# 5. cgroup v2
echo "5. 检查cgroup版本"
stat -fc %T /sys/fs/cgroup/

6. 总结

本教程深入讲解了虚拟化技术:

核心知识点:

  1. 虚拟化类型: 全虚拟化、半虚拟化、容器
  2. KVM架构: CPU虚拟化、内存虚拟化、I/O虚拟化
  3. Namespace: 6种隔离机制
  4. Cgroup: CPU/内存/IO资源限制
  5. 容器网络: Bridge、Host、Overlay

实战技能:

  • 搭建KVM虚拟机
  • 创建和管理Docker容器
  • 配置cgroup资源限制
  • 优化虚拟化性能

最佳实践:

  1. VM使用VirtIO提升性能
  2. 启用大页内存
  3. CPU亲和性绑定
  4. 容器使用Overlay2存储驱动
  5. 生产环境禁用swap
  6. 合理设置资源限制

掌握虚拟化是理解云计算和容器化的基础!

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布