Azure 容器注册表实现 Docker 内容信任 (DCT) 模型,以启用推送和拉取已签名映像。 本文将指导您如何在您的容器注册表中启用 DCT。 DCT 是容器注册表 的高级服务层 的一项功能。
重要
DCT 将于 2028 年 3 月 31 日弃用并完全删除。 有关详细信息和转换指南,请参阅 从 Docker 内容信任过渡到公证项目。
限制
具有存储库范围权限的令牌目前无法支持 Docker 推送和拉取签名图像。
DCT 的工作原理
对于在设计时考虑到安全性的任何分布式系统,验证进入系统的数据的 源 和 完整性 是非常重要的。 数据的使用者需要能够验证数据的发布者(源),并确保数据在发布后未修改(完整性)。
作为映像发布者,可以使用 DCT 对推送到注册表的映像进行签名。 映像的使用者(从注册表拉取映像的人员或系统)可以将其客户端配置为仅拉取已签名的映像。 当映像使用者拉取签名的映像时,其 Docker 客户端会验证映像的完整性。 在此模型中,使用者可以确信你在注册表中发布了已签名的映像,并且发布后未修改映像。
注意
容器注册表不支持 acr import 导入使用 DCT 签名的映像。 按照设计,导入后不会显示签名。 Notary v2 将这些签名存储为工件。
受信任的映像
DCT 与存储库中的标签一起工作。 映像存储库可以包含同时具有已签名标记和未签名标记的映像。 例如,可以只对 myimage:stable 和 myimage:latest 映像签名,而不对 myimage:dev 映像签名。
签名密钥
使用一组加密签名密钥管理 DCT。 这些密钥与注册表中的特定存储库相关联。
Docker 客户端和你的注册表使用多种类型的签名密钥来管理存储库中标记的信任。 启用 DCT 并将其集成到管道中以用于容器发布和使用时,必须仔细管理这些密钥。 有关详细信息,请参阅本文后面的 “管理密钥 ”和 Docker 文档中 的内容信任管理密钥 。
为注册表启用 DCT
您的第一步是在注册表级别上启用 DCT。 启用 DCT 后,客户端(用户或服务)可以将签名的映像推送到注册表。
为注册表启用 DCT 不会将注册表使用情况限制为仅启用 DCT 的使用者。 未启用 DCT 的使用者可以照常使用注册表。 但是,在其客户端中启用 DCT 的使用者 只能 查看注册表中的已签名映像。
若要使用 Azure 门户为注册表启用 DCT,请转到注册表。 在策略下,选择内容信任>启用>保存。 你还可以在 Azure CLI 中使用 az acr config content trust update 命令。
为客户端启用 DCT
若要使用受信任的映像,映像发布者和使用者都需要为其 Docker 客户端启用 DCT。 作为发行商,你可以对传送到启用 DCT 的注册表中的镜像进行签名。 作为消费者,启用 DCT 会将您的镜像库视图限制为仅限签名图像。 默认情况下,DCT 在 Docker 客户端中处于禁用状态,但你可以为每个 shell 会话或每个命令启用它。
若要为 shell 会话启用 DCT,请将 DOCKER_CONTENT_TRUST 环境变量设置为 1。 例如,在 Bash shell 中,使用以下代码:
# Enable DCT for a shell session
export DOCKER_CONTENT_TRUST=1
如果要为单个命令启用或禁用 DCT,多个 Docker 命令支持该 --disable-content-trust 参数。
若要为单个命令启用 DCT,请使用以下代码:
# Enable DCT for a single command
docker build --disable-content-trust=false -t myacr.azurecr.cn/myimage:v1 .
如果为 shell 会话启用了 DCT 并想要为单个命令禁用它,请使用以下代码:
# Disable DCT for a single command
docker build --disable-content-trust -t myacr.azurecr.cn/myimage:v1 .
授予映像签名权限
只有授予权限的用户或系统才能将受信任的映像推送到注册表。 若要向用户(或使用服务主体的系统)授予此推送权限,请将 AcrImageSigner 角色分配给用户的Microsoft Entra 标识。 此权限是除了将映像推送到注册表所需的 AcrPush(或等效)角色之外另外需要的权限。 有关详细信息,请参阅 Azure 容器注册表权限和角色分配概述。
截至 2021年7月,该AcrImageSigner角色包括Microsoft.ContainerRegistry/registries/sign/write操作和数据Microsoft.ContainerRegistry/registries/trustedCollections/write操作。
Azure 门户
若要使用 Azure 门户授予 AcrImageSigner 角色,请执行以下步骤:
选择“访问控制 (IAM)”。
选择 添加>角色分配以打开添加角色分配窗格。
分配以下角色。 在此示例中,角色分配给单个用户。 有关详细步骤,请参阅 使用 Azure 门户分配 Azure 角色。
设置 值 Role AcrImageSigner 将访问权限分配到 User 成员 阿兰
Azure CLI
若要使用 Azure CLI 向用户授予签名权限,请将 AcrImageSigner 角色分配给用户,范围限定为注册表。 该命令的格式如下:
az role assignment create --scope <registry ID> --role AcrImageSigner --assignee <user name>
例如,若要将角色分配给非管理用户,可以在经过身份验证的 Azure CLI 会话中运行以下命令。 修改 REGISTRY 值,使之反映 Azure 容器注册表的名称。
# Grant signing permissions to an authenticated Azure CLI user
REGISTRY=myregistry
REGISTRY_ID=$(az acr show --name $REGISTRY --query id --output tsv)
az role assignment create --scope $REGISTRY_ID --role AcrImageSigner --assignee azureuser@contoso.com
也可向服务主体授予将受信任的映像推送到注册表的权限。 服务主体适用于需将受信任的映像推送到注册表的生成系统和其他无人参与系统。 类似于授予用户权限的格式,但您为 --assignee 值指定了服务主体 ID:
az role assignment create --scope $REGISTRY_ID --role AcrImageSigner --assignee <service principal ID>
该值 <service principal ID> 可以是服务主体 appId 的值、其 objectId 值或其值之一 servicePrincipalNames 。 若要详细了解如何使用服务主体和 Azure 容器注册表,请参阅使用服务主体的 Azure 容器注册表身份验证。
重要
在任何角色更改后,运行 az acr login 以刷新 Azure CLI 的本地标识令牌,以便新角色生效。 有关验证标识角色的信息,请参阅 使用 Azure CLI 分配 Azure 角色 并 排查 Azure RBAC 问题。
推送受信任的映像
若要将受信任的映像标记推送到容器注册表,请启用 DCT 并使用 docker push。 首次使用带签名的标签进行推送后,你需要为根签名密钥和存储库签名密钥创建口令。 根密钥和存储库密钥都是以本地方式在计算机上生成并存储的。
$ docker push myregistry.azurecr.cn/myimage:v1
[...]
The push refers to repository [myregistry.azurecr.cn/myimage]
ee83fc5847cb: Pushed
v1: digest: sha256:aca41a608e5eb015f1ec6755f490f3be26b48010b178e78c00eac21ffbe246f1 size: 524
Signing and pushing trust metadata
You are about to create a new root signing key passphrase. This passphrase
will be used to protect the most sensitive key in your signing system. Please
choose a long, complex passphrase and be careful to keep the password and the
key file itself secure and backed up. It is highly recommended that you use a
password manager to generate the passphrase and keep it safe. There will be no
way to recover this key. You can find the key in your config directory.
Enter passphrase for new root key with ID 4c6c56a:
Repeat passphrase for new root key with ID 4c6c56a:
Enter passphrase for new repository key with ID bcd6d98:
Repeat passphrase for new repository key with ID bcd6d98:
Finished initializing "myregistry.azurecr.cn/myimage"
Successfully signed myregistry.azurecr.cn/myimage:v1
在您首次启用 DCT 的 docker push 操作后,Docker 客户端对后续推送使用相同的根密钥。 每次将内容后续推送到同一存储库时,系统只要求提供存储库密钥。 每次将受信任的映像推送到新存储库时,系统会要求提供新存储库密钥的通行短语。
拉取受信任的映像
若要拉取受信任的映像,请启用 DCT 并按正常方式运行 docker pull 命令。 若要拉取受信任的映像,AcrPull 角色对于普通用户来说已足够了。 不需要其他角色(类似于 AcrImageSigner 角色)。 启用了 DCT 的使用者只能提取具有签名标记的映像。 下面是拉取签名标记的示例:
$ docker pull myregistry.azurecr.cn/myimage:signed
Pull (1 of 1): myregistry.azurecr.cn/myimage:signed@sha256:0800d17e37fb4f8194495b1a188f121e5b54efb52b5d93dc9e0ed97fce49564b
sha256:0800d17e37fb4f8194495b1a188f121e5b54efb52b5d93dc9e0ed97fce49564b: Pulling from myimage
8e3ba11ec2a2: Pull complete
Digest: sha256:0800d17e37fb4f8194495b1a188f121e5b54efb52b5d93dc9e0ed97fce49564b
Status: Downloaded newer image for myregistry.azurecr.cn/myimage@sha256:0800d17e37fb4f8194495b1a188f121e5b54efb52b5d93dc9e0ed97fce49564b
Tagging myregistry.azurecr.cn/myimage@sha256:0800d17e37fb4f8194495b1a188f121e5b54efb52b5d93dc9e0ed97fce49564b as myregistry.azurecr.cn/myimage:signed
如果启用了 DCT 的客户端尝试拉取未签名的标签,操作将失败,并出现类似于以下示例的错误:
$ docker pull myregistry.azurecr.cn/myimage:unsigned
Error: remote trust data does not exist
幕后
运行docker pull时,Docker 客户端与Notary CLI使用相同的库来请求你正在提取的标记的标记到 SHA-256 摘要映射。 客户端验证信任数据上的签名后,它会指示 Docker 引擎执行“按摘要拉取”。在拉取期间,引擎使用 SHA-256 校验和作为内容地址从 Azure 容器注册表请求和验证映像清单。
注意
Azure 容器注册表未正式支持 Notary CLI,但与公证服务器 API 兼容。 公证服务器 API 包含在 Docker Desktop 中。 目前,建议使用 Notary 版本 0.6.0。
管理密钥
如推送第一个受信任映像时的 docker push 输出中所述,根密钥是最敏感的。 默认情况下,Docker 客户端将签名密钥存储在以下目录中:
~/.docker/trust/private
通过将根密钥和存储库密钥压缩到存档中并将存档存储在安全位置来备份这些密钥。 例如,在 Bash 中使用此命令:
umask 077; tar -zcvf docker_private_keys_backup.tar.gz ~/.docker/trust/private; umask 022
除了本地生成的根密钥和存储库密钥外,容器注册表会在推送受信任的映像时生成并存储其他几个密钥。 有关 DCT 实现中各种密钥的详细讨论,包括管理指南,请参阅 Docker 文档中 的内容信任管理密钥 。
丢失根密钥
如果您无法访问根密钥,就无法访问该密钥为其标记签名的任何存储库中的已签名标记。 容器注册表无法还原对使用丢失根密钥签名的映像标记的访问。 若要删除注册表的所有信任数据(签名),请禁用并重新为注册表启用 DCT。
警告
在注册表中禁用和重新启用 DCT 会删除注册表中每个存储库中所有已签名标记的所有信任数据。 此操作不可逆。 容器注册表无法恢复已删除的信任数据。 禁用 DCT 不会删除映像本身。
若要为注册表禁用 DCT,请转到 Azure 门户中的注册表。 在“策略”下选择“内容信任”“禁用”“保存”。 系统会警告:你会丢失注册表中的所有签名。 选择“确定”即可永久删除注册表中的所有签名。
相关内容
- 有关 DCT 的详细信息,包括
docker trust命令和 信任委派,请参阅 Docker 中的内容信任。 - 有关生成和推送 Docker 映像时使用 DCT 的示例,请参阅 Azure Pipelines 文档。