核心理念:一次构建,随处运行
Docker 的本质是应用的标准化集装箱。它将应用及其所有依赖项(代码、运行时、系统工具、库、配置)打包在一个称为"镜像"的轻量级、可移植的容器中,从而保证应用在任何计算环境中都能以完全相同的方式运行。
一、核心三要素:镜像、容器、仓库
-
镜像(Image)
-
定义 :一个只读的模板,包含了运行应用所需的文件系统结构和内容。它像一个面向 Docker 引擎的"软件安装包"。
-
特点:分层存储(Layer),每一层都是对前一层的增量修改。这种设计使得镜像非常高效、可复用。
-
类比 :镜像是类(Class)。
-
-
容器(Container)
-
定义 :镜像的一个运行实例。容器在镜像的顶层创建一个可写的"容器层",所有运行时的修改都发生在此层。
-
特点:拥有独立的进程、网络、文件系统等运行环境,但与宿主机共享内核。它是轻量级、秒级启动的。
-
类比 :容器是对象(Object),或一个运行中的进程。
-
-
仓库(Registry)
-
定义:集中存放镜像的地方。最著名的是 Docker Hub。
-
组成 :一个仓库包含多个镜像标签 。例如
ubuntu:20.04和ubuntu:22.04是同一个ubuntu仓库下的不同镜像。
-
关系图解:

一个镜像可以创建多个容器,一个运行的容器可以提交为新的镜像,镜像在仓库和本地之间可以推送拉取。
二、Docker 架构与核心原理
1. 整体架构图
下图清晰地展示了 Docker 客户端-守护进程的架构模式,以及核心组件间的交互关系:

-
Docker 客户端 (Client) :用户通过 CLI(
docker命令)或 GUI 与 Docker 交互。 -
Docker 守护进程 (Daemon,
dockerd) :在宿主机后台运行,负责构建、运行、分发容器。它是 Docker 引擎的核心。 -
Docker 主机 (Host):运行守护进程和容器的物理或虚拟机。
-
镜像仓库 (Registry):存放镜像的远程服务器。
通信流程 :当你在终端输入 docker run 时,客户端通过 REST API 将指令发送给守护进程,守护进程执行操作并返回结果。
2. 与虚拟机的本质区别
这是理解 Docker 轻量化的关键。
传统虚拟机:
-
基础设施:物理服务器。
-
Hypervisor:虚拟机监控器,在物理硬件上虚拟出一套完整的虚拟硬件(CPU、内存、磁盘、网卡)。例如 VMware, VirtualBox。
-
Guest OS:每个虚拟机都需要安装一个完整的操作系统(如 Windows 或完整的 Linux 发行版)。
-
应用:运行在 Guest OS 之上。
-
缺点:资源占用大(每台 VM 都要占数 GB 到数十 GB),启动慢(分钟级),性能有损耗。
Docker 容器:
-
基础设施:物理服务器。
-
宿主机操作系统:Linux(或通过 Docker Desktop 在 Win/Mac 上运行的轻量级 Linux VM)。
-
容器引擎 :Docker Engine。它直接利用宿主机内核。
-
容器 :每个容器只是一个隔离的进程,直接运行在宿主机内核之上。容器内没有独立的内核,只有必要的用户空间文件和库。
-
应用:直接运行在容器中。
-
优点:轻量(MB 级)、快速(秒级启动)、高性能(接近原生)。
架构对比图:

三、核心技术:Linux 内核特性
Docker 的强大隔离能力并非魔法,而是基于 Linux 内核的几项关键技术。Docker 容器本质上是带有配置选项的 Linux 进程。
1. 命名空间(Namespaces)
为进程提供独立的系统视图,实现资源的隔离。
-
pid命名空间:进程隔离。容器内拥有独立的进程树,PID=1 通常是容器启动进程。 -
net命名空间:网络隔离。容器拥有独立的网络栈(IP、端口、路由表等)。 -
mnt命名空间 :文件系统挂载点隔离。容器看到独立的根文件系统/。 -
ipc命名空间:进程间通信资源(如消息队列)的隔离。 -
uts命名空间:主机名和域名的隔离。 -
user命名空间:用户和用户组 ID 的隔离,增强安全性。
图解:不同的命名空间将全局资源(如进程树、网络接口)包装起来,让每个容器都感觉自己独占系统。
2. 控制组(Cgroups)
限制和隔离进程组的物理资源使用。
-
作用:限制 CPU、内存、磁盘 I/O、网络带宽的使用,防止某个容器耗尽宿主机资源。
-
示例:你可以为容器 A 设定最多使用 1 个 CPU 核心和 512MB 内存。
3. 联合文件系统(UnionFS)
实现镜像分层 和容器可写层的核心技术。
-
原理 :将多个目录(称为层)"联合"挂载到同一个虚拟目录下。上层文件会覆盖下层的同名文件。
-
Docker 中的应用:
-
镜像 :由一系列只读层构成。例如,一个
ubuntu + nginx + myapp的镜像有三层。 -
容器 :在镜像的所有只读层之上,添加一个唯一的可写层(容器层) 。所有对容器的修改(写文件、删文件)都发生在这个可写层。删除文件只是在可写层标记为"删除",下层数据依然存在。
-
-
好处:极大节省存储和传输成本。拉取镜像时,已存在的层无需重复下载。
镜像与容器分层图解:

两个不同的容器共享底层的只读镜像层,但拥有各自独立、互不干扰的可写层。
4. 容器运行时(Container Runtime)
负责真正创建和运行容器的底层软件。
-
Docker 早期 :使用
LXC(Linux Container),后来被runc取代。 -
containerd与runc:-
runc:一个轻量级的、符合 OCI 标准的低级运行时 。它直接与内核交互,使用命名空间和 cgroups 来运行一个容器。runc本质上就是docker run命令的底层实现。 -
containerd:一个高级运行时 ,负责管理完整的容器生命周期(镜像传输、存储、执行runc等)。Docker Daemon 将容器执行任务委托给containerd。
-
-
OCI(开放容器倡议) :定义了容器镜像和运行时的行业标准(
image-spec,runtime-spec)。runc是 OCI 的参考实现。
现代 Docker 运行流程简化图:
bash
用户执行 `docker run nginx`
|
v
Docker CLI
|
v
Docker Daemon (dockerd)
|
v
containerd (通过 gRPC API)
|
v
containerd-shim (管理容器进程,与守护进程解耦)
|
v
runc (创建容器)
|
v
容器进程 (如 nginx) 启动
总结
Docker 的核心原理可以概括为:
-
打包 :通过联合文件系统 将应用及其环境打包成分层的只读镜像。
-
分发 :通过仓库实现镜像的版本管理和分发。
-
隔离 :通过 Linux 命名空间 为每个容器实例提供独立的运行环境(进程、网络、文件系统等)。
-
限制 :通过 cgroups 限制每个容器实例的资源使用上限。
-
运行 :通过标准的容器运行时(
containerd/runc),利用宿主内核,将镜像实例化为一个轻量级的、隔离的进程(容器)。
正是这些技术的结合,使得 Docker 在效率、便携性和一致性上取得了革命性的突破,成为现代云计算和 DevOps 的基石。