1. 概述

在现代软件部署与运维领域,直接在物理服务器上运行服务的情况已经非常少见。我们更倾向于在虚拟主机(无论是本地还是云上)或容器(如 Docker)之间做出选择。

这种对基础设施更高层次的抽象,要求我们掌握诸如 基础设施即代码(IaC) 和容器编排工具(如 Kubernetes)的使用。但即便不使用这些复杂工具,我们也能通过一些轻量级手段获得显著优势。

本文将探讨虚拟化与容器化的基本原理,比较它们的技术差异与适用场景,帮助你更好地进行技术选型。

2. 为什么要抽象化?

最基础的部署方式,是在物理服务器上安装操作系统(如 Linux 或 Windows),然后在其上运行应用和服务:

Basic Deployment

这种方式在很多小型企业的机房中仍然常见。

但从 2000 年代中期开始,数据中心和云环境逐步普及虚拟化技术。到了 2010 年代中后期,以 Docker 为代表的容器技术标准化并开始广泛应用。

推动这些技术持续发展的核心原因包括:

灵活性与可扩展性:可以轻松调整配置或复制到其他主机,按需扩展服务数量。

资源利用率高:无需长期保留闲置服务器,可根据需要动态分配计算与存储资源。

进程隔离:每个服务独立运行,互不干扰,避免因更新一个服务而影响其他服务。

配置与变更管理:支持虚拟机快照、逐步配置文档化,配合 Terraform、Ansible 等 IaC 工具,避免“临时性”配置导致的混乱。

3. 虚拟化基础

虚拟化是指通过软件运行一个虚拟机(VM),主机系统运行一个称为 hypervisor 的虚拟化管理程序,虚拟机在 hypervisor 中运行,其操作系统(称为“Guest OS”)通常无法感知自己并非运行在真实硬件上:

Virtualizied Deployment2

常见的虚拟化软件包括:

  • Linux 的 KVM
  • VMware Workstation / ESXi
  • XenServer
  • VirtualBox(免费,适合桌面使用)
  • DosBox(虽然是个游戏模拟器,但也能运行完整系统如 BeOS)
  • Microsoft 的 Hyper-V

这些工具可用于运行服务(如 Wiki + 数据库)、网络监控工具,也可以用于开发环境的隔离测试。

从 2000 年代中期开始,Intel 与 AMD 在 CPU 中加入了虚拟化扩展(Intel VT / AMD-V),这些功能已成为服务器标配,但在桌面环境中可能需要手动在 BIOS 中启用。

3.1 虚拟机能做什么?

使用虚拟机镜像代替直接在物理服务器上安装系统,带来了显著的可移植性优势。镜像标准化后,可以在不同主机之间迁移,甚至支持“热迁移”(Live Migration)。

AWS、GCP、Azure 等云平台本质上也是基于虚拟机实例构建的。我们无需手动安装 Ubuntu,只需指定资源和操作系统即可快速部署。

每个虚拟机都像一个完整的操作系统,具备独立的内核和运行环境。这意味着:

  • 可以运行不同的 Linux 发行版、Windows、BSD 等
  • 完全隔离,安全性高
  • 但体积大、启动慢、资源占用高

从用户角度看,虚拟机与物理机几乎无异。

4. 容器基础

容器(如 Docker)运行在完整的操作系统之上,由操作系统提供内核、文件系统、网络等基础服务:

Container Deployment

容器本身包含运行某个服务所需的所有内容:

  • 应用代码或二进制文件
  • 依赖库(如 Python、JRE)
  • 配置文件、环境变量、本地化设置等

这些内容都绑定到特定版本。你可以理解为一个“包锁定”机制,比如 package-lock.jsonrequirements.txt 所起的作用。

4.1 Docker 的角色

对很多人来说,Docker 就是容器的代名词。虽然也有其他容器引擎(如 Red Hat 的 Podman),但 Docker 的生态和社区仍是学习容器技术的最佳入口。

Docker 提供了一个庞大的镜像库,我们可以从中拉取镜像,构建和运行本地容器。

容器镜像是运行容器的模板。容器运行时加载镜像后生成容器实例。它基于主机的内核运行,仅封装应用及其依赖。

常见的基础镜像有:

  • alpine(轻量级)
  • ubuntu
  • centos

我们可以将 Java 应用与 Tomcat 一起打包进一个容器中,例如:

docker run -d -p 8080:8080 my-java-app

4.2 联合文件系统(Union/Overlay FS)

容器之所以体积小、启动快,关键在于其使用了联合文件系统

容器镜像由多个只读层组成,最底层为 base image,上层为应用和配置。运行时新增的修改只写入最上层的读写层。

这意味着:

✅ 多个容器共享同一个 base image,节省存储空间
✅ 启动速度快,因为无需复制整个文件系统

4.3 容器的部署与管理

容器非常适合在开发、测试、生产环境中保持一致性,避免“在我机器上能跑”的尴尬。

在生产环境中,我们通常会:

  • 拉取镜像
  • 自定义配置
  • 启动容器

即使部署在云实例上,也仍需大量运维工作。

云厂商也提供了容器托管服务,例如:

  • AWS Fargate:只需上传镜像并配置资源即可运行
  • Azure Container Instances
  • GCP Cloud Run

而 Kubernetes(简称 K8s)作为容器编排的事实标准,提供了高可用、自动恢复等能力,但同时也带来了复杂性。

虽然你可能目前还不需要 K8s,但提前将应用容器化,有助于未来快速扩展。

5. 总结

虚拟机与容器都解决了服务隔离和部署一致性的问题,但它们的实现方式和适用场景有所不同:

对比维度 虚拟机(VM) 容器(Container)
启动速度 慢(需启动完整操作系统) 快(共享主机内核)
存储占用 大(完整 OS + 应用) 小(仅应用 + 依赖)
隔离性 强(完全独立的 OS) 弱(共享内核)
管理复杂度 中等 高(尤其在集群环境下)
适用场景 长期运行、需要不同 OS、对隔离性要求高 快速迭代、微服务、CI/CD、轻量级部署

虚拟机更适合长期运行、需要不同操作系统支持或对隔离性要求高的场景
容器则更适合微服务、DevOps、快速迭代、资源敏感型部署

选择哪种方式,取决于你的具体业务需求、团队技术栈和运维能力。容器虽轻量,但并非万能;虚拟机虽重,但仍有其不可替代的价值。


原始标题:Docker and Containers vs. Virtual Machines