常见问题解答 - Azure 容器注册表

本文解答有关 Azure 容器注册表的常见问题和已知问题。

有关注册表故障排除指南,请参阅:

资源管理

是否可以使用 Azure 资源管理器 (ARM) 模板创建 Azure 容器注册表(ACR) ?

是的。 这里提供了模板,可以用来创建注册表。

ACR 中是否提供对映像的安全漏洞扫描?

是的。 请参阅 Microsoft Defender for Cloud 中的文档。

如何使用 Azure 容器注册表配置 Kubernetes?

请参阅 Kubernetes 的文档以及适用于 Azure Kubernetes 服务的步骤。

如何获取容器注册表的管理员凭据?

重要

管理员用户帐户专门用于单个用户访问注册表,主要用于测试目的。 建议不要与多个用户共享管理员帐户凭据。 建议用户和服务主体在无外设方案中使用单个标识。 请参阅身份验证概述

在获取管理员凭据之前,请确保已启用注册表的管理员用户。

使用 Azure CLI 获取凭据:

az acr credential show -n myRegistry

使用 Azure PowerShell:

Invoke-AzureRmResourceAction -Action listCredentials -ResourceType Microsoft.ContainerRegistry/registries -ResourceGroupName myResourceGroup -ResourceName myRegistry

如何在资源管理器模板中获取管理员凭据?

重要

管理员用户帐户专门用于单个用户访问注册表,主要用于测试目的。 建议不要与多个用户共享管理员帐户凭据。 建议用户和服务主体在无外设方案中使用单个标识。 请参阅身份验证概述

在获取管理员凭据之前,请确保已启用注册表的管理员用户。

获取第一个密码:

{
    "password": "[listCredentials(resourceId('Microsoft.ContainerRegistry/registries', 'myRegistry'), '2017-10-01').passwords[0].value]"
}

获取第二个密码:

{
    "password": "[listCredentials(resourceId('Microsoft.ContainerRegistry/registries', 'myRegistry'), '2017-10-01').passwords[1].value]"
}

尽管使用 Azure CLI 或 Azure PowerShell 删除了复制,但删除复制操作仍然失败并出现“已禁止”状态

当用户对注册表拥有 Container Registry Contributor and Data Access Configuration Administrator 权限(授予副本删除权限)但对订阅没有读取者级权限时(需要通过门户删除副本)时,会出现此错误。 若要解决此问题,请向用户分配对订阅的“读取者”权限:

az role assignment create --role "Reader" --assignee user@contoso.com --scope /subscriptions/<subscription_id> 

防火墙规则已成功更新,但不生效

传播防火墙规则更改需要一段时间。 更改防火墙设置后,请等待几分钟,然后验证此更改。

注册表操作

如何访问 Docker 注册表 HTTP API V2?

ACR 支持 Docker 注册表 HTTP API V2。 可通过 https://<your registry login server>/v2/ 访问 API。 示例: https://mycontainerregistry.azurecr.cn/v2/

如何删除不由存储库中的任何标记引用的所有清单?

如果你使用的是 bash:

az acr manifest list-metadata --name myRepository --registry myRegistry --query "[?tags[0]==null].digest" --output tsv  | xargs -I% az acr repository delete --name myRegistry ---image myRepository@%

对于 PowerShell:

az acr manifest list-metadata --name myRepository --repository myRegistry --query "[?tags[0]==null].digest" --output tsv | %{ az acr repository delete --name myRegistry --image myRepository@$_ }

备注

在 delete 命令中添加 -y 可跳过确认。

有关详细信息,请参阅删除 Azure 容器注册表中的容器映像

为何删除映像后,注册表配额用量未减少?

如果其他容器映像仍在引用基础层,则可能会发生这种情况。 如果删除不带引用的映像,则注册表用量在几分钟后即会更新。

如何验证存储配额更改?

使用以下 Docker 文件创建使用 1GB 层的映像。 这可以确保该映像的某个层不会由注册表中的任何其他映像共享。

FROM alpine
RUN dd if=/dev/urandom of=1GB.bin  bs=32M  count=32
RUN ls -lh 1GB.bin

使用 Docker CLI 生成映像并将其推送到注册表。

docker build -t myregistry.azurecr.cn/1gb:latest .
docker push myregistry.azurecr.cn/1gb:latest

在 Azure 门户中应该可以看到存储用量已增加,或者可以使用 CLI 查询用量。

az acr show-usage -n myregistry

使用 Azure CLI 或门户删除映像,并在几分钟后检查更新的用量。

az acr repository delete -n myregistry --image 1gb

在容器中运行 CLI 时如何对注册表进行身份验证?

需要通过装载 Docker 套接字来运行 Azure CLI 容器:

docker run -it -v /var/run/docker.sock:/var/run/docker.sock azuresdk/azure-cli-python:dev

在容器中安装 docker

apk --update add docker

然后对注册表进行身份验证:

az acr login -n MyRegistry

如何启用 TLS 1.2?

使用任何最近发布的 Docker 客户端(18.03.0 和更高版本)启用 TLS 1.2。

重要

从 2020 年 1 月 13 日开始,Azure 容器注册表将要求服务器和应用程序的所有安全连接都使用 TLS 1.2。 对 TLS 1.0 和 1.1 的支持将停用。

Azure 容器注册表是否支持内容信任?

支持,可以在 Azure 容器注册表中使用受信任映像,因为 Docker Notary 已集成且可以启用。 有关详细信息,请参阅 Azure 容器注册表中的内容信任

指纹文件位于何处?

~/.docker/trust/tuf/myregistry.azurecr.cn/myrepository/metadata 下:

  • 所有角色(委托角色除外)的公钥和证书都存储在 root.json 中。
  • 委托角色的公钥和证书将存储在其父角色的 JSON 文件(例如,targets.json 角色的 targets/releases)中。

建议在 Docker 和 Notary 客户端完成总体 TUF 验证后验证这些公钥和证书。

在无权管理注册表资源的情况下如何授予提取或推送映像的访问权限?

ACR 支持提供不同权限级别的 内置角色 。 具体而言,AcrPullAcrPush 角色允许用户在无权管理 Azure 中的注册表资源的情况下提取和/或推送映像。

  • Azure 门户:“注册表”->“访问控制(IAM)”->“添加”(对于“角色”,请选择 AcrPullAcrPush)。

  • Azure CLI:运行以下命令找到注册表的资源 ID:

    az acr show -n myRegistry
    

    然后,可将 AcrPullAcrPush 角色分配给用户(以下示例使用 AcrPull):

    az role assignment create --scope resource_id --role AcrPull --assignee user@example.com
    

    或者,将角色分配到由应用程序 ID 标识的服务主体:

    az role assignment create --scope resource_id --role AcrPull --assignee 00000000-0000-0000-0000-000000000000
    

然后,被分配者可以验证和访问注册表中的映像。

  • 对注册表进行身份验证:

    az acr login -n myRegistry 
    
  • 列出存储库:

    az acr repository list -n myRegistry
    
  • 提取映像:

    docker pull myregistry.azurecr.cn/hello-world
    

如果只使用 AcrPullAcrPush 角色,则被分配者将无权管理 Azure 中的注册表资源。 例如,az acr listaz acr show -n myRegistry 不会显示注册表。

如何为注册表启用自动映像隔离?

映像隔离目前是 ACR 的预览版功能。 可以启用注册表的隔离模式,使普通用户只能看到已成功通过安全扫描的映像。 有关详细信息,请参阅 ACR GitHub 存储库

如何实现匿名提取访问?

有关详细信息,请参阅使注册表内容公用

如何将不可分发层推送到注册表?

清单中的不可分发层包含一个 URL 参数,可以通过该参数提取内容。 启用不可分发层推送的一些可能用例适用于:网络受限制的注册表、具有受限访问权限的气隙注册表,或没有 Internet 连接的注册表。

例如,如果设置了网络安全组(NSG)规则,以便 VM 只能从 Azure 容器注册表拉取映像,则 Docker 将为外部/不可分发层拉取故障。 例如,Windows Server Core 映像在其清单中会包含对 Azure 容器注册表的外部层引用,所以在此情况下将无法拉取。

若要启用不可分发层的推送,请执行以下操作:

  1. 编辑 daemon.json 文件,该文件在 Linux 主机上位于 /etc/docker/ 中,在 Windows Server 上位于 C:\ProgramData\docker\config\daemon.json 中。 假设文件之前为空,请添加以下内容:

    {
      "allow-nondistributable-artifacts": ["myregistry.azurecr.cn"]
    }
    

    备注

    值是注册表地址的数组,各个地址之间以逗号分隔。

  2. 保存并退出该文件。

  3. 重启 Docker。

将映像推送到列表中的注册表时,它们的不可分发层会被推送到注册表。

警告

不可分发项目通常在其分发和共享方式与位置方面存在限制。 请仅在将项目推送到专用注册表时使用此功能。 请确保遵守与重新分发不可分发项目相关的任何条款。

诊断和运行状况检查

使用 `az acr check-health` 检查运行状况

若要排查常见的环境和注册表问题,请参阅检查 Azure 容器注册表的运行状况

Docker pull 失败,出现错误:net/http: 等待连接时取消了请求(等待标头时超过了 Client.Timeout)

  • 如果此错误是暂时性的,则重试后,提取将会成功。
  • 如果 docker pull 连续失败,则原因可能是 Docker 守护程序出现了问题。 重启 Docker 守护程序通常可以缓解此问题。
  • 如果重启 Docker 守护程序后仍旧出现此问题,则原因可能是计算机上出现了一些网络连接问题。 若要检查计算机上的常规网络是否正常,请运行以下命令来测试终结点连接。 包含此连接性检查命令的最低 az acr 版本为 2.2.9。 如果使用早期的版本,请升级 Azure CLI。
az acr check-health -n myRegistry
  • 始终应该对所有 Docker 客户端操作使用重试机制。

Docker 提取速度缓慢

使用速度工具来测试计算机网络下载速度。 如果计算机网络速度缓慢,请考虑在注册表所在的同一区域中使用 Azure 虚拟机(VM),以提高网络速度。

Docker 推送速度缓慢

使用速度工具来测试计算机网络上传速度。 如果计算机网络速度较慢,请考虑使用与注册表位于同一区域的 Azure VM 以提高网络速度。

Docker 推送成功,但 Docker 提取失败并出现错误:未授权: 需要身份验证

默认启用 --signature-verification 的 Red Hat 版 Docker 守护程序可能会发生此错误。 可以运行以下命令来检查 Red Hat Enterprise Linux (RHEL) 或 Fedora 的 Docker 守护程序选项:

grep OPTIONS /etc/sysconfig/docker

例如,Fedora 28 服务器使用以下 Docker 守护程序选项:

OPTIONS='--selinux-enabled --log-driver=journald --live-restore'

如果缺少 --signature-verification=falsedocker pull 将会失败并出现如下所示的错误:

Trying to pull repository myregistry.azurecr.cn/myimage ...
unauthorized: authentication required

若要解决该错误:

  1. 将选项 --signature-verification=false 添加到 Docker 守护程序配置文件 /etc/sysconfig/docker。 例如:

    OPTIONS='--selinux-enabled --log-driver=journald --live-restore --signature-verification=false'

  2. 运行以下命令重启 Docker 守护程序服务:

    sudo systemctl restart docker.service
    

运行 --signature-verification 可以找到 man dockerd 的详细信息。

az acr login 成功,但 Docker 失败并出现错误:未授权: 需要身份验证

请确保使用全小写的服务器 URL(例如 docker push myregistry.azurecr.cn/myimage:latest),即使注册表资源名称是大写的或大小写混合的(例如 myRegistry)。

启用和获取 Docker 守护程序的调试日志

使用 dockerd 选项启动 debug。 首先创建 Docker 守护程序配置文件 (/etc/docker/daemon.json)(如果不存在),并添加 debug 选项:

{    
    "debug": true    
}

然后重启守护程序。 例如,对于 Ubuntu 14.04:

sudo service docker restart

可以在 Docker 文档中找到详细信息。

  • 日志可能在不同的位置生成,具体取决于所用的系统。 例如,对于 Ubuntu 14.04,日志位置为 /var/log/upstart/docker.log
    有关详细信息,请参阅 Docker 文档

  • 对于用于 Windows 的 Docker,将在 %LOCALAPPDATA%/docker/ 下生成日志。 但是,此位置不一定包含所有调试信息。

    若要访问完整的守护程序日志,可能需要执行一些额外的步骤:

    docker run --privileged -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v /usr/local/bin/docker:/usr/local/bin/docker alpine sh
    
    docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host alpine /bin/sh
    chroot /host
    

    现在,可以访问运行 dockerd 的 VM 的所有文件。 日志位于 /var/log/docker.log

新用户权限在更新后可能不会立即生效

向服务主体授予新权限(新角色)时,更改可能不会立即生效。 有两种可能的原因:

  • Microsoft Entra 角色分配延迟。 通常分配速度很快,但由于传播延迟,此过程可能需要几分钟时间。

  • ACR 令牌服务器上的权限延迟最长可能需要 10 分钟。 若要缓解此情况,可以运行 docker logout,并在 1 分钟后使用同一用户的身份再次进行身份验证:

    docker logout myregistry.azurecr.cn
    docker login myregistry.azurecr.cn
    

目前,ACR 不支持用户删除宿主复制。 解决方法是在模板中包括宿主复制创建指令,但通过添加如下所示的 "condition": false 来跳过宿主复制的创建:

{
    "name": "[concat(parameters('acrName'), '/', parameters('location'))]",
    "condition": false,
    "type": "Microsoft.ContainerRegistry/registries/replications",
    "apiVersion": "2017-10-01",
    "location": "[parameters('location')]",
    "properties": {},
    "dependsOn": [
        "[concat('Microsoft.ContainerRegistry/registries/', parameters('acrName'))]"
     ]
},

未在 REST API 调用中以正确的格式指定身份验证信息

你可能会遇到 InvalidAuthenticationInfo 错误,尤其是结合选项 curl-L,跟踪重定向)使用 --location 工具时。 例如,结合 curl 选项和基本身份验证使用 -L 提取 Blob:

curl -L -H "Authorization: basic $credential" https://$registry.azurecr.cn/v2/$repository/blobs/$digest

可能会生成以下响应:

<?xml version="1.0" encoding="utf-8"?>
<Error><Code>InvalidAuthenticationInfo</Code><Message>Authentication information is not given in the correct format. Check the value of Authorization header.
RequestId:00000000-0000-0000-0000-000000000000
Time:2019-01-01T00:00:00.0000000Z</Message></Error>

根本原因是某些 curl 实现使用原始请求中的标头跟踪重定向。

若要解决此问题,需要在不使用标头的情况下手动跟踪重定向。 使用 -D -curl 选项输出响应标头,然后提取 Location 标头:

REDIRECT_URL=$(curl -s -D - -H "Authorization: basic $credential" https://$registry.azurecr.cn/v2/$repository/blobs/$digest | grep "^Location: " | cut -d " " -f2 | tr -d '\r')
curl $REDIRECT_URL

为何 Azure 门户不列出我的所有存储库或标记?

如果使用 Microsoft Edge/IE 浏览器,则最多可以查看 100 个存储库或标记。 如果注册表中的存储库或标记超过 100 个,则我们建议使用 Firefox 或 Chrome 浏览器将其列出。

为何 Azure 门户无法提取存储库或标记?

浏览器可能无法向服务器发送请求来提取存储库或标记。 可能有各种原因,例如:

  • 缺少网络连接
  • 防火墙
  • 从公共网络使用门户,而注册表仅允许专用访问
  • 广告阻止程序
  • 域名服务器 (DNS) 错误

请与网络管理员联系,或者检查网络配置和连接性。 尝试使用 Azure CLI 来运行 az acr check-health -n yourRegistry,以便检查环境是否能够连接到容器注册表。 另外,也可尝试在浏览器中使用 incognito 或专用会话,避免使用任何过时的浏览器缓存或 Cookie。

为什么拉取或推送请求失败,并出现不受允许的操作?

以下是一些可能出现不允许进行操作的情况:

  • 不再支持经典注册表。 请使用 az acr update或 Azure 门户升级到受支持的服务层
  • 映像或存储库可能已锁定,因此无法进行删除或更新。 可以使用 az acr repository show 命令查看当前属性。
  • 如果映像处于隔离状态,则会禁用某些操作。 详细了解隔离
  • 注册表可能已达到其存储限制

存储库格式无效或不受支持

如果在存储库操作中指定存储库名称时出现“存储库格式不受支持”、“无效格式”或“请求的数据不存在”等错误,请检查名称的拼写和大小写。 有效的存储库名称只能包含小写字母数字字符、句点、短划线、下划线和正斜杠。

如何在 Windows 上收集 HTTP 跟踪?

先决条件

Windows 容器

将 Docker 代理配置为 127.0.0.1:8888

Linux 容器

查找 Docker VM 虚拟交换机的 IP:

(Get-NetIPAddress -InterfaceAlias "*Docker*" -AddressFamily IPv4).IPAddress

将 Docker 代理配置为上一命令的输出和端口 8888(例如 10.0.75.1:8888)

任务

如何批量取消运行?

以下命令可取消指定的注册表中所有正在运行的任务。

az acr task list-runs -r $myregistry --run-status Running --query '[].runId' -o tsv \
| xargs -I% az acr task cancel-run -r $myregistry --run-id %

如何在 az acr build 命令中包含 .git 文件夹?

如果将本地源文件夹传递到 az acr build 命令,则默认会从上传的包中排除 .git 文件夹。 可以使用以下设置创建 .dockerignore 文件。 这会告知命令还原已上传包中 .git 下的所有文件。

!.git/**

此设置也适用于 az acr run 命令。

任务是否支持用于源触发器的 GitLab?

我们目前不支持用于源触发器的 GitLab。

任务支持什么 git 存储库管理服务?

Git 服务 源上下文 手动生成 通过“提交”触发器自动生成
GitHub https://github.com/user/myapp-repo.git#mybranch:myfolder
Azure Repos https://dev.azure.com/user/myproject/_git/myapp-repo#mybranch:myfolder
GitLab https://gitlab.com/user/myapp-repo.git#mybranch:myfolder
位桶 https://user@bitbucket.org/user/mayapp-repo.git#mybranch:myfolder

运行错误消息故障排除操作

错误消息 故障排除指南
未为 VM 配置任何访问权限,因此未找到订阅 如果在 ACR 任务中使用 az login --identity,则可能发生这种情况。 这是暂时性错误,在托管标识的角色分配无法传播时发生。 请等几秒钟,然后重试即可。

CI/CD 集成

启用 ACR 的 Azure 内置策略将如何阻止启用管理员凭据?

将以下 Azure 内置策略设置为相应的策略状态时,将阻止用户在其注册表上启用管理员用户。

Azure 内置策略 策略状态 管理员状态
配置容器注册表以禁用本地管理员帐户。 修改 禁用
容器注册表应禁用本地管理员帐户。 拒绝 禁用
容器注册表应禁用本地管理员帐户。 审核 不符合

后续步骤