Docker 和虚拟机的区别
虚拟机
- 基础设施(Infrastructure)。它可以是你的个人电脑,数据中心的服务器,或者是云主机。
- 主操作系统(Host Operating System)。你的个人电脑之上,运行的可能是 MacOS,Windows 或者某个 Linux 发行版。
- 虚拟机管理系统(Hypervisor)。利用 Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。类型1的 Hypervisor 有支持 MacOS 的 HyperKit,支持 Windows 的 Hyper-V 以及支持 Linux 的 KVM。类型2的 Hypervisor 有 VirtualBox 和 VMWare。
- 操作系统(Guest Operating System)。假设你需要运行3个相互隔离的应用,则需要使用 Hypervisor 启动3个从操作系统,也就是3个虚拟机。这些虚拟机都非常大,也许有700MB,这就意味着它们将占用2.1GB的磁盘空间。更糟糕的是,它们还会消耗很多CPU和内存。
- 各种依赖。每一个从操作系统都需要安装许多依赖。如果你的的应用需要连接 PostgreSQL 的话,则需要安装 libpq-dev;如果你使用 Ruby 的话,应该需要安装 gems;如果使用其他编程语言,比如 Python 或者 Node.js,都会需要安装对应的依赖库。
Docker 容器
- 主操作系统(Host Operating System)。所有主流的 Linux 发行版都可以运行 Docker。对于 MacOS 和 Windows,也有一些办法"运行" Docker。
- Docker守护进程(Docker Daemon)。Docker 守护进程取代了 Hypervisor,它是运行在操作系统之上的后台进程,负责管理 Docker 容器。
- 各种依赖。对于 Docker,应用的所有依赖都打包在 Docker 镜像中,Docker 容器是基于 Docker 镜像创建的。
- 应用。应用的源代码与它的依赖都打包在 Docker 镜像中,不同的应用需要不同的 Docker 镜像。不同的应用运行在不同的 Docker 容器中,它们是相互隔离的。
对比
虚拟机是在物理资源层面实现的隔离,相对于虚拟机,Docker 是你 APP 层面实现的隔离,并且省去了虚拟机操作系统(Guest OS),从而节省了一部分的系统资源;Docker 守护进程可以直接与主操作系统进行通信,为各个 Docker 容器分配资源;它还可以将容器与主操作系统隔离,并将各个容器互相隔离。虚拟机启动需要数分钟,而 Docker 容器可以在数毫秒内启动。由于没有臃肿的从操作系统,Docker 可以节省大量的磁盘空间以及其他系统资源。
虚拟机与 docker 的区别,在于 vm 多了一层 guest OS,虚拟机的 Hypervisor 会对硬件资源也进行虚拟化,而容器 Docker 会直接使用宿主机的硬件资源。
下面我们采用形象的比喻区分两者的隔离级别:
- 服务器:比作一个大型的仓管基地,包含场地与零散的货物——相当于各种服务器资源。
- 虚拟机技术:比作仓库,拥有独立的空间堆放各种货物或集装箱,仓库之间完全独立——仓库相当于各种系统,独立的应用系统和操作系统。
- Docker:比作集装箱,操作各种货物的打包——将各种应用程序和他们所依赖的运行环境打包成标准的容器,容器之间隔离。
隔离性
在于隔离性上面,由于 vm 对操作系统也进行了虚拟化,隔离的更加彻底。而 Docker 共享宿主机的操作系统,隔离性较差。
运行效率
由于 vm 的隔离操作,导致生成虚拟机的速率大大低于容器 Docker 生成的速度,因为 Docker 直接利用宿主机的系统内核。比如 openstack 能够以 10台/min 的速度创建虚拟机,而 docker 可以做到在几秒钟之内创建大量容器,它们的启动速度是在数量级上的差距。
因为虚拟机增加了一层虚拟硬件层,运行在虚拟机上的应用程序在进行数值计算时是运行在 Hypervisor 虚拟的CPU上的;另外一方面是由于计算程序本身的特性导致的差异。虚拟机虚拟的 cpu 架构不同于实际 cpu 架构,数值计算程序一般针对特定的 cpu 架构有一定的优化措施,虚拟化使这些措施作废,甚至起到反效果。
资源利用率
在资源利用率上虚拟机由于隔离更彻底,因此利用率也会相对较低。
因为虚拟机增加了一层虚拟硬件层,运行在虚拟机上的应用程序在进行数值计算时是运行在 Hypervisor 虚拟的 CPU 上的;另外一方面是由于计算程序本身的特性导致的差异。虚拟机虚拟的 cpu 架构不同于实际 cpu 架构,数值计算程序一般针对特定的 cpu 架构有一定的优化措施,虚拟化使这些措施作废,甚至起到反效果。
在这个对比图里,我们应该把 Docker 画在跟应用同级别并且靠边的位置。这意味着,用户运行在容器里的应用进程,跟宿主机上的其他进程一样,都由宿主机操作系统统一管理,只不过这些被隔离的进程拥有额外设置过的 Namespace 参数。而 Docker 项目在这里扮演的角色,更多的是旁路式的辅助和管理工作。
这样的架构也解释了为什么 Docker 项目比虚拟机更受欢迎的原因。这是因为,使用虚拟化技术作为应用沙盒,就必须要由 Hypervisor 来负责创建虚拟机,这个虚拟机是真实存在的,并且它里面必须运行一个完整的 Guest OS 才能执行用户的应用进程。这就不可避免地带来了额外的资源消耗和占用。
而相比之下,容器化后的用户应用,却依然还是一个宿主机上的普通进程,这就意味着这些因为虚拟化而带来的性能损耗都是不存在的;而另一方面,使用 Namespace 作为隔离手段的容器并不需要单独的 Guest OS,这就使得容器额外的资源占用几乎可以忽略不计。
首先,既然容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。
尽管你可以在容器里通过 Mount Namespace 单独挂载其他不同版本的操作系统文件,比如 CentOS 或者 Ubuntu,但这并不能改变共享宿主机内核的事实。这意味着,如果你要在 Windows 宿主机上运行 Linux 容器,或者在低版本的 Linux 宿主机上运行高版本的 Linux 容器,都是行不通的。
而相比之下,拥有硬件虚拟化技术和独立 Guest OS 的虚拟机就要方便得多了。最极端的例子是,Microsoft 的云计算平台 Azure,实际上就是运行在 Windows 服务器集群上的,但这并不妨碍你在它上面创建各种 Linux 虚拟机出来。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具