电脑之家
柔彩主题三 · 更轻盈的阅读体验

容器镜像签名机制:拉取镜像前怎么确认它没被篡改?

发布时间:2026-04-04 14:31:19 阅读:0 次

你有没有遇到过这样的情况:在 Docker 里 run 一个看似正规的 nginx 镜像,结果容器跑起来后偷偷往日志里写加密货币挖矿脚本?或者 CI/CD 流水线突然构建失败,查了半天发现 base 镜像被人替换成带后门的版本?这可不是危言耸听——公开 Registry 上的镜像,谁都能推、谁都能改,光靠镜像名和 tag 根本没法保真。

签名不是“盖章”,是数学验证

容器镜像签名机制,说白了就是给镜像打上一张“数字身份证”。它不依赖仓库管理员的信任背书,而是用非对称加密(比如 ECDSA)让开发者用自己的私钥对镜像 manifest(清单文件)生成签名,别人用对应的公钥就能验出这个镜像从打包到推送,一比特都没被改过。

举个生活化的例子:就像你收到一封带火漆印章的信,但这个印章不是画上去的,而是用你家特制的模具+熔蜡压出来的——收信人拿你公开的模具一比对,蜡形严丝合缝,就说明信没被调包。

实际怎么签?以 cosign 为例

目前最常用的工具是 cosign(Sigstore 项目出品),轻量、开源、支持 OCI 标准。假设你刚构建好一个镜像:

docker build -t ghcr.io/yourname/app:v1.2 .

先登录 GitHub Container Registry(或其他支持 OCI 的 registry),再用 cosign 签名:

cosign sign --key cosign.key ghcr.io/yourname/app:v1.2

签名会作为独立 artifact 推送到同一 registry 下的 .sig 路径,不改动原镜像。别人拉取时,可以强制校验:

cosign verify --key cosign.pub ghcr.io/yourname/app:v1.2

如果输出 Verified OK,且显示签名时间、签名人邮箱(若配置了 identity),那基本可以放心运行。

别只签不验:Docker 和 Kubernetes 怎么落地?

Docker Desktop 本身不自动验签,但可以通过 notary 或配合 containerdimage verification 插件启用。更现实的做法是在 CI 流水线里加一步:

# 在部署脚本中加入
if ! cosign verify --key prod.pub $IMAGE_REF; then
  echo "签名验证失败,拒绝部署!" >&2
  exit 1
fi

Kubernetes 用户可以用 SLSA 认证策略或 Pod Security Admission 结合 ImagePolicyWebhook 实现集群级拦截——只要镜像没通过指定密钥验证,Pod 就起不来。

小提醒:签名≠万能保险

签名只保证“镜像内容没变”,不保证代码本身安全。比如你签了一个含已知漏洞的 Log4j 镜像,它依然会爆。所以签名要和 SBOM(软件物料清单)、漏洞扫描联动使用,形成完整信任链。

下次 pull 镜像前,不妨多敲一行 cosign verify——这不是多此一举,是你给自己服务器加的一道隐形防盗门。