构建 Docker 镜像,将其上传到 ECR,并在 Lambda 函数中使用它

问题描述 投票:0回答:1

感觉就像是先有鸡还是先有蛋的问题。 我正在尝试构建一个 Docker 映像,将其添加到我的 ECR 存储库,并在使用 CDK V2 的 Lambda 函数中使用它。

这是我的代码:

const repository = new ecr.Repository(this, `WorkerHelloRepository`, {
    repositoryName: `worker-hello`,
    imageTagMutability: ecr.TagMutability.IMMUTABLE,
    imageScanOnPush: true,
    removalPolicy: cdk.RemovalPolicy.DESTROY,
    lifecycleRules: [
    {
        description: 'Keeps a maximum number of images to minimize storage',
        maxImageCount: 10,
    },
    ],
});

const asset = new DockerImageAsset(this, `WorkerHelloDockerImageAsset`, {
    directory: path.join(__dirname, `../../../workers/hello`),
    buildArgs: {},
});

const destinationImageName = `${repository.repositoryUri}:${asset.assetHash}`;
new ecrdeploy.ECRDeployment(this, 'EcrDeployment', {
    src: new ecrdeploy.DockerImageName(asset.imageUri),
    dest: new ecrdeploy.DockerImageName(destinationImageName),
});

const lambdaFunction = new lambda.DockerImageFunction(this, `WorkerHelloFunction`, {
    code: lambda.DockerImageCode.fromEcr(repository, {
    tagOrDigest: asset.assetHash,
    cmd: ['index.newEntry'],
    }),
});

repository.grantPull(lambdaFunction);

lambdaFunction.addToRolePolicy(
    new cdk.aws_iam.PolicyStatement({
    actions: ['ecr:BatchGetImage', 'ecr:GetDownloadUrlForLayer'],
    resources: [repository.repositoryArn],
    effect: cdk.aws_iam.Effect.ALLOW,
    }),
);

CloudFormation 返回的错误说该图片不存在:

4:05:35 AM | CREATE_FAILED        | AWS::Lambda::Function                 | workers-stack/work...orkerHelloFunction
Resource handler returned message: "Source image ***********.dkr.ecr.us-west-2.amazonaws.com/worker-hello:55106229314a459e2cf7fbfa14c2c03b728ffd20a70dad
3cf25ff51d7664abce does not exist. Provide a valid source image. (Service: Lambda, Status Code: 400, Request ID: 6ef7e839-ddb3-43c1-9170-c50865f6af70)" (Reques
tToken: be9bf05b-47e6-5239-da32-46cbe422853d, HandlerErrorCode: InvalidRequest)

但是当我检查 ECR 存储库时(CloudFormation 无法删除,因为它不为空),我可以看到图像并且其 uri 是正确的。

我尝试通过执行以下操作手动将 Lambda 函数的依赖项添加到创建的资产:

lambdaFunction.node.addDependency(asset);

我很确定 CDK 足够聪明,能够实际检测到这种依赖关系,但它并没有解决问题。

我真的想避免为 ECR 建立一个单独的堆栈,但我想这可以解决问题。我没有尝试的是将 ECR 内容和 Lambda 资源移动到两个不同的嵌套堆栈中,并从一个堆栈添加到另一个堆栈的依赖项,但我不明白为什么它会工作得更好。

有什么想法吗?或者甚至有关于如何解决先有鸡还是先有蛋的问题的指导吗?

typescript amazon-web-services aws-lambda aws-cdk amazon-ecr
1个回答
0
投票

您的依赖项应该依赖于 ECR 部署,而不是原始资产(因为 lambda 不直接使用该资产)。

你已经完成了大部分工作,这应该可行:

const deployment = new ecrdeploy.ECRDeployment(this, 'EcrDeployment', {
    src: new ecrdeploy.DockerImageName(asset.imageUri),
    dest: new ecrdeploy.DockerImageName(destinationImageName),
});

const lambdaFunction = new lambda.DockerImageFunction(this, `WorkerHelloFunction`, {
    code: lambda.DockerImageCode.fromEcr(repository, {
    tagOrDigest: asset.assetHash,
    cmd: ['index.newEntry'],
    }),
});

// Dependency on the deployment, not the asset
lambdaFunction.node.addDependency(deployment);
© www.soinside.com 2019 - 2024. All rights reserved.