{T}

容器化技术与虚拟机对比

0. 引言

部署应用的演进史,本质上是一部"环境隔离"与"资源利用"的博弈史:物理机时代资源浪费严重,虚拟机时代隔离彻底但开销巨大,容器时代则在两者之间找到了平衡点。容器不是更轻的虚拟机,而是基于操作系统内核特性的进程级隔离方案——理解这一本质区别,是后续学习 Dockerfile、镜像分层与编排的基础。

本章将从部署形态的演进出发,对比容器与虚拟机的核心差异,拆解容器的三大底层支柱(Namespace、Cgroups、OverlayFS),并梳理 Docker 运行时从 Dockershim 走向 CRI 的演进脉络与选型建议。


1. 部署形态演进:从物理机到容器

1.1 四个阶段的递进

阶段隔离粒度资源密度启动速度典型问题
物理机无隔离单应用独占分钟级资源浪费、环境冲突
虚拟机虚拟硬件单虚机多应用分钟级占用大、启动慢
容器进程级单机数百容器秒级隔离弱于虚拟机
Serverless函数级极致弹性毫秒级冷启动与厂商绑定

虚拟机通过 Hypervisor 虚拟化硬件,每个虚机内部运行完整操作系统(Guest OS),占据数 GB 内存;容器则直接共享宿主机内核,只隔离进程的视图,开销以 MB 计。

1.2 虚拟机时代的两大痛点

  • 资源空转:虚机内操作系统、系统服务、依赖库层层冗余,CPU 与内存利用率低;
  • 交付鸿沟:同一应用在开发、测试、生产环境依赖库版本不一致,出现"我机器上能跑"的经典问题。

容器的价值恰恰在于:把应用连同其运行环境一起打包交付,从根源上消除环境差异。


2. 容器与虚拟机的核心差异

2.1 架构对比

图表渲染中…

虚拟机多一层 Hypervisor 与 Guest OS,容器则直接调度宿主机内核资源。

2.2 关键维度对比表

维度虚拟机容器
隔离层级硬件级(完整 Guest OS)进程级(Namespace/Cgroups)
内核独立内核共享宿主机内核
镜像大小GB 级(含 OS)MB 级(仅应用+依赖)
启动时间分钟级秒级
单机密度个位数数百个
资源开销高(虚机常驻)低(进程级)
安全边界强(硬件隔离)弱(内核共享)
迁移性虚机镜像,跨平台一般镜像随处运行,生态统一

2.3 性能差异

  • CPU/内存:容器无虚拟化损耗,接近原生性能;虚机有 Hypervisor 与设备模拟开销;
  • 磁盘 IO:旧式虚拟化磁盘 IO 损耗明显,容器共享宿主文件系统,配合 OverlayFS 分层后 IO 表现更好;
  • 网络:虚机走虚拟网桥/vNIC,容器走 veth 对 + 网桥,延迟均低,但容器方案更轻量。

一句话总结:虚拟机隔离的是"机器",容器隔离的是"进程视图";前者防的是内核级风险,后者追求的是密度与速度。


3. 容器的三大底层支柱

3.1 Namespace:看到的隔离

Namespace 让容器内的进程"看不见"宿主机的进程、网络、文件系统等资源视图:

Namespace隔离内容作用
PID进程编号容器内进程从 1 开始,看不到宿主进程
Mount挂载点容器拥有独立的文件系统视图
Network网络栈独立 IP、端口、路由
UTS主机名独立 hostname
IPC进程间通信独立消息队列/共享内存
User用户 ID容器内 root 与宿主 root 解耦

3.2 Cgroups:资源的限制

Cgroups(Control Groups)负责限制与统计资源用量:容器可设置 CPU 份额、内存上限、IO 带宽,防止单个容器耗尽宿主机资源拖垮其他进程。

图表渲染中…

3.3 OverlayFS:文件的分层

镜像由多层只读层叠加而成,容器启动时在最上层增加一个可写层,写操作走 Copy-on-Write(写时复制)机制:

  • 多个容器共享同一份镜像只读层,磁盘占用极小
  • 容器删除后仅丢弃可写层,镜像本身不受影响;
  • 分层结构让镜像构建可以增量缓存,是 Dockerfile 缓存机制的基础。

4. 容器运行时演进:从 Dockershim 到 CRI

4.1 演进时间线

Kubernetes 早期直接调用 Docker 的 Dockershim 适配层;随着容器运行时生态多样化,K8s 定义了标准接口 CRI(Container Runtime Interface)

图表渲染中…

4.2 演进的关键节点

时间事件影响
2016Kubernetes 1.5 引入 CRI运行时接口标准化
2017Docker 拆出 containerd 捐给 CNCF轻量运行时独立发展
2020K8s 1.20 宣布弃用 Dockershim生态转向 containerd/CRI-O
2021K8s 1.24 移除 DockershimDocker 不再直接作为 K8s 运行时

对普通开发者而言,Docker CLI 与 Docker 引擎依旧可用,变化只发生在 K8s 集群内部如何与容器运行时交互的层面。

4.3 运行时选型建议

  • 单机开发/CI:Docker Engine 最成熟,生态工具链最全;
  • K8s 生产集群:containerd 为默认首选,轻量且稳定;
  • 安全敏感场景:可叠加 gVisor、Kata Containers 等沙箱运行时增强隔离。

5. 选型建议:容器还是虚拟机?

场景推荐理由
Web 应用、微服务、CI/CD容器交付一致、密度高、启动快
多租户强隔离、异质 OS 需求虚拟机内核级隔离更安全
混合部署两者共存容器跑应用、虚机做边界
本地开发环境容器一条命令拉起整套依赖

现实生产环境往往是"虚机兜底 + 容器承载"的组合:虚机提供租户边界,容器承载业务负载。


6. 小结

  • 容器是进程级隔离:基于 Namespace(视图)、Cgroups(资源)、OverlayFS(文件)三大机制,并非轻量虚拟机;
  • 交付一致性:镜像打包应用与运行环境,消除环境差异,启动秒级、密度数百;
  • 运行时标准化:Docker 从 K8s 唯一运行时退位为 CRI 生态中的工具链一环,containerd 成为生产默认;
  • 选型理性化:隔离需求高用虚拟机,密度与交付效率优先用容器,两者可组合使用。

下一章讲解 Docker 的安装步骤与三大核心概念——镜像、容器、仓库。