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层的摘要校验形成双重信任锚点。
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的设计直接影响镜像供应链的可追溯性与隔离性。以下是三种主流设计模式:
- 单项目单Repository模式:每个微服务或组件拥有独立的Repository,命名清晰,权限控制粒度细,适合大型企业级多团队协作。
- 多标签聚合模式:同一个Repository下通过标签区分环境(
:dev、:staging、:prod),适合小团队快速迭代,但标签覆盖可能引入安全风险。 - 不可变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 分发原理:分层并行拉取
当客户端拉取镜像时,仓库按照以下流程分发:
- 获取Manifest:客户端通过
GET /v2/<name>/manifests/<reference>获取Manifest,解析出所有层的摘要。 - 检查本地缓存:客户端对比本地已有层的摘要,跳过已存在的层。
- 并行拉取Blob:对缺失的层,客户端通过
GET /v2/<name>/blobs/<digest>并行下载,每个层独立校验摘要。 - 组装镜像:所有层下载完成后,根据Manifest中的配置信息组装成可运行的容器文件系统。
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) |