如何删除 AWS ECR 未标记和较旧的图像?

已发表: 2022-09-07

Amazon ECR 与 Amazon Elastic Kubernetes Service (Amazon EKS)、Amazon Elastic Container Service (Amazon ECS) 和 AWS Lambda 集成,简化了从开发到生产的工作流程。

Amazon ECR 在高度可扩展且可用的架构中托管映像,使您能够为您的应用程序可靠地部署容器。 删除未标记和旧图像以保持卫生很重要。

今天,应用程序作为微服务运行。 微服务一词只不过是一个容器,它封装了所有代码及其依赖项,因此应用程序可以在任何计算环境中快速可靠地运行。 由于它们的便携性、小尺寸和便利性,集装箱正成为运输现代应用程序的一种选择方法。

容器是根据称为图像的只读模板设计的。 这些图像需要存储在某个地方,以便任何有权使用它们的机器检索它们。

这就是容器注册表的用武之地。不久前,人们使用 DockerHub 来存储这些图像和工件。 但是,如果您使用的是 AWS 云服务,我相信您已经在使用 AWS ECR,它是 DockerHub 的替代品。

AWS ECR 是一个完全托管的容器注册表,提供高性能托管,允许您以公共和私有存储库的形式部署应用程序映像和工件。

每天,多个 AWS 托管的应用程序将数百万个图像/应用程序工件推入/拉出特定的 ECR 存储库。

在本文中,我们将讨论如何清除旧的和过时的 AWS ECR 并保持 ECR 存储库的清洁。

需求:立即删除未标记和旧图像!

清理 ECR 存储库的主要原因是开发卫生。 在任何时候,没有人愿意在他们的 ECR 中保留超过 10 个部署的映像。 也是因为回滚在行业中经常发生,但是从之前的 5 个工件还原变化的回滚是很少见的。

简而言之,任何超过五个部署的图像/工件都是无用的。 贵组织的战略报告可能会发生变化,但我们不建议将其作为最佳实践。

在整个行业中,标记用于指定最稳定的最新图像或最后五个最新图像。 作为软件开发生命周期的一部分,图像会快速生成,并且这些标签会被新图像替换,而旧图像则没有标记且无用。

在这种情况下,图像/工件很大,它还会增加 ECR 的存储费用。 AWS ECR 的定价为“存储在私有或公共存储库中的数据每 GB/月 0.10 美元”。

这个价格对你来说可能看起来很小,但正如他们所说,水滴构成了海洋。 所有这些图像,如果存放时间较长,将会在您的 AWS 发票中增加更高的费用。

建议从您的 ECR 存储库中清除这些旧的和未标记的图像,因为您不需要它们! 简单的! 为什么要保留它并为此付出代价?

手动删除 AWS ECR 图像

方法1:GUI方式!

第 1 步:登录 Amazon Web Services 帐户并前往您要清除的存储库。

第2步:在这里,您可以看到存储库具有最新标签以指定最稳定的版本。 您看到的其他标签可以称为未标记。 要删除,我们只需要选择图像并单击删除即可。

第 3 步:确认删除

方法 2:CLI 方式!

要使用 CLI 删除映像,您需要在您的机器上配置所有 AWS IAM 访问密钥以及授予您访问存储库所需的 IAM 权限。

在这种情况下,我们已经对其进行了配置。 如果您还没有,您可以从 AWS 配置基础指南中进行操作。

如果不确定您是否已在计算机上配置 AWS CLI,请使用以下命令进行验证。

 aws sts get-caller-identity

现在我们已经确认可以使用 AWS CLI,您可以使用以下命令删除未标记的 ECR 映像。

 aws ecr batch-delete-image --repository-name test-ecr-policy --image-ids imageTag=custom-image-6

在这里,我们正在做一些类似于我们在 GUI 中所做的事情。 我们将删除存储库 test-ecr-policy 中标记为 custom-image-6 的图像。

方法 3:脚本方式!

此方法的先决条件是在您运行的机器上配置 AWS 访问密钥。

删除未标记图像的脚本。

 import boto3 client = boto3.client('ecr') response = client.list_images(repositoryName='test-ecr-policy') untaggedImageList = [image for image in response['imageIds'] if image['imageTag'] == 'custom-build-4'] response2 = client.batch_delete_image(repositoryName='aws-test-ecrpolicy', imageIds=untaggedImageList) print(response2)

响应将为您提供已删除图像 ID 的列表,以及失败(如果有)。

删除 ECR 图像的调度方法

如果您是 DevOps 工程师或经常管理 AWS ECR,您将已经知道手动删除这些映像的痛苦。

运行脚本/命令确实使事情变得更容易,但我们确信您会希望有一些东西可以自动删除这些图像而不必担心它们。

好消息,AWS ECR 为您的图像提供生命周期策略,您可以设置它以及时或按计划删除这些图像。 让我们看看怎么做。

方法1:GUI方式!

第 1 步:前往要设置生命周期策略的存储库。 在左侧面板上,您可以看到生命周期策略。 你可以点击它开始。

第 2 步:您可以单击它并创建您的第一条规则。

第 3 步: ECR 允许您在两种情况下删除图像,一种是如果您的图像已指定天数或是否已标记/未标记,并且您只想保留它们,例如 X 天。

让我们看看它是如何完成的。 现在,您可以设置是否要删除未标记的图像,如果它们是一天或更早,或者未标记图像的图像计数超过一个。

根据您的用例选择。 不要忘记; 您可以将这些数字增加到您选择的数字。 保存以触发生命周期规则。

方法 2:CLI 方式!

用于设置生命周期策略的 AWS ECR CLI 命令是put-lifecycle-policy。

让我们看看怎么做。 为此,您必须创建一个列出策略条件的 JSON 文件。 您可以将其命名为 policy.json 或您选择的任何名称。

但在此之前,让我们看一下生命周期策略元素。

 rulePriority (Type: integer, Required: yes):

从低到高的规则顺序。 首先应用优先级为 1 的生命周期策略规则,然后是 2,依此类推。生命周期策略规则必须具有唯一的规则值。

策略规则不需要连续值。 Any-tagged 规则必须具有最高的 rulePriority 并且最后被审查。

 description (Type: string, Required: no):

解释生命周期策略中的规则的用途。

 tagStatus (Type: string, Required: yes):

它检查添加的生命周期策略规则是否指定了图像标签。 标记、未标记或任何都可以。 如果未指定,则评估所有图像。 Tagged 需要一个 tagPrefixList 值。 Untagged 需要省略 tagPrefixList。

 tagPrefixList (Type: list[string], Required: yes, only if tagStatus is set to tagged):

如果“tagStatus”为“tagged”,则您的生命周期策略需要以逗号分隔的图像标签前缀列表。

使用标签前缀 prod,您可以指定标记为 prod、prod1、prod2 等的所有图像。多个标签仅选择具有所有标签的图像。

 countType (Type: string, Required: yes):

如果 countType 为 imageCountMoreThan,则指定 countNumber 以限制存储库中的图像数量。

如果 countType 为 sinceImagePushed 则指定 countUnit 和 countNumber 以限制存储库的图像。

 countUnit (Type: string, Required: yes, only if countType is set to sinceImagePushed):

只有countType为sinceImagePushed时才指定计数单位; 否则,会发生错误。

 countNumber (Type: integer, Required: yes):

仅正整数(0 不是可接受的值)。 如果 countType 为 imageCountMoreThan,则该值为要保留的最大照片数。 使用 sinceImagePushed 作为 countType 确定最大图像年龄。

 type (Type: string, Required: yes):

选择一种操作类型。 可以使用的值是“expire”。

这是我的“policy.json”。

 { "rules": [ { "rulePriority": 1, "description": "Expire images older than 10 days", "selection": { "tagStatus": "untagged", "countType": "sinceImagePushed", "countUnit": "days", "countNumber": 14 }, "action": { "type": "expire" } } ] }

根据贵组织的要求。 “sinceImagePushed”可以替换为“imageCountMoreThan”。

用于设置此策略的 CLI 命令为:

 aws ecr put-lifecycle-policy --repository-name "test-ecr-polict" --lifecycle-policy-text "file://policy.json"

方法 3:脚本方式!

我们将使用 boto3 命令来实现这一点。 我们可以使用相同的“policy.json”来设置它。 下面是使用的代码片段。

 import boto3 client = boto3.client('ecr') response = client.put_lifecycle_policy( registryId='PODES12342', repositoryName='test-ecr-policy', lifecyclePolicyText='plicy.json' ) print(response)

如何跨多个 ECR 存储库应用单个策略?

通常,关于如何在多个存储库中应用相同的策略存在问题。

手动设置策略是一项重复而无聊的任务。

这是一个可用于生产系统的代码片段,用于跨 100 多个存储库应用策略。

 from boto3 import Session,client from os import getenv AWS_ACCESS_KEY_ID = getenv("ACCESSKEY") AWS_SECRET_ACCESS_KEY = getenv("SECRETKEY") session = Session( aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY ) client = client('ecr') response = client.describe_repositories() repositories = response['repositories'] globalLifecyclePolicy = 'put your policy here'' for repo in repositories: repoName = repo['repositoryName'] client.put_lifecycle_policy( repositoryName = repoName,lifecyclePolicyText = globalLifecyclePolicy)

结论

我们可以根据指定的参数轻松构建 ECR 生命周期策略并销毁旧镜像。 AWS 提供大量文档以及生命周期策略示例。

您还可以对标记图像尝试替代策略,例如将条件与图像上传日期匹配。

您还可以探索一些促进您的 AWS 学习的 AWS 关键术语。