开启 Docker Content Trust 需先设置 DOCKER_CONTENT_TRUST=1(临时或写入 shell 配置),再确保 registry 支持签名验证;Docker Hub 默认支持,Harbor 需启用 content_trust 并配置 Notary 或 Cosign。

怎么开启 Docker Content Trust(DCT)并让镜像签名生效
不配置 DOCKER_CONTENT_TRUST=1,所有签名检查都形同虚设——它不是默认开启的,也不是装完 Docker 就自动启用的。你拉一个带签名的镜像,Docker 会照常运行,完全不报错,除非你显式打开信任检查。
实操上分两步:本地环境变量设置 + 远程仓库支持。前者控制客户端行为,后者决定签名能否被验证。
- 在 shell 中执行
export DOCKER_CONTENT_TRUST=1(临时);或写入~/.bashrc/~/.zshrc(长期) - 确保目标 registry 支持 DCT:Docker Hub 默认支持;私有 Harbor 需开启「内容信任」功能(对应配置项是
content_trust,且需配合 Notary 服务或启用了 Cosign 的 OCI 兼容模式) - 注意:
docker pull和docker build --push都受该变量影响;但docker run不直接受控——它依赖拉取时是否已校验过签名
Docker Hub 上怎么给镜像打签名(notary v1 流程还在用吗)
Notary v1 已被弃用,Docker Hub 现在用的是基于 Cosign + OCI Artifact 的签名机制,但 CLI 层仍保留 docker trust 命令作为兼容入口——它背后实际调用的是 cosign(如果你装了)或 Hub 自托管的签名服务。
关键点在于:签名对象不是镜像本身,而是镜像的 manifest digest;且必须用你自己的密钥对(本地生成或由 Docker Hub 托管)。
- 首次推送需先初始化信任:运行
docker trust key generate,生成本地 root key 和 delegation key - 关联仓库:用
docker trust signer add --key把公钥绑定到目标镜像仓库(如username/nginx) - 推送带签名镜像:必须用
docker push推送 manifest-list 或单架构镜像,且 tag 必须明确(不能是latest这类模糊 tag),否则签名无法绑定 - 常见错误:
no trust data available表示该 tag 没签过名;signature verification failed往往是因为本地时间偏差 >5 分钟,或 registry 返回的 signature payload 被中间代理篡改
私有 registry(Harbor / Nexus)怎么验证签名而不报“unknown authority”
私有仓库默认不被 Docker 客户端信任,即使你开了 DCT,也会卡在证书校验阶段,报错类似 x509: certificate signed by unknown authority——这不是签名问题,是 TLS 证书链没配对。
签名验证发生在 TLS 握手之后,所以得先让 Docker 认得你的 registry,再谈内容信任。
- 把私有 registry 的 CA 证书复制到
/etc/docker/certs.d/(路径必须严格匹配 host:port): /ca.crt - 重启 Docker daemon:否则
docker trust仍会走系统默认根证书池,忽略你放的 ca.crt - Harbor 用户注意:
content_trust.enabled必须为true,且项目级「内容信任」开关也要打开(UI 里叫 “Enable Content Trust”) - 如果用 Cosign 直接签名(绕过
docker trust),验证时要显式指定公钥:cosign verify --key cosign.pub username/nginx@sha256:xxx
CI/CD 流水线里自动签名容易漏掉哪几个环节
自动化签名最常失败的地方不在签名命令本身,而在上下文缺失和权限错位:密钥没加载、tag 动态生成导致签名丢失、多阶段构建中误推未签名层。
尤其要注意 CI 环境里 docker trust 不会自动读取交互式生成的密钥——它只认 ~/.docker/trust 下的文件,而这个目录在容器内通常是空的。
- 必须在 CI job 开始前,把 root key 和 delegation key 注入到
~/.docker/trust/private/(注意权限:私钥文件需0400) - 避免用
$(git describe)或$(date +%s)这类动态 tag:签名必须针对确定的 manifest digest,而动态 tag 可能指向不同 digest - 使用 BuildKit 构建时,
docker build --push不会自动触发签名;得拆成docker build -o type=image,name=...+docker push+docker trust sign - Harbor 的 webhook 如果监听
push事件,可能收不到签名事件(它是独立的trust事件),别指望靠它触发后续校验流程
签名不是加个 flag 就完事的事——它把镜像从“可运行的东西”变成了“带身份契约的制品”,一旦链条断一环,验证就静默失效。最容易被忽略的是时间同步和私有 CA 证书部署,这两处不出错,签名才真正起作用。










