宣布收集 CDK 垃圾

作者: Kaizen Conroy, 亚当凯勒 |

亚马逊云科技云开发套件 (CDK) 是一个开源框架,使开发人员能够使用熟悉的编程语言定义云基础设施。此外,CDK 还提供更高级别的抽象(结构),这降低了在亚马逊云科技上构建时定义和集成亚马逊云科技服务所需的复杂性。CDK 还提供 CDK 资产等核心功能,使用户能够将应用程序资产捆绑到他们的 CDK 应用程序中。这些资产可以是本地文件 (main.py)、目录 (python_app/) 或 Docker 镜像 (Dockerfile)。CDK 资产存储在 CDK 引导期间创建的 Amazon Simple Storage Service (Amazon S3) 存储桶或 Amazon Elastic Container Registry (Amazon ECR) 存储库中。

对于大规模利用资产的 CDK 开发人员来说,随着时间的推移,他们可能会注意到引导的存储桶或存储库积累了旧的或未使用的数据。如果用户想自己清理这些数据,CDK 没有提供明确的方法来确定哪些数据可以安全删除。为了解决这个问题,我们很高兴地宣布 CDK 垃圾回收预览版上线,这是 CDK 的一项新功能,可自动删除您引导的 Amazon S3 存储桶和 Amazon ECR 存储库中的旧资产,为用户节省时间和金钱。此功能从亚马逊云科技 CDK 版本 2.165.0 开始可用。

我们预计 CDK 垃圾回收能够帮助亚马逊云科技 CDK 客户节省与使用该产品相关的存储成本,同时不会影响客户使用 CDK 的方式。

快速入门

CDK 垃圾回收以名为 gc 的 CDK CLI 命令的形式公开。要在默认配置中使用 CDK 垃圾回收,请在 CDK 应用程序的终端上运行以下命令。

cdk gc --unstable=gc

--unstable 标志旨在确认 CDK 垃圾回收处于预览模式。这表明该功能的范围和 API 可能仍会发生变化,但除此之外,该功能通常已准备就绪并完全支持生产。

草率排练

CDK 垃圾回收在环境层面运行,因此它将尝试删除您调用的亚马逊云科技账户/区域中的隔离资产。出于本演练的目的,您将使用自定义限定符重新启动环境,这样就不会在准备就绪之前删除隔离的资产。

cdk bootstrap --qualifier=abcdef --toolkit-stack-name=CDKToolkitDemo

现在,你有一个名为 CDKToolkitDemo 的新引导模板以及与之相关的引导资源。接下来,设置一个同时包含 Amazon S3 和 Amazon ECR 资产的 CDK 应用程序:

mkdir garbage-collection-demo && cd garbage-collection-demo
cdk init -l typescript app

下一步是将现有代码替换为以下 CDK 堆栈 lib/garbage-collection-demo-stack.ts

import * as path from 'path';
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class GarbageCollectionDemoStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const fn1 = new lambda.Function(this, 'my-function-s3', {
    code: lambda.Code.fromAsset(path.join(__dirname, '..', 'lambda')),
    runtime: lambda.Runtime.NODEJS_LATEST,
    handler: 'index.handler',
    });

    const fn2 = new lambda.Function(this, 'my-function-ecr', {
    code: lambda.Code.fromAssetImage(path.join(__dirname, '..', 'docker')),
    runtime: lambda.Runtime.FROM_IMAGE,
    handler: lambda.Handler.FROM_IMAGE,
    });
  }
}

这将创建两个 Amazon Lambda 函数,一个使用 Amazon S3 资产作为其源代码,另一个使用 Amazon ECR 映像作为其源代码。您需要添加我们的 CDK 应用程序中引用的资产。添加一个简单的 Lambda 函数 lambda/index.js

exports.handler = async function(event) {
  const response = require('./response.json');
  return response;
};

然后添加一个简单的 Docker 镜像 docker/Dockerfile

FROM public.ecr.aws/docker/library/alpine:latest

现在,您可以运行 cdk deploy 并在您的亚马逊云科技账户中设置您的初始 CDK 应用程序。

cdk deploy \
  --toolkit-stack-name=CDKToolkitDemo \
  --context='@aws-cdk/core:bootstrapQualifier=abcdef'

此时,您可以检查以确保资产已正确添加到引导的 Amazon S3 存储桶和 Amazon ECR 存储库中:

s3 存储桶中的 cdk 资产

在初始亚马逊云科技 CDK 部署之后,引导的 Amazon S3 存储桶中存在两个对象。

在初始 AWS CDK 部署后,启动的亚马逊 ECR 存储库中存在1 个映像。

在初始部署亚马逊云科技 CDK 之后,引导的 Amazon ECR 存储库中存在一个镜像。

输出显示您在两个引导资源中都有预期的数据。Amazon S3 存储桶还存储您运行 cdk 部署时生成的 Amazon CloudFormation 模板的 json 文件。

现在,您可以通过更新这两个资产来模拟典型的 CDK 开发周期。对位于以下位置的 Amazon S3 资产添加一点小改动 lambda/index.js

exports.handler = async function(event) {
  console.log('hello world');
  const response = require('./response.json');
  return response;
};

然后在 docker/Dockerfile

FROM public.ecr.aws/docker/library/alpine:latest
CMD echo 'Hello World'

您现在可以再次运行 cdk deploy,并且这两个资产都应使用新的哈希值重新上传。

在第二次 AWS CDK 部署之后,引导的 Amazon S3 存储桶中存在 4 个对象。

在第二次亚马逊云科技 CDK 部署之后,引导的 Amazon S3 存储桶中存在四个对象。

在第二次 AWS CDK 部署之后,引导的 Amazon ECR 存储库中存在 2 个映像。

在第二次亚马逊云科技 CDK 部署之后,引导的 Amazon ECR 存储库中存在两个镜像。

该输出确认一切都符合预期,并且已添加新资产。由于您正在使用新的引导资源,因此您仍然可以分辨出哪些资源当前处于隔离状态,哪些不是。目前,Amazon CloudFormation 中只引用了前缀为 50f409b9 的压缩文件,而在 Amazon ECR 中,只引用了前缀为 a5801b5b 的图像。这意味着所有其他资产(Amazon S3 中的 3 个对象和 Amazon ECR 中的 1 个对象)都是隔离的,可以删除。

需要注意的一点是,Amazon S3 中的其他文件不是您的本地资产——这些是 Amazon CloudFormation 模板,在发送到 Amazon CloudFormation 之前,作为中间步骤上传到 Amazon S3。它们在被复制后就不再需要了,是通过 CDK 垃圾回收进行删除的理想选择。

这就是 CDK 垃圾回收的用武之地。使用正确的参数,您可以清理孤立的对象,同时不会干扰正在使用的资产。

cdk gc \
  --unstable=gc \
  --bootstrap-stack-name=CDKToolkitDemo \
  --rollback-buffer-days=0 \
  --created-buffer-days=0

由于您想立即删除资产,而不是将其标记为以后删除,因此请将 rollback-buffer-days 设置为 0。您还想删除刚刚创建的资产,因此请务必将 created-buffer-days 也设置为 0。创建的缓冲区天数的默认值为 1。

 ⏳ Garbage Collecting environment aws://912331974472/us-east-1...
Found 3 objects to delete based off of the following criteria:
- objects have been isolated for > 0 days
- objects were created > 0 days ago

Delete this batch (yes/no/delete-all)? 

CDK 垃圾回收发现有三项资产将从 Amazon S3 中删除,这是意料之中的。它会提示您验证是否要删除,然后输入 yes。然后你会得到这样的回复:

[100.00%] 4 files scanned: 0 assets (0.00 MiB) tagged, 3 assets (0.02 MiB) deleted.

其次是:

Found 1 image to delete based off of the following criteria:
- images have been isolated for > 0 days
- images were created > 0 days ago

Delete this batch (yes/no/delete-all)?

再一次,这对于 Amazon ECR 来说是意料之中的,因此您再次输入 "是"。然后你会得到回应:

[100.00%] 2 files scanned: 0 assets (0.00 MiB) tagged, 1 assets (3.90 MiB) deleted.

此时,CDK 垃圾收集已完成。

详情

CDK 垃圾回收提供了一些参数,可帮助您根据特定场景自定义体验。这些选项可帮助您确定希望垃圾收集的积极程度。

  • rollback-buffer-days:这是资产在符合删除条件之前必须标记为隔离的天数。
  • created-buffer-days:这是资产在符合删除资格之前必须存活的天数。

当您不使用 cdk deploy 而是使用仅在模板上运行的部署方法(例如管道)时,应考虑回滚缓冲天数。如果您的管道可以在不涉及 CDK CLI 的情况下进行回滚,则此参数将有助于确保资产不会过早删除。使用时,cdk gc 不会删除未使用的对象,而是使用当前日期对其进行标记。后续运行 cdk gc 将检查此标签,只有在标记时间超过指定的缓冲天数后才删除该资产。

如果您想对最近上传的资产更加安全,则应考虑创建的缓冲天数。使用时,cdk gc 过滤掉所有未保存该天数的资产。请注意,这可能不包括已在多个 CDK 应用程序中共享的资产。CDK 重复使用相同的资产,并且最近部署的 CDK 应用程序可能引用了之前上传的资产。

例如,如果您想确保仅删除一个月以上且已隔离一周的资产,则可以指定:

cdk gc --unstable --rollback-buffer-days=7 --created-buffer-days=30.
资产接受垃圾回收审计时的决策流程图。

资产接受垃圾回收审计时的决策流程图。

CDK 垃圾收集的局限性

在 CDK 垃圾回收期间,我们会收集所有堆栈模板以查看正在使用哪些资产。如果垃圾回收在资产上传和堆栈部署之间运行,则它可能不会提取最新的堆栈部署,但会提取最新的资产。在这种情况下,CDK 垃圾回收可能会删除这些资产。

我们建议在运行 CDK 垃圾回收时不要部署堆栈。如果这是不可避免的,则设置 --created-buffer-days 会有所帮助,因为垃圾回收将避免删除最近创建的资产。最后,如果您确实遇到部署失败的情况,缓解措施是重新部署,因为资产上传步骤将能够重新上传丢失的资产。实际上,这种竞争条件仅适用于特定的边缘情况,不太可能发生。但是,我们正在研究一种存储 CDK 资产的新方法,以降低出现这种竞争条件的风险。本期正在跟踪这项工作。

结论

CDK 垃圾回收帮助用户管理其亚马逊云科技账户中未使用的 CDK 资产的生命周期。随着用户继续使用 CDK 进行扩展,诸如 CDK 垃圾收集之类的工具将在维护清洁、高效和具有成本效益的云环境方面发挥至关重要的作用。我们鼓励 CDK 用户探索此功能,提供反馈并将其整合到他们的工作流程中,以优化他们的亚马逊云科技资源管理。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。