在容器化交付中,镜像一旦被替换、篡改或错误标记,就可能把风险直接带入测试与生产环境。🔐 镜像签名的核心价值,是让使用者能够验证镜像发布者身份与内容完整性,从“镜像能否拉取”升级为“镜像是否可信”。
一、镜像签名解决什么问题
Docker 镜像通常通过标签引用,例如 app:1.0 或 app:latest,但标签本身可以重新指向其他内容。仅检查标签无法证明当前镜像就是发布时的版本,也不能确认它来自获授权的发布者。
镜像摘要 digest 是由镜像内容计算得到的不可变标识。使用 repo@sha256:摘要 的方式部署,可以降低标签漂移带来的风险,但摘要固定只解决“内容是否变化”,不能独立证明“由谁发布”。因此,较完整的方案应同时包含摘要固定、数字签名、身份验证和部署策略。
简单理解:摘要回答“是不是同一份内容”,签名回答“这份内容是否由可信主体发布”。
二、认识 Docker Content Trust
Docker Content Trust,简称 DCT,基于 Notary v1 和 TUF 信任模型,为镜像标签提供签名与客户端验证能力。发布者签名后,使用者可以在拉取镜像时检查签名元数据,从而验证镜像完整性和发布者身份。详细机制可参考 Docker 内容信任文档。
需要特别注意的是,Docker 已宣布逐步淘汰 DCT,notary.docker.io 的 Notary v1 服务计划于 2026 年 12 月 8 日关闭。因此,DCT 更适合用于维护现有环境和理解历史信任链,新建项目应优先评估 Cosign 或 Notary Project 的 Notation。迁移背景可查看 Docker 迁移说明。⚠️
三、启用内容信任并验证镜像
1. 开启 DCT
在 Linux 或 macOS Shell 中执行:
export DOCKER_CONTENT_TRUST=1
启用后,docker pull、docker push 和 docker build 等相关命令会执行内容信任检查。拉取没有有效签名的标签时,操作通常会失败,而不是静默使用未经验证的镜像。
2. 拉取受信任镜像
执行:
docker pull registry.example.com/team/app:1.0
如果仓库、标签及签名元数据均可用,客户端会完成验证并拉取对应镜像。若提示没有信任数据、签名过期或无法访问 Notary 服务,应先排查镜像是否确实完成签名,再检查仓库地址、证书、网络和客户端时间。
3. 查看签名信息
执行:
docker trust inspect --pretty registry.example.com/team/app:1.0
该命令可查看签名者、签名键以及标签对应的摘要。排查问题时,应重点确认摘要是否与发布记录一致、签名者是否在授权名单中,以及目标标签是否真的被签名。
四、签名并发布自己的镜像
先完成登录、构建和标记,再执行:
docker trust sign registry.example.com/team/app:1.0
首次为仓库签名时,Docker 可能创建根密钥和仓库签名密钥,并要求设置口令。根密钥代表最高信任级别,不应长期存放在普通开发机或 CI 节点中。建议离线加密备份,并把日常发布权限交给委托签名者。
完成签名后,可再次运行 docker trust inspect 检查签名结果,并在另一台启用 DOCKER_CONTENT_TRUST=1 的主机上执行拉取测试。这样能够同时验证签名数据上传、远程访问和消费端校验流程。✅
五、将验证接入 CI/CD
在流水线中,可将内容信任检查安排在构建基础镜像、生成制品和部署之前。若验证失败,应立即终止任务,避免通过手工参数绕过。签名步骤则应放在测试、漏洞扫描和审批通过之后,确保只有合格制品能够获得发布签名。
- 构建阶段:基础镜像使用摘要固定,并检查来源是否合法。
- 测试阶段:完成单元测试、依赖检查和镜像漏洞扫描。
- 签名阶段:仅允许受保护的发布任务访问签名密钥。
- 部署阶段:验证签名、签名者身份、仓库范围和镜像摘要。
- 审计阶段:记录制品摘要、签名者、流水线编号和部署环境。
自动化环境可以通过变量提供仓库签名密钥口令,但不应把口令明文写入脚本、Dockerfile 或代码仓库。应使用 CI 平台的密钥库、短期凭据或外部密钥管理系统,并限制日志输出。DCT 自动化方式可参考 官方自动化指南。
六、常见误区与排查方法
- 只签 latest:latest 容易变化,建议同时发布明确版本标签,并保存对应摘要。
- 把扫描等同于签名:漏洞扫描判断已知风险,签名验证来源与完整性,两者不能互相替代。
- 私钥进入镜像:签名私钥不得复制到构建上下文、镜像层或普通流水线制品中。
- 只在开发机验证:真正的控制点应覆盖 CI/CD 和生产部署入口。
- 直接关闭失败校验:验证异常可能意味着签名缺失、证书过期或信任链变化,应先定位原因。
七、面向新项目的迁移建议
对于仍在使用 DCT 的团队,可先检索 DOCKER_CONTENT_TRUST、docker trust sign、docker trust inspect 等配置,梳理依赖范围,再设计替代方案。迁移期间不宜直接删除旧校验,而应让新旧流程并行验证,确认签名、存储、策略执行和回滚机制均正常后再切换。
新方案可优先考虑 Cosign 或 Notation。它们更适合 OCI 制品和现代供应链场景,可与云密钥管理、CI/CD 身份以及 Kubernetes 准入策略结合。无论采用哪种工具,都应明确可信签名者、允许的仓库范围、密钥轮换方式和验证失败处理规则,而不是停留在“成功生成一个签名”。
总结
Docker 镜像信任不是单一命令,而是一套覆盖构建、签名、存储、验证、部署和审计的控制链。🛡️ 维护现有系统时,可以利用 DCT 检查签名标签并保护发布流程;规划新系统时,则应结合 DCT 的退役时间,尽快迁移到 Cosign 或 Notation,并配合摘要固定、密钥保护及部署准入策略,真正实现“未经验证的镜像不得进入生产环境”。