3. 镜像仓库架构:镜像仓库分层结构、Registry与Repository设计、镜像存储与分发原理

镜像仓库是镜像供应链的核心基础设施,承担着镜像的存储、版本管理、分发与信任验证等关键职责。理解其分层架构、Registry与Repository的设计模式以及存储分发原理,是构建安全、高效、可扩展的镜像供应链的基础。

3.1 镜像仓库分层结构

现代镜像仓库(如 Harbor、Docker Registry、Quay)普遍采用四层逻辑架构,从底层存储到上层访问控制,每一层解决不同维度的工程问题。

层级 名称 核心职责 典型组件/技术
L4 接入与安全层 认证、授权、审计、TLS终止、速率限制 Nginx、OAuth2 Proxy、RBAC、OIDC
L3 业务逻辑层 镜像元数据管理、标签管理、GC、Webhook Registry API、Garbage Collector、Notification
L2 存储抽象层 Blob与Manifest的读写、分片、去重、校验 Distribution Driver、Content-Addressable Storage
L1 物理存储层 持久化、高可用、备份、异地容灾 S3、GCS、Azure Blob、NFS、Ceph
架构要点:分层设计的核心价值在于解耦——存储层可以无缝切换(从本地文件系统迁移到S3),安全策略可以独立升级,业务逻辑层不受底层存储变更影响。在信任边界通信场景中,L4层的签名验证与L2层的摘要校验形成双重信任锚点。
镜像仓库四层分层架构 镜像仓库四层分层架构 L4 接入与安全层 认证 · 授权 · TLS · 审计 · 速率限制 L3 业务逻辑层 元数据管理 · 标签管理 · GC · Webhook L2 存储抽象层 Blob/Manifest读写 · 分片 · 去重 · 摘要校验 L1 物理存储层 S3 · GCS · Azure Blob · NFS · Ceph 信任边界 签名+摘要 双重锚点

3.2 Registry与Repository设计

在镜像仓库的命名空间中,Registry 与 Repository 是两个容易混淆但职责完全不同的概念。理解它们的区别是设计多租户镜像供应链的前提。

3.2.1 概念辨析

维度 Registry(注册表) Repository(仓库)
定义 一个完整的镜像托管服务实例 Registry内某个特定镜像的集合
URL示例 registry.example.com registry.example.com/team-a/nginx
包含关系 包含多个Repository 包含多个Tag和镜像版本
安全边界 全局认证、TLS、审计策略 细粒度RBAC、项目级隔离
存储结构 独立的存储桶/文件系统命名空间 Blob共享,Manifest独立

3.2.2 Repository设计模式

在信任边界通信机制中,Repository的设计直接影响镜像供应链的可追溯性与隔离性。以下是三种主流设计模式:

  1. 单项目单Repository模式:每个微服务或组件拥有独立的Repository,命名清晰,权限控制粒度细,适合大型企业级多团队协作。
  2. 多标签聚合模式:同一个Repository下通过标签区分环境(:dev、:staging、:prod),适合小团队快速迭代,但标签覆盖可能引入安全风险。
  3. 不可变Repository模式:禁止标签覆盖,每次推送生成唯一摘要引用,配合签名机制实现镜像不可篡改,是供应链安全的首选模式。
安全警示:在多标签聚合模式下,如果允许标签覆盖(如 docker push myapp:latest),攻击者可能通过覆盖标签植入恶意镜像。在信任边界通信架构中,应强制启用不可变标签策略,并配合Notary或Sigstore进行签名验证。

3.3 镜像存储与分发原理

镜像仓库的存储与分发机制基于OCI(Open Container Initiative)分发规范,核心思想是内容寻址存储(Content-Addressable Storage, CAS)与分层复用。

3.3.1 存储模型:Blob与Manifest

镜像在仓库中以两种对象形式存储:

  • Blob(二进制大对象):存储镜像层(Layer)的实际数据,每个Blob由其内容摘要(SHA256)唯一标识。相同的层在不同镜像间共享,极大节省存储空间。
  • Manifest(清单):描述镜像的元数据,包括各层的摘要、大小、媒体类型以及配置信息。Manifest本身也是一个Blob,同样通过摘要寻址。

存储路径结构示例:

/docker/registry/v2/
├── blobs/
│   └── sha256/
│       ├── a1b2c3... (layer blob)
│       ├── d4e5f6... (config blob)
│       └── g7h8i9... (manifest blob)
└── repositories/
    └── team-a/
        └── nginx/
            ├── _layers/
            │   └── sha256/
            │       └── a1b2c3... (link file)
            ├── _manifests/
            │   ├── revisions/
            │   │   └── sha256/
            │   │       └── g7h8i9... (link file)
            │   └── tags/
            │       └── 1.21/
            │           └── current (link to manifest)
            └── _uploads/ (临时上传目录)

3.3.2 分发原理:分层并行拉取

当客户端拉取镜像时,仓库按照以下流程分发:

  1. 获取Manifest:客户端通过 GET /v2/<name>/manifests/<reference> 获取Manifest,解析出所有层的摘要。
  2. 检查本地缓存:客户端对比本地已有层的摘要,跳过已存在的层。
  3. 并行拉取Blob:对缺失的层,客户端通过 GET /v2/<name>/blobs/<digest> 并行下载,每个层独立校验摘要。
  4. 组装镜像:所有层下载完成后,根据Manifest中的配置信息组装成可运行的容器文件系统。
镜像拉取分发流程 镜像拉取分发流程(分层并行拉取) Docker 客户端 ① GET Manifest Registry ② 返回Manifest 解析Manifest 检查本地缓存 ③ 并行GET Blob 返回Blob数据 组装镜像 分层复用优势 • 基础层(如Ubuntu)被多个镜像共享 • 只拉取增量层,减少带宽消耗 • 每层独立校验SHA256摘要 • 支持断点续传(Range请求) 信任边界校验点: 1. Manifest签名验证 2. 每层摘要一致性校验 3. 层内容解压后完整性检查 4. 最终镜像配置校验

3.3.3 推送流程与分片上传

镜像推送采用分片上传(Monolithic Upload 或 Chunked Upload)机制,避免大镜像单次传输失败导致全部重传:

  • 初始化上传会话:客户端发起 POST /v2/<name>/blobs/uploads/,获取上传URL。
  • 分片上传:客户端将层数据分成多个片段(Chunk),通过 PATCH 请求逐片上传,服务端记录已接收的偏移量。
  • 完成上传:上传所有分片后,客户端发送 PUT 请求并携带最终摘要,服务端校验摘要一致性后生成Blob。
  • 推送Manifest:所有层上传完成后,客户端推送Manifest,仓库更新标签引用。
性能优化实践:在信任边界通信场景中,建议在推送阶段增加签名步骤——客户端在推送Manifest前,使用私钥对Manifest内容进行签名,并将签名附加到Manifest的Annotations中。仓库端在接收时验证签名,确保只有经过授权的构建系统才能推送镜像。

3.4 信任边界视角下的架构设计要点

结合镜像供应链的信任边界通信需求,仓库架构需要额外关注以下设计要点:

架构维度 信任边界要求 实现方案
存储层 防篡改、可审计 启用WORM存储、存储层访问日志、定期摘要校验
分发层 传输加密、中间人防护 强制TLS 1.3、证书固定、mTLS双向认证
业务层 签名验证、策略执行 集成Notary/Sigstore、OPA策略引擎、准入控制Webhook
接入层 身份认证、细粒度授权 OIDC集成、RBAC、基于属性的访问控制(ABAC)