2. 镜像仓库基础:Docker Registry 与 Harbor 架构、镜像存储原理、镜像层与 Manifest 概念
2.1 镜像仓库的角色与分类
镜像仓库(Registry)是云原生供应链的存储与分发核心。按部署形态可分为两类:
| 类型 | 代表产品 | 适用场景 | 关键特性 |
|---|---|---|---|
| 公共仓库 | Docker Hub、Quay.io、GitHub Container Registry | 开源镜像分发、CI/CD 基础镜像拉取 | 全球 CDN、匿名拉取、速率限制 |
| 私有仓库 | Harbor、Sonatype Nexus、JFrog Artifactory | 企业内网、合规审计、供应链安全 | RBAC、漏洞扫描、镜像签名、复制策略 |
容量水位巡检关注点: 私有仓库的存储配额、GC 回收效率、Blob 去重率直接影响集群稳定性和成本。Harbor 是 CNCF 毕业项目,也是企业级镜像供应链的首选底座。
2.2 Docker Registry 架构与核心组件
Docker Registry(v2)采用 HTTP API + 分布式存储 的简洁架构,不依赖数据库,所有元数据通过 Manifest 和 Blob 的引用关系推导。
关键设计: Registry 本身无状态,所有持久化数据(Blob + Manifest)写入存储后端。水平扩展只需增加实例并共享同一存储后端即可。
2.3 Harbor 架构:企业级扩展
Harbor 在原生 Registry 之上增加了完整的 管理平面,形成“Portal + Core + Registry + Database”的四层架构。
容量水位巡检关键组件: Job Service 负责 GC 和复制任务;Trivy/Clair 扫描器会缓存漏洞数据库,占用额外磁盘;PostgreSQL 存储项目、用户、标签等元数据,需监控连接数和慢查询。
2.4 镜像存储原理:Blob 与 Manifest
Docker 镜像采用 内容寻址存储(Content-Addressable Storage, CAS),每个存储单元通过其内容的 SHA256 哈希值唯一标识。
2.4.1 镜像层(Layer / Blob)
- 定义: 每个 Blob 代表一个文件系统变更集(tar.gz 格式),对应 Dockerfile 中的一条指令(RUN、COPY、ADD 等)。
- 存储路径:
/docker/registry/v2/blobs/sha256/{hash[0:2]}/{full_hash}/data - 去重: 相同内容的层在不同镜像间共享,只存储一份物理副本。
- 不可变性: Blob 一旦写入不可修改,只能通过 GC 删除未被引用的孤儿 Blob。
2.4.2 Manifest(镜像清单)
Manifest 是镜像的元数据文件,描述镜像由哪些层组成、以及配置信息。Registry v2 支持两种格式:
| 格式 | Media Type | 特点 | 适用场景 |
|---|---|---|---|
| Image Manifest V2 Schema 2 | application/vnd.docker.distribution.manifest.v2+json | 单架构、层列表 + 配置 | 传统单架构镜像 |
| OCI Image Manifest | application/vnd.oci.image.manifest.v1+json | 兼容 OCI 规范,支持 artifact 扩展 | OCI 标准镜像、Cosign 签名 |
| Manifest List (Fat Manifest) | application/vnd.docker.distribution.manifest.list.v2+json | 多架构索引,指向各平台 Manifest | 多架构镜像(amd64/arm64) |
Cosign 签名关联: Cosign 将签名信息写入 OCI Manifest 的
subject 字段,生成一个独立的签名 Manifest(media type: application/vnd.dev.cosign.simplesigning.v1+json),与原始镜像 Manifest 通过引用链关联。
2.5 镜像拉取流程与存储路径解析
以下是一次完整的 docker pull 操作在 Registry 内部的存储访问路径:
- 获取 Manifest: 客户端请求
/v2/{name}/manifests/{reference},Registry 返回 Manifest JSON。 - 解析层列表: 从 Manifest 的
layers字段获取每个 Blob 的 digest(SHA256)。 - 并行下载 Blob: 客户端请求
/v2/{name}/blobs/{digest},Registry 从存储后端读取对应文件。 - 解压与组装: 客户端将 Blob 解压为文件系统层,按顺序叠加为容器根文件系统。
# 存储后端文件路径示例(本地文件系统)
/var/lib/registry/
├── docker/
│ └── registry/
│ └── v2/
│ ├── blobs/
│ │ └── sha256/
│ │ ├── a1/ # 哈希前两位作为子目录
│ │ │ └── a1b2c3...full_hash
│ │ │ └── data # 实际层数据(tar.gz)
│ │ └── b2/
│ │ └── b2c3d4...full_hash
│ │ └── data
│ └── repositories/
│ └── library/
│ └── nginx/
│ ├── _manifests/
│ │ ├── revisions/
│ │ │ └── sha256/
│ │ │ └── manifest_hash
│ │ └── tags/
│ │ └── latest/
│ │ ├── current # 指向当前 Manifest digest
│ │ └── link # 符号链接
│ └── _layers/
│ └── sha256/
│ └── layer_hash
│ └── link # 指向 blobs 目录的链接
容量巡检陷阱: 当大量镜像被删除后,孤儿 Blob 不会立即释放磁盘空间。Harbor 的 GC 机制需要手动触发或定时执行,且 GC 期间 Registry 会进入只读模式。巡检时应关注
blobs/ 目录大小与 repositories/ 中引用数的比例,若比例异常偏高,说明需要执行 GC。
2.6 镜像层与 Manifest 的关系图
容量水位巡检指标: 关注
blobs/ 目录下文件总数与 repositories/ 中引用的 Blob 数之差。差值越大,孤儿 Blob 越多,磁盘浪费越严重。建议设置 GC 触发阈值:孤儿 Blob 占比超过 10% 时自动触发清理。
2.7 本章小结
- Docker Registry 是轻量无状态存储服务,核心为 HTTP API + Blob/Manifest 内容寻址。
- Harbor 在 Registry 之上增加 RBAC、扫描、复制、GC 等企业能力,是供应链安全巡检的管控中心。
- 镜像层(Blob) 是内容寻址的不可变文件,Manifest 是描述镜像组成的元数据清单。
- Cosign 签名 利用 OCI Manifest 的扩展能力,将签名作为独立 artifact 与镜像关联。
- 容量巡检需重点关注 孤儿 Blob 比例、GC 执行频率、存储后端 IO 延迟 三个核心指标。