【虚拟机】 从 CPU 指令到虚拟机隔离:虚拟机就是一个“模拟了完整硬件的普通进程”

CodeStats | 资深底层技术爱好者与实战派架构师,WWAIC(全周 AI 编程)范式创始人

专注计算机体系结构、操作系统内核、Java 虚拟机实现原理与自研框架落地。本文手撕虚拟机底层:不讲空话,只从 CPU 指令 → 操作系统 → 进程 → 硬件虚拟化这条铁链,彻底讲透虚拟机是什么、凭什么能隔离、和 Docker 容器到底有什么区别。

参考原文(CSDN)从 CPU 指令到容器隔离:Docker 就是一个打了标签的普通进程


📖 本文你能获得什么
程序运行的本质:CPU 取指执行 + 操作系统调度 = 进程的“虚拟 CPU”假象

CPU 权限分级:彻底搞懂 ring 0 / ring 3、内核态/用户态、系统调用

虚拟机执行原理:Guest OS 如何“骗过”CPU —— 从 Trap & Emulate 到 Intel VT-x 硬件辅助虚拟化

设备模拟真相:硬盘、网卡全是 QEMU 用软件“演”出来的(镜像文件、TAP 设备、virtio)

隔离本质对比:虚拟机隔离“硬件”(独立内核)vs Docker 隔离“名字空间”(共享内核)

技术选型框架:什么时候选虚拟机,什么时候选 Docker,一张表+一句话秒懂

适合谁看:资深底层技术爱好者、实战派架构师、云原生开发者,以及任何想彻底搞懂“虚拟机到底是个什么东西”的人。

目录


核心观点一句话

虚拟机 = 硬件模拟(CPU/内存/硬盘/网卡)+ 独立 Guest OS + 完整隔离边界

它不共享宿主机内核,它是宿主机上一个被赋予了“完整硬件视图”的普通进程。


提问一:程序运行的本质是什么?

程序运行的本质 = CPU 从内存中逐条取指令、执行指令的过程。

一个程序本身只是存放在磁盘上的一组指令和静态数据,没有生命周期。是操作系统把程序代码加载到内存中,生成相应的数据结构(进程控制块、内存映射表等),然后从代码的起始位置读取指令交给 CPU 顺序执行。

CPU 本质上就是一个“去内存中根据地址取指令,然后执行指令的硬件”。指令执行过程中可能遇到跳转指令(循环、条件判断最终都被编译为跳转指令),CPU 的下一条指令就不再是内存中顺序的下一条。

从 CPU → 操作系统 → 应用程序的完整链条是:

层级职责
CPU取指、译码、执行,只认机器指令
操作系统加载程序、调度进程、管理内存、提供系统调用接口
应用程序在操作系统之上运行,通过系统调用请求内核服务

操作系统提供了“存在多个虚拟 CPU”的假象,让每个进程都以为自己独占整台机器。每个进程被分配一个虚拟地址空间(32 位 Linux 为 4GB),通过 MMU 映射到真实物理内存。


提问二:CPU 权限管控和内核态、用户态是什么关系?

CPU 权限管控 = 通过指令集特权级划分,将操作系统和用户程序运行在不同权限级别上。

Intel x86 CPU 用 ring 0(内核态)ring 3(用户态) 来划分权限:

运行态特权级能力
内核态 (Ring 0)最高可执行任何 CPU 指令,直接操作硬件,访问所有内存地址
用户态 (Ring 3)最低只能执行受限指令,访问受限资源,不能直接访问硬件

内核态和用户态的关系:

有一类指令叫特权指令(如读写硬盘、修改内存映射表),一旦用错,整个操作系统会直接宕机。因此,普通程序要访问硬件,必须通过系统调用(System Call)陷入内核,让内核代劳。

当用户态程序发起系统调用时,CPU 会从 ring 3 切换到 ring 0,跳转到内核代码位置执行,完成后再从 ring 0 返回 ring 3。

这一层奠定了“权限分级控制”的基础。


提问三:虚拟机是如何通过用户态进程执行内核态权限指令的?

核心答案:通过「Trap & Emulate」(陷阱+模拟)或「硬件辅助虚拟化」技术。

虚拟机(如 KVM + QEMU)本身是宿主机上的一个用户态进程,但 Guest OS 内部有自己的内核态和用户态。问题在于:Guest OS 认为自己运行在 ring 0,但实际它在宿主机上只是一个用户态进程,没有真正的 ring 0 权限。

解决方案有两种:

1. 纯软件模拟(Trap & Emulate)

当 Guest OS 执行一条特权指令时,由于它实际运行在用户态,CPU 会触发一个陷阱(Trap),陷入宿主机内核。宿主机内核(或 VMM)捕获这个陷阱后,模拟执行这条指令,然后把结果返回给 Guest OS。

这种方式叫“陷阱-模拟”——敏感指令被捕获,由软件模拟执行。

缺点是性能差:每条特权指令都要触发陷阱、陷入内核、模拟执行、返回。

2. 硬件辅助虚拟化(Intel VT-x / AMD-V)

现代 CPU 提供了专门的虚拟化指令集(Intel VT-x、AMD-V)。KVM 利用这些硬件能力,让 Guest OS 的指令直接在 CPU 上运行,不需要软件模拟。

工作流程如下:

  1. 用户态的 QEMU 通过 ioctl 系统调用进入 KVM 内核模块
  2. KVM 为虚拟机创建虚拟 CPU(vCPU)虚拟内存
  3. 执行 VMLAUNCH 指令,CPU 进入客户模式(Guest Mode)
  4. Guest OS 在客户模式下直接运行,大部分指令由硬件直接执行
  5. 遇到敏感操作时,CPU 自动退出客户模式,由 KVM 处理

一句话总结:虚拟机不是“在用户态执行内核指令”,而是通过硬件虚拟化扩展,让 Guest OS 运行在一个特殊的“客户模式”下,敏感指令由 VMM 捕获并模拟。


提问四:虚拟机是如何解决硬盘和网卡模拟的?

核心答案:通过「设备模拟」——在虚拟机监控器(VMM)中用软件模拟硬件设备的行为。

虚拟机需要让 Guest OS 认为自己有真实的硬盘和网卡。但实际上,这些都是软件模拟出来的。

硬盘模拟

在宿主机上创建一个镜像文件(如 .qcow2.raw),作为虚拟磁盘。当 Guest OS 发起磁盘 I/O 请求时:

  1. Guest OS 的驱动程序向“虚拟硬盘”发出读写指令
  2. 这些指令被 VMM(如 QEMU)捕获
  3. QEMU 将指令转换为对宿主机镜像文件的读写操作
  4. 结果返回给 Guest OS

网卡模拟

类似地,QEMU 模拟一个标准的网卡设备(如 Intel e1000)。Guest OS 看到的是一块真实的物理网卡,实际上所有网络数据包都由 QEMU 处理:

  1. Guest OS 发送数据包到“虚拟网卡”
  2. QEMU 捕获数据包
  3. QEMU 通过宿主机的网络栈(如 TAP 设备、网桥)将数据包发出
  4. 收到的数据包由 QEMU 注入到 Guest OS 的“虚拟网卡”

I/O 虚拟化的三种方式

方式原理性能
设备模拟(全虚拟化)纯软件模拟硬件设备最低
半虚拟化(virtio)Guest OS 知道自己被虚拟化,与 VMM 协作较高
设备直通(PCI Passthrough)直接将物理设备分配给虚拟机最高

一句话总结:硬盘和网卡的模拟,本质是 VMM 在宿主机上“假装”成硬件设备,拦截 Guest OS 的 I/O 请求并转换为对宿主机资源的操作。


提问五:虚拟机隔离的本质是什么?一句话总结

虚拟机隔离的本质 = 通过 VMM(虚拟机监控程序)在硬件层面模拟出多台独立的“物理机器”,每台虚拟机拥有独立的 CPU、内存、硬盘、网卡和操作系统内核,彼此之间完全不可见、不可访问。

一台虚拟机的崩溃(操作系统故障、应用程序崩溃、驱动程序故障)不会影响同一物理服务器上的其他虚拟机。每个虚拟机都像运行在独立的物理机器上一样。

虚拟机的隔离是硬件级别的强隔离,因为它模拟的是完整的硬件边界。


提问六:虚拟机和 Docker 区别对比及各场景一句话总结

对比表格

维度虚拟机(KVM)容器(Docker)
隔离边界硬件(模拟完整硬件)内核(系统调用接口)
独立内核每个虚拟机一个 Guest OS 内核无,共享宿主机内核
启动时间分钟级毫秒级
资源开销GB 级别MB/KB 级别
隔离级别强(硬件辅助虚拟化)中(内核 Namespace)
本质模拟硬件,跑操作系统隔离进程,跑应用

各场景一句话总结

场景一句话推荐
需要运行不同内核的操作系统(如在 Linux 上跑 Windows)选虚拟机,因为容器共享宿主机内核,无法运行不同内核的 OS
多租户环境、遗留应用迁移、强安全隔离要求选虚拟机,硬件级隔离更彻底
微服务架构、云原生应用、快速弹性伸缩选 Docker,轻量快速,资源利用率极高
快速开发、测试和部署,大规模应用分发选 Docker,秒级启动,镜像分层复用
传统 IT 环境中的服务器虚拟化项目选虚拟机,成熟稳定,隔离性好
混合部署(需要兼顾隔离和效率)两者结合:在虚拟机中运行多个 Docker 容器

本质升华:一台机器 vs 一个进程

纵观全文,从CPU指令到设备模拟,虚拟机和Docker给出了两种截然不同的“隔离”答卷:

  • 虚拟机(KVM)的隔离思想是“向下切割硬件”:它通过VMM在物理硬件层面模拟出独立的CPU、内存、硬盘和网卡,每一台虚拟机都拥有自己独立的操作系统内核。虚拟机本质是在硬件边界上筑墙——墙内系统崩溃(如内核Panic),墙外宿主机和其他虚拟机毫无感知。这是一种**“物理机器级”的强隔离**,重资产,但绝对彻底。

  • Docker容器的隔离思想是“向上圈定进程”:它不模拟任何硬件,而是利用Linux内核的命名空间(Namespace)操作系统层面给进程打上“视野标签”(独立的PID、网络、文件系统等),再用Cgroups划定资源使用上限。Docker本质是在操作系统边界上画圈——所有容器共享宿主机同一个内核,隔离的是“进程能看到什么、能用多少资源”,而非硬件本身。这是一种**“进程级”的轻量隔离**,快如闪电,但共享内核风险。

一句话记住它们

虚拟机隔离的是“硬件”,所以它能跑Windows也能跑Linux,不依赖宿主机内核,防的是“物理故障和内核崩溃”
Docker隔离的是“操作系统名字空间”,所以它只能跑与宿主机同内核的应用,防的是“进程干扰和文件冲突”

思想终极提炼

  • 虚拟机的核心思想“把一台物理主机,变成多台虚拟主机” —— 解决的是“硬件资源池化与多系统共存”问题。
  • Docker的核心思想“把一台物理主机上的进程,安排得明明白白” —— 解决的是“应用交付与环境依赖一致性”问题。

在技术选型的天平上:

  • 如果你担心内核级漏洞或需要运行异构OS,请把砝码压在虚拟机(硬件墙)上;
  • 如果你追求极致弹性微服务迭代资源利用率,请把砝码压在Docker(进程标签)上。

记住:虚拟机动的是“地基”(硬件),Docker改的是“门牌号”(命名空间)。地基隔开的是整栋楼,门牌号隔开的是同一栋楼里的不同房间。


最后:点赞 · 收藏 · 评论

如果这篇文章帮你彻底搞懂了虚拟机的底层原理,并理清了它与Docker的本质区别:

  • 👍 点赞 让更多同学看到这篇硬核推演
  • ⭐ 收藏 方便随时复习完整逻辑链
  • 💬 评论 留下疑问或补充

从 CPU 指令到硬件虚拟化,从硬件墙到命名空间标签——你已掌握云计算虚拟化技术的两大基石。


© 2026 CodeStats | 原创不易,转载注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeStats

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值