2. 镜像供应链基础:容器镜像的组成、镜像层与基础镜像、镜像仓库与分发机制

2.1 容器镜像的组成结构

容器镜像本质上是一个只读的、分层的文件系统集合,外加一份描述其运行配置的元数据。理解镜像的内部组成是构建信任边界的第一步。

组成部分 说明 信任关注点
镜像层(Layer) 每一层代表 Dockerfile 中一条指令(如 RUN、COPY)产生的文件系统变更。 层的内容是否被篡改?来源是否可信?
镜像清单(Manifest) JSON 文件,描述镜像的层列表、架构、操作系统及配置。 清单签名是否有效?是否匹配实际层摘要?
镜像索引(Index) 多架构镜像的入口,指向不同平台对应的 Manifest。 索引是否被替换指向恶意镜像?
配置对象(Config) JSON 对象,包含环境变量、入口点、默认命令、暴露端口等。 配置是否被注入后门参数?
关键概念:镜像的不可变标识是 digest(SHA256 摘要),而非标签(tag)。标签可变,digest 不可变。供应链安全的第一原则:始终使用 digest 引用镜像。

2.2 镜像层与基础镜像

镜像层采用 UnionFS(联合文件系统) 技术堆叠。每一层只记录与上一层的差异(增量)。基础镜像位于最底层,是所有上层变更的起点。

容器镜像分层结构示意图 容器镜像分层结构 可写容器层(运行态) 镜像层 4:CMD / ENTRYPOINT 镜像层 3:COPY app.jar 镜像层 2:RUN apt-get install 基础镜像层:Ubuntu 22.04 基础镜像决定供应链信任的根。选择官方、签名、最小化基础镜像可大幅降低攻击面。

2.2.1 基础镜像的选择策略

  • 官方镜像(Official Images): 由 Docker 官方或上游社区维护,经过安全扫描,但需注意版本更新频率。
  • 最小化镜像(Distroless / Alpine): 仅包含运行时依赖,无 shell 和包管理器,攻击面显著减小。
  • 签名镜像(Notation / Cosign): 使用 OCI 标准签名验证镜像发布者身份,防止中间人替换。
  • 固定摘要(Pin by Digest): 避免使用 latest 或可变标签,强制锁定基础镜像版本。
⚠ 常见陷阱: 使用 FROM ubuntu:latest 会导致每次构建拉取不同版本的基础镜像,破坏可复现性,且可能意外引入漏洞。应始终使用 FROM ubuntu:22.04@sha256:abc123...。

2.3 镜像仓库与分发机制

镜像仓库(Registry)是镜像供应链的中枢。从开发者推送镜像到生产环境拉取,整个分发链路存在多个信任风险点。

2.3.1 仓库类型对比

类型 示例 信任控制 适用场景
公共仓库 Docker Hub, GitHub Container Registry 依赖平台安全 + 镜像签名验证 开源项目、基础镜像获取
私有仓库 Harbor, AWS ECR, Azure ACR 访问控制 + 漏洞扫描 + 策略引擎 企业内部分发、生产部署
代理缓存仓库 Harbor Proxy, Docker Registry Mirror 缓存上游镜像 + 内容过滤 + 速率限制 离线环境、加速拉取、安全审计

2.3.2 分发协议与信任链

OCI Distribution Spec 定义了镜像的推送和拉取流程。信任链的核心环节包括:

  1. 身份认证: 客户端与仓库之间的 TLS 双向认证或 Bearer 认证。
  2. 摘要验证: 拉取时客户端计算层摘要并与 Manifest 中的 digest 比对。
  3. 签名验证: 使用 Cosign / Notation 验证镜像签名是否由可信发布者签发。
  4. 策略执行: 在仓库端(如 Harbor)配置策略,阻止未签名或包含高危漏洞的镜像被部署。
镜像分发信任链流程 镜像分发信任链流程 开发者 Cosign 签名 Harbor 仓库 策略引擎(漏洞扫描 + 签名校验) Kubernetes 集群(拉取 + 部署) 信任链断裂点:签名缺失、仓库被攻破、策略绕过、拉取时未验证 digest。

2.4 镜像供应链信任边界总结

💡 核心原则: 信任不应隐式传递。每一层、每一次分发、每一个仓库交互都应显式验证。将“零信任”思想引入镜像供应链——验证一切,信任无物。
  • 镜像层: 每一层都应记录来源(FROM 层 + 构建上下文),并通过摘要锁定。
  • 基础镜像: 选择最小化、官方签名、固定摘要的基础镜像,定期更新。
  • 仓库: 私有仓库启用访问控制、漏洞扫描、签名策略和审计日志。
  • 分发: 客户端强制验证 digest 和签名,拒绝未经验证的镜像。