使用 Azure CLI 删除 Azure 容器注册表中的容器映像Delete container images in Azure Container Registry using the Azure CLI

要保持 Azure 容器注册表的大小不变,应定期删除过时的映像数据。To maintain the size of your Azure container registry, you should periodically delete stale image data. 尽管部分部署到生产的容器映像可能需要存储更长时间,但通常可更快删除其他映像。While some container images deployed into production may require longer-term storage, others can typically be deleted more quickly. 例如,在自动化生成和测试方案中,可使用从未部署的映像快速填充注册表,并可在完成生成和测试通过后不久即将其清除。For example, in an automated build and test scenario, your registry can quickly fill with images that might never be deployed, and can be purged shortly after completing the build and test pass.

因为可通过多种不同的方式删除映像数据,请务必了解每个删除操作如何影响存储使用情况。Because you can delete image data in several different ways, it's important to understand how each delete operation affects storage usage. 本文介绍几种删除映像数据的方法:This article covers several methods for deleting image data:

  • 删除存储库:删除存储库中的所有映像和所有唯一层。Delete a repository: Deletes all images and all unique layers within the repository.
  • 标记删除:删除映像、其标记、其引用的所有唯一层,以及与其关联的所有其他标记。Delete by tag: Deletes an image, the tag, all unique layers referenced by the image, and all other tags associated with the image.
  • 清单摘要删除:删除映像、该映像引用的所有唯一层,以及与其关联的所有标记。Delete by manifest digest: Deletes an image, all unique layers referenced by the image, and all tags associated with the image.

提供示例脚本是为了自动完成删除操作。Sample scripts are provided to help automate delete operations.

有关这些概念的介绍,请参阅关于注册表、存储库和映像For an introduction to these concepts, see About registries, repositories, and images.

删除存储库Delete repository

删除存储库时,将一并删除存储库中的所有映像,包括所有标记、唯一层和清单。Deleting a repository deletes all of the images in the repository, including all tags, unique layers, and manifests. 删除存储库时,将恢复引用该存储库中唯一层的映像所使用的存储空间。When you delete a repository, you recover the storage space used by the images that reference unique layers in that repository.

以下 Azure CLI 命令会删除“acr-helloworld”存储库,并删除该存储库中的所有标记和清单。The following Azure CLI command deletes the "acr-helloworld" repository and all tags and manifests within the repository. 如果已删除清单所引用的层未由注册表中的其他任何映像引用,则还删除其层数据,从而恢复存储空间。If layers referenced by the deleted manifests are not referenced by any other images in the registry, their layer data is also deleted, recovering the storage space.

 az acr repository delete --name myregistry --repository acr-helloworld

按标记删除Delete by tag

可通过在删除操作中指定存储库名称和标记,删除存储库中的单个映像。You can delete individual images from a repository by specifying the repository name and tag in the delete operation. 如果按标记删除,将恢复该映像中任何唯一层所用的存储空间;唯一层是指不由存储库中的其他任何映像共享的层。When you delete by tag, you recover the storage space used by any unique layers in the image (layers not shared by any other images in the registry).

若要按标记删除,请使用 az acr repository delete,并在 --image 参数中指定映像名称。To delete by tag, use az acr repository delete and specify the image name in the --image parameter. 此操作删除映像的所有唯一层以及与之关联的任何其他标记。All layers unique to the image, and any other tags associated with the image are deleted.

例如,从注册表“myregistry”中删除“acr-helloworld:latest”映像:For example, deleting the "acr-helloworld:latest" image from registry "myregistry":

$ az acr repository delete --name myregistry --image acr-helloworld:latest
This operation will delete the manifest 'sha256:0a2e01852872580b2c2fea9380ff8d7b637d3928783c55beb3f21a6e58d5d108' and all the following images: 'acr-helloworld:latest', 'acr-helloworld:v3'.
Are you sure you want to continue? (y/n): y

Tip

按标记删除不应与删除标记(取消标记)混淆 。Deleting by tag shouldn't be confused with deleting a tag (untagging). 可使用 Azure CLI 命令 az acr repository untag 删除标记。You can delete a tag with the Azure CLI command az acr repository untag. 取消标记映像时不释放任何空间,因为其清单和层数据仍保留在注册表中。No space is freed when you untag an image because its manifest and layer data remain in the registry. 仅删除标记引用本身。Only the tag reference itself is deleted.

按清单摘要删除Delete by manifest digest

清单摘要可与零个、一个或多个标记相关联。A manifest digest can be associated with one, none, or multiple tags. 按摘要删除时,将删除清单引用的所有标记,正如映像的任何唯一层的层数据一样。When you delete by digest, all tags referenced by the manifest are deleted, as is layer data for any layers unique to the image. 不删除共享的层数据。Shared layer data is not deleted.

要按摘要删除,请先列出包含想要删除的映像的存储库清单摘要。To delete by digest, first list the manifest digests for the repository containing the images you wish to delete. 例如:For example:

$ az acr repository show-manifests --name myregistry --repository acr-helloworld
[
  {
    "digest": "sha256:0a2e01852872580b2c2fea9380ff8d7b637d3928783c55beb3f21a6e58d5d108",
    "tags": [
      "latest",
      "v3"
    ],
    "timestamp": "2018-07-12T15:52:00.2075864Z"
  },
  {
    "digest": "sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57",
    "tags": [
      "v2"
    ],
    "timestamp": "2018-07-12T15:50:53.5372468Z"
  }
]

接下来,在 az acr repository delete 命令中指定要删除的摘要。Next, specify the digest you wish to delete in the az acr repository delete command. 该命令的格式如下:The format of the command is:

az acr repository delete --name <acrName> --image <repositoryName>@<digest>

例如,要删除上述输出(具有标记“v2”)中列出的最后一个清单:For example, to delete the last manifest listed in the preceding output (with the tag "v2"):

$ az acr repository delete --name myregistry --image acr-helloworld@sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57
This operation will delete the manifest 'sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57' and all the following images: 'acr-helloworld:v2'.
Are you sure you want to continue? (y/n): y

从注册表中删除 acr-helloworld:v2 映像,正如该映像的任何唯一的层数据一样。The acr-helloworld:v2 image is deleted from the registry, as is any layer data unique to that image. 如果清单与多个标记关联,还删除所有相关联的标记。If a manifest is associated with multiple tags, all associated tags are also deleted.

按时间戳删除摘要Delete digests by timestamp

若要保持存储库或注册表的大小,可能需要定期删除早于某个日期的清单摘要。To maintain the size of a repository or registry, you might need to periodically delete manifest digests older than a certain date.

以下 Azure CLI 命令按升序列出存储库中早于指定时间戳的所有清单摘要。The following Azure CLI command lists all manifest digest in a repository older than a specified timestamp, in ascending order. <acrName><repositoryName> 替换为适合环境的值。Replace <acrName> and <repositoryName> with values appropriate for your environment. 时间戳可能是完整的日期时间表达式,也可能是一个日期,如此示例所示。The timestamp could be a full date-time expression or a date, as in this example.

az acr repository show-manifests --name <acrName> --repository <repositoryName> \
--orderby time_asc -o tsv --query "[?timestamp < '2019-04-05'].[digest, timestamp]"

在确定过时的清单摘要以后,可以运行以下 Bash 脚本,删除早于指定时间戳的清单摘要。After identifying stale manifest digests, you can run the following Bash script to delete manifest digests older than a specified timestamp. 它需要 Azure CLI 和 xargs 。It requires the Azure CLI and xargs. 默认情况下,该脚本不执行任何删除。By default, the script performs no deletion. ENABLE_DELETE 值改为 true 以启用映像删除。Change the ENABLE_DELETE value to true to enable image deletion.

Warning

请谨慎使用以下示例脚本,已删除映像数据是无法恢复的。Use the following sample script with caution--deleted image data is UNRECOVERABLE. 如果系统按清单摘要(而不是映像名称)拉取映像,则不应运行这些脚本。If you have systems that pull images by manifest digest (as opposed to image name), you should not run these scripts. 删除清单摘要后,这些系统即无法从注册表拉取映像。Deleting the manifest digests will prevent those systems from pulling the images from your registry. 不按清单拉取,而是考虑采用建议的最佳做法,即“唯一标记”方案 。Instead of pulling by manifest, consider adopting a unique tagging scheme, a recommended best practice.

#!/bin/bash

# WARNING! This script deletes data!
# Run only if you do not have systems
# that pull images via manifest digest.

# Change to 'true' to enable image delete
ENABLE_DELETE=false

# Modify for your environment
# TIMESTAMP can be a date-time string such as 2019-03-15T17:55:00.
REGISTRY=myregistry
REPOSITORY=myrepository
TIMESTAMP=2019-04-05  

# Delete all images older than specified timestamp.

if [ "$ENABLE_DELETE" = true ]
then
    az acr repository show-manifests --name $REGISTRY --repository $REPOSITORY \
    --orderby time_asc --query "[?timestamp < '$TIMESTAMP'].digest" -o tsv \
    | xargs -I% az acr repository delete --name $REGISTRY --image $REPOSITORY@% --yes
else
    echo "No data deleted."
    echo "Set ENABLE_DELETE=true to enable deletion of these images in $REPOSITORY:"
    az acr repository show-manifests --name $REGISTRY --repository $REPOSITORY \
   --orderby time_asc --query "[?timestamp < '$TIMESTAMP'].[digest, timestamp]" -o tsv
fi

删除无标记的映像Delete untagged images

清单摘要部分中所述,使用现有标记推送已修改的映像时,会取消标记之前推送的映像,从而导致孤立(或“无关联”)的映像 。As mentioned in the Manifest digest section, pushing a modified image using an existing tag untags the previously pushed image, resulting in an orphaned (or "dangling") image. 之前推送的映像的清单及其层数据仍保留在注册表中。The previously pushed image's manifest--and its layer data--remains in the registry. 请注意以下事件序列:Consider the following sequence of events:

  1. 推送具有标记 latest 的映像 acr-helloworld:docker push myregistry.azurecr.cn/acr-helloworld:latest Push image acr-helloworld with tag latest: docker push myregistry.azurecr.cn/acr-helloworld:latest

  2. 检查存储库 acr-helloworld 的清单 :Check manifests for repository acr-helloworld:

    $ az acr repository show-manifests --name myregistry --repository acr-helloworld
    [
     {
       "digest": "sha256:d2bdc0c22d78cde155f53b4092111d7e13fe28ebf87a945f94b19c248000ceec",
       "tags": [
         "latest"
       ],
       "timestamp": "2018-07-11T21:32:21.1400513Z"
     }
    ]
    
  3. 修改 acr-helloworld Dockerfile Modify acr-helloworld Dockerfile

  4. 推送具有标记 latest 的映像 acr-helloworld:docker push myregistry.azurecr.cn/acr-helloworld:latest Push image acr-helloworld with tag latest: docker push myregistry.azurecr.cn/acr-helloworld:latest

  5. 检查存储库 acr-helloworld 的清单 :Check manifests for repository acr-helloworld:

    $ az acr repository show-manifests --name myregistry --repository acr-helloworld
    [
     {
       "digest": "sha256:7ca0e0ae50c95155dbb0e380f37d7471e98d2232ed9e31eece9f9fb9078f2728",
       "tags": [
         "latest"
       ],
       "timestamp": "2018-07-11T21:38:35.9170967Z"
     },
     {
       "digest": "sha256:d2bdc0c22d78cde155f53b4092111d7e13fe28ebf87a945f94b19c248000ceec",
       "tags": [],
       "timestamp": "2018-07-11T21:32:21.1400513Z"
     }
    ]
    

正如上一步骤的输出中所示,现在存在一个 "tags" 属性为空列表的孤立清单。As you can see in the output of the last step in the sequence, there is now an orphaned manifest whose "tags" property is an empty list. 此清单仍与其引用的任何唯一层数据一起位于注册表中。This manifest still exists within the registry, along with any unique layer data that it references. 要删除此类孤立映像及其层数据,必须按清单摘要删除 。To delete such orphaned images and their layer data, you must delete by manifest digest.

删除所有无标记的映像Delete all untagged images

可使用以下 Azure CLI 命令列出存储库中所有无标记的映像。You can list all untagged images in your repository using the following Azure CLI command. <acrName><repositoryName> 替换为适合环境的值。Replace <acrName> and <repositoryName> with values appropriate for your environment.

az acr repository show-manifests --name <acrName> --repository <repositoryName> --query "[?tags[0]==null].digest"

在脚本中使用此命令,可以删除存储库中所有未标记的映像。Using this command in a script, you can delete all untagged images in a repository.

Warning

请谨慎使用以下示例脚本,已删除映像数据是无法恢复的。Use the following sample scripts with caution--deleted image data is UNRECOVERABLE. 如果系统按清单摘要(而不是映像名称)拉取映像,则不应运行这些脚本。If you have systems that pull images by manifest digest (as opposed to image name), you should not run these scripts. 删除无标的记映像后,这些系统即无法从注册表拉取映像。Deleting untagged images will prevent those systems from pulling the images from your registry. 不按清单拉取,而是考虑采用建议的最佳做法,即“唯一标记”方案 。Instead of pulling by manifest, consider adopting a unique tagging scheme, a recommended best practice.

Bash 中的 Azure CLIAzure CLI in Bash

以下 Bash 脚本会删除存储库中所有无标记的映像。The following Bash script deletes all untagged images from a repository. 它需要 Azure CLI 和 xargs 。It requires the Azure CLI and xargs. 默认情况下,该脚本不执行任何删除。By default, the script performs no deletion. ENABLE_DELETE 值改为 true 以启用映像删除。Change the ENABLE_DELETE value to true to enable image deletion.

#!/bin/bash

# WARNING! This script deletes data!
# Run only if you do not have systems
# that pull images via manifest digest.

# Change to 'true' to enable image delete
ENABLE_DELETE=false

# Modify for your environment
REGISTRY=myregistry
REPOSITORY=myrepository

# Delete all untagged (orphaned) images
if [ "$ENABLE_DELETE" = true ]
then
    az acr repository show-manifests --name $REGISTRY --repository $REPOSITORY  --query "[?tags[0]==null].digest" -o tsv \
    | xargs -I% az acr repository delete --name $REGISTRY --image $REPOSITORY@% --yes
else
    echo "No data deleted."
    echo "Set ENABLE_DELETE=true to enable image deletion of these images in $REPOSITORY:"
    az acr repository show-manifests --name $REGISTRY --repository $REPOSITORY --query "[?tags[0]==null]" -o tsv
fi

PowerShell 中的 Azure CLIAzure CLI in PowerShell

以下 PowerShell 脚本会删除存储库中所有无标记的映像。The following PowerShell script deletes all untagged images from a repository. 它需要 PowerShell 和 Azure CLI。It requires PowerShell and the Azure CLI. 默认情况下,该脚本不执行任何删除。By default, the script performs no deletion. $enableDelete 值改为 $TRUE 以启用映像删除。Change the $enableDelete value to $TRUE to enable image deletion.

# WARNING! This script deletes data!
# Run only if you do not have systems
# that pull images via manifest digest.

# Change to '$TRUE' to enable image delete
$enableDelete = $FALSE

# Modify for your environment
$registry = "myregistry"
$repository = "myrepository"

if ($enableDelete) {
    az acr repository show-manifests --name $registry --repository $repository --query "[?tags[0]==null].digest" -o tsv `
    | %{ az acr repository delete --name $registry --image $repository@$_ --yes }
} else {
    Write-Host "No data deleted."
    Write-Host "Set `$enableDelete = `$TRUE to enable image deletion."
    az acr repository show-manifests --name $registry --repository $repository --query "[?tags[0]==null]" -o tsv
}

后续步骤Next steps

要详细了解 Azure 容器注册表中的映像存储,请参阅 Azure 容器注册表中的容器映像存储For more information about image storage in Azure Container Registry see Container image storage in Azure Container Registry.