簡體   English   中英

從管道中的 CDK 堆棧緩存 Lambda Docker 圖像

[英]Caching Lambda Docker images from a CDK stack in a pipeline

為簡單起見,假設我們有一個包含單個 lambda function 創建為 Docker 圖像的堆棧:

import { Stack, StackProps, Duration } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    const exampleFun = new lambda.DockerImageFunction(this, "ExampleFun", {
      code: lambda.DockerImageCode.fromImageAsset("lambda/example_fun"),
      timeout: Duration.seconds(10)
    });
  }
}

我省略了lambda/example_fun的內容,因為它很簡單,即它包含一個帶有一些虛擬處理程序的 single.py 文件和一個 Dockerfile,它使用 say public.ecr.aws/lambda/python:3.9 作為基礎並使用處理程序為 cmd。

現在,特別是如果有很多這樣的 lambda 和/或它們很大,CDK 管道(例如您作為AWS CDK Workshop的一部分構建的管道)將不會緩存它們中的任何一個。 具體來說,讓我們有:

import * as cdk from 'aws-cdk-lib';
import * as codecommit from 'aws-cdk-lib/aws-codecommit';
import { Construct } from 'constructs';
import {CodeBuildStep, CodePipeline, CodePipelineSource} from "aws-cdk-lib/pipelines";
import { FunStack } from "./fun-stack";
import { Stage, StageProps  } from "aws-cdk-lib";

export class FunPipelineStage extends Stage {
    constructor(scope: Construct, id: string, props?: StageProps) {
        super(scope, id, props);

        new FunStack(this, 'Fun');
    }
}

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

        const repo = new codecommit.Repository(this, 'FunRepo', {
            repositoryName: "FunRepo"
        });

        const pipeline = new CodePipeline(this, 'Pipeline', {
            pipelineName: 'FunLambdaPipeline',
            synth: new CodeBuildStep('SynthStep', {
                input: CodePipelineSource.codeCommit(repo, 'master'),
                installCommands: [
                    'npm install -g aws-cdk'
                ],
                commands: [
                    'npm ci',
                    'npm run build',
                    'npx cdk synth'
                ]
            })
        });

        const deploy = new FunPipelineStage(this, 'Deploy');
        const deployStage = pipeline.addStage(deploy);
    }
}

應該如何修改管道以允許我們在部署時緩存管道生成的DockerImageFunction

如果我正確閱讀了AWS CodeBuild 中構建緩存的文檔並從BuildSpec 的 CDK 文檔中正確推斷,我想我應該使用codebuild.BuildSpec.fromObject來指定構建規范文件。

通過一些實驗,我能夠通過fromObject和 buildspec 文件執行簡單的安裝和/或構建命令,但不太清楚如何緩存。 特別是,管道如何引用作為堆棧的一部分構建的 Docker 圖像? 目標是在每次構建時,如果 Docker 圖像沒有改變,它們將從緩存中讀取並避免重建。

也許另一種選擇是設置一個 ECR 存儲庫,以某種方式在每次構建時檢查是否找到構建容器的 hash,如果沒有,則構建並推送。 但是,我不知道如何具體執行此操作,因為我看不到如何引用構建的 Docker 圖像(如果這有意義的話)。

使用partialBuildSpec prop 提供部分構建規范,並使用cache prop 指定緩存方法,如模塊概述所示:

    ...
    synth: new CodeBuildStep('SynthStep', {
        input: CodePipelineSource.codeCommit(repo, 'master'),
        installCommands: [
            'npm install -g aws-cdk'
        ],
        commands: [
            'npm ci',
            'npm run build',
            'npx cdk synth'
        ],
        partialBuildSpec: codebuild.BuildSpec.fromObject({
          cache: {
            paths: [ "path/to/cache/**/*" ]
          }
        }),
        cache: codebuild.Cache.bucket(new s3.Bucket(this, 'Cache')),
    })

容器將在任何情況下構建 - 你可以讓它更快。 容器 hash 不先構建它是不可能知道是否改變的。

可能相關: https://github.com/aws/aws-cdk/issues/19157

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM