问题: docker pull 命令从客户端到服务端是怎么执行的

👇 点击展开/折叠 面试背诵模板(建议先背这个) docker pull 执行流程分为三个阶段:客户端解析镜像名 → 与 Registry 交互获取清单 → 逐层下载并组装镜像。核心是 Docker Daemon 先向 Registry 请求镜像清单(Manifest),解析出所有层 ID 和摘要,然后并发下载每一层(默认并发 5 层),每层下载后计算 sha256 校验和验证完整性,最终解压到本地存储目录 /var/lib/docker/overlay2/。若本地已存在某层则跳过下载,实现层复用。整个过程涉及 Registry API v2 规范,包含认证、清单拉取和 Blob 下载三个子流程。
---

一、整体流程概览

docker pull 的本质是从容器镜像仓库(Registry)下载镜像的每一层(Layer)到本地存储。核心交互发生在 Docker Client、Docker Daemon 和 Registry 三者之间。流程可分为两个主要版本:旧版(Registry API v1)和新版(Registry API v2),当前主流使用 v2 版本。

二、主要执行步骤

步骤 1:客户端发起请求
用户在终端执行 docker pull nginx:latest,Docker Client 解析镜像名(仓库地址、镜像名、标签),默认使用 Docker Hub 官方仓库(docker.io)。

步骤 2:Docker Daemon 接收并处理
Docker Client 通过 REST API 将请求发送给 Docker Daemon。Daemon 解析镜像名后,构造 Registry API 请求 URL。对于官方镜像,完整地址为 https://registry-1.docker.io/v2/。

步骤 3:认证与 Token 获取
Daemon 向 Registry 请求 Bearer Token。Registry 返回认证授权端点(如 auth.docker.io),Daemon 再向该端点申请访问令牌,令牌包含对指定仓库的读取权限(scope: repository:library/nginx:pull)。

步骤 4:获取镜像清单(Manifest)
Daemon 向 Registry 发起 GET 请求获取镜像清单。Registry 返回 Manifest 文件,其中包含:

  • 镜像的 Config(配置层)和每个 Layer 的 digest(sha256 摘要)
  • 各层的大小(size)、压缩格式(mediaType)

步骤 5:解析并检查本地层缓存
Daemon 解析 Manifest,提取所有层的 digest 列表。对每一层,检查本地存储(/var/lib/docker/overlay2/)是否已存在该层的缓存。若存在则跳过该层下载(镜像层复用),否则进入下载队列。

步骤 6:并发下载镜像层(Blob 下载)
Daemon 对需要下载的层,从 Registry 的 /v2/.../blobs/ 端点逐层拉取。每层为 gzip 压缩的 tar 归档文件,下载后解压。默认并发数为 5 个层同时下载,可通过 --max-concurrent-downloads 调整。

步骤 7:校验层完整性并落盘
每层下载完成后,Daemon 计算文件的 sha256 校验和,与 Manifest 中记录的 digest 比对。校验通过后,将该层数据以链式方式写入本地存储目录。

步骤 8:组装镜像元数据
所有层下载并校验完成后,Daemon 在本地 manifest 数据库中创建镜像记录(镜像 ID、标签、各层 ID 的链式关系),并将镜像的配置信息(如环境变量、工作目录、Entrypoint)写入本地。

步骤 9:返回完成状态
Daemon 向 Client 返回拉取完成状态,终端输出 Status: Downloaded newer image for nginx:latest。

三、关键技术点与优化机制

机制 说明
镜像层复用 若本地已存在某层(digest 相同),直接复用,无需重新下载
并发下载 默认 5 层并发,加速下载
渐进式下载 拉取过程中可看到每层的下载进度,边下载边输出
镜像压缩 层以 gzip 压缩传输,节省带宽
Content-Addressable Storage 层内容通过 sha256 摘要寻址,保证唯一性和完整性
校验机制 每层下载后校验 digest,防止传输损坏或篡改

四、涉及的核心组件交互

  • Docker Client:负责解析命令并转发请求
  • Docker Daemon:作为核心协调者,执行认证、Manifest 拉取、层下载、校验和组装的全流程
  • Registry:镜像存储服务(Docker Hub、阿里云 ACR、Harbor 等),提供 API v2 接口
  • 本地存储:下载后的层存储在 /var/lib/docker/overlay2/,使用 overlay2 存储驱动进行联合挂载