Docker|容器与Docker基础知识
从虚拟机开始
操作系统相较于单一应用程序,其复杂性及资源消耗显著更高,即便是一个全新安装、尚未部署任何应用程序的操作系统,其磁盘占用通常也以数十GB起,内存需求亦需数GB以上。
假设我们拥有一台内存为16GB的物理机,计划部署三个应用程序。若采用虚拟机技术进行部署,一种可能的资源分配方式如下:

虚拟机划分示意图
在此场景下,我们启动了三个虚拟机,分别部署一个应用程序。其中,VM1占用2GB内存,VM2占用1GB内存,VM3占用4GB内存。仅这三个虚拟机就合计占用了7GB的内存资源,因此我们没有办法划分出更多虚拟机从而部署更多的应用程序。
然而,我们部署和使用的核心目标是应用程序本身,而非操作系统。将大量宝贵的内存资源耗费在多个重复的、并非直接使用对象的操作系统上,显然是一种资源浪费。
这种资源浪费现象揭示了虚拟机技术存在的两个主要问题:
- 资源开销大:每个虚拟机内部都需要运行一个完整的操作系统,导致硬件资源(尤其是内存和磁盘)的重复占用。
- 启动速度慢:虚拟机的启动过程实质上是操作系统的启动过程,需要完成硬件检测、驱动加载等一系列操作,因此启动时间较长,通常以分钟计。
是否存在一种技术,能够既保留虚拟机提供的隔离优势,又能克服上述资源浪费和启动缓慢的缺点,从而实现效率与隔离性的兼得呢?答案是肯定的,这种技术便是容器技术。
容器技术基础
现代软件开发的一个重要目标是实现应用程序间的隔离,确保它们在运行时相互独立、互不干扰。容器技术正是基于这一需求应运而生。容器提供了一种轻量级的虚拟化方式,它封装了应用程序及其所有依赖项(如库、运行时、系统工具等),使其可以在不同的环境中以一致的方式运行。

Docker是目前最流行的容器化平台之一。理解Docker,需要掌握几个核心概念和命令:
- Image(镜像):一个只读的模板,包含了运行应用程序所需的一切(代码、运行时、库、环境变量、配置文件等)。镜像是创建容器的基石。
- Container(容器):基于镜像创建的一个可运行实例。可以将其理解为镜像的运行态。容器是隔离的、可移植的,并且是 ephemeral(短暂存在的,其状态通常不持久化)。
- Docker Daemon:在宿主机上运行的守护进程,负责管理镜像、容器、网络和存储等。
- Docker Client:用户与Docker Daemon交互的命令行工具。
三个关键命令及其关系:
- docker build:用于根据Dockerfile文件构建新的Image。Dockerfile是一个文本文件,包含了一系列指令,描述了如何从基础镜像构建出新的镜像。
- docker run:用于基于一个已存在的Image创建并启动一个新的Container。当执行此命令时,Docker Daemon会加载指定的Image,创建一个隔离的运行环境(即Container),并在其中执行应用程序。
- docker pull:用于从远程的Docker Registry(如Docker Hub)下载指定的Image到本地。这使得用户可以方便地复用社区或团队内共享的标准化镜像,无需从零开始构建。

三种命令的对比及关系
Docker的底层实现机制
Docker的强大功能主要建立在Linux内核提供的两项关键技术之上:
Namespace(命名空间)
Linux系统中的许多资源,如进程ID(PID)、进程间通信(IPC)、网络栈、挂载点(Mount)、用户和组ID(UID/GID)、UTS(主机名和域名)以及控制组(Cgroup)等,在传统上是全局可见的。Namespace机制提供了一种资源隔离的方案。通过为进程或进程组分配独立的Namespace,这些资源便不再是全局共享的,而是被限制在特定的Namespace内部。各个Namespace之间的资源互不干扰,使得每个Namespace内的环境看起来就像一个独立的操作系统实例。然而,仅有Namespace技术尚不足以完全模拟操作系统的行为。
Control Groups (cgroups)
尽管Namespace实现了资源隔离,但隔离后的进程仍然可能无限制地访问宿主机上的系统资源,例如CPU、内存、磁盘I/O和网络带宽等,这可能导致资源耗尽或影响其他容器乃至宿主机本身的性能。为了对容器内进程的资源使用进行限制和管理,Docker利用了Linux内核的cgroups(Control Groups)技术。cgroups允许系统管理员为进程设置资源使用的上限和优先级,例如限制容器最多可使用的内存量、指定可使用的CPU核心、限制磁盘I/O速率等。通过cgroups,可以确保容器中的应用程序在可控的资源范围内运行,保障系统的稳定性和多租户环境下的公平性。
总结
结合Namespace提供的隔离能力和cgroups提供的资源限制与管理能力,容器得以在用户看来如同一个轻量级的独立操作系统实例,既保证了应用程序间的隔离性,又极大地降低了资源开销和启动时间,从而实现了虚拟化技术与系统效率的平衡。