使用容器镜像在 Lambda 中部署转译后的 TypeScript 代码 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用容器镜像在 Lambda 中部署转译后的 TypeScript 代码

您可以将 TypeScript 代码作为 Node.js 容器镜像部署到Amazon Lambda函数中。 Amazon为 Node.js 提供了基础映像,以帮助您构建容器镜像。这些基本映像会预加载一个语言运行时和在 Lambda 上运行映像所需的其他组件。Amazon 为每个基本映像提供 Dockerfile,以帮助构建容器映像。

如果使用社群或私有企业基本镜像,则必须将 Node.js 运行时接口客户端 (RIC) 添加到该基本镜像,以使其与 Lambda 兼容。

Lambda 提供了可用于本地测试的运行时系统接口仿真器。Node.js 的 Amazon 基本映像包含运行时系统接口仿真器。如果您使用备用基本映像,例如 Alpine Linux 或  Debian 映像,则可将仿真器构建到映像中将其安装在本地计算机上

使用 Node.js 基础镜像来构建和打包 TypeScript 函数代码

要完成本节中的步骤,您必须满足以下条件:

通过Amazon基本映像为 Lambda 创建映像
  1. 在本地计算机上,为新函数创建项目目录。

  2. 使用 npm 或您选择的软件包管理器创建一个新的 Node.js 项目。

    npm init
  3. 添加 @types/aws-lambdaesbuild 软件包作为开发依赖项。@types/aws-lambda 程序包包含 Lambda 的类型定义。

    npm install -D @types/aws-lambda esbuild
  4. 构建脚本添加到 package.json 文件。

    "scripts": { "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js" }
  5. 创建名为 index.ts 的新文件。将以下示例代码添加到该新文件。这是适用于 Lambda 函数的代码。该函数将返回一条 hello world 消息。

    注意

    import 语句从 @types/aws-lambda 中导入类型定义。它不导入 aws-lambda NPM 程序包,这是一个无关的第三方工具。有关更多信息,请参阅存储库中的 aws-lambda。 DefinitelyTyped GitHub

    import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
  6. 使用以下配置创建一个新的 Dockerfile。

    • FROM 属性设置为基本映像的 URI。

    • 设置 CMD 参数以指定 Lambda 函数处理程序。

    例 Dockerfile

    以下 Dockerfile 将使用多阶段构建。第一步将 TypeScript 代码转换成。 JavaScript第二步生成仅包含 JavaScript 文件和生产依赖项的容器镜像。

    FROM public.ecr.aws/lambda/nodejs:18 as builder WORKDIR /usr/app COPY package.json index.ts ./ RUN npm install RUN npm run build FROM public.ecr.aws/lambda/nodejs:18 WORKDIR ${LAMBDA_TASK_ROOT} COPY --from=builder /usr/app/dist/* ./ CMD ["index.handler"]
  7. 使用 docker build 命令构建 Docker 映像。以下示例将映像命名为 docker-image 并为其提供 test 标签

    docker build --platform linux/amd64 -t docker-image:test .
    注意

    该命令指定了 --platform linux/amd64 选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用 --platform linux/arm64 选项。

  1. 使用 docker run 命令启动 Docker 映像。在此示例中,docker-image 是映像名称,test 是标签。

    docker run --platform linux/amd64 -p 9000:8080 docker-image:test

    此命令会将映像作为容器运行,并在 localhost:9000/2015-03-31/functions/function/invocations 创建本地端点。

    注意

    如果为 ARM64 指令集架构创建 Docker 映像,请务必使用 --platform linux/arm64 选项,而不是 --platform linux/amd64 选项。

  2. 在新的终端窗口中,将事件发布到本地端点。

    Linux/macOS

    在 Linux 和 macOS 中,运行以下 curl 命令:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    此命令使用空事件调用函数并返回响应。如果您使用自己的函数代码而不是示例函数代码,则可能需要使用 JSON 负载调用函数。例如:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
    PowerShell

    在中 PowerShell,运行以下Invoke-WebRequest命令:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"

    此命令使用空事件调用函数并返回响应。如果您使用自己的函数代码而不是示例函数代码,则可能需要使用 JSON 负载调用函数。例如:

    Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
  3. 获取容器 ID。

    docker ps
  4. 使用 docker kill 命令停止容器。在此命令中,将 3766c4ab331c 替换为上一步中的容器 ID。

    docker kill 3766c4ab331c
将映像上传到 Amazon ECR 并创建 Lambda 函数
  1. 运行get-login-password命令将 Docker CLI 验证到您的 Amazon ECR 注册表。

    • --region 值设置为要在其中创建 Amazon ECR 存储库的 Amazon Web Services 区域。

    • 111122223333 替换为您的 Amazon Web Services 账户 ID。

    aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn
  2. 使用 create-repository 命令在 Amazon ECR 中创建存储库。

    aws ecr create-repository --repository-name hello-world --region cn-north-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
    注意

    Amazon ECR 存储库必须与 Lambda 函数位于同一 Amazon Web Services 区域 内。

    如果成功,您将会看到如下响应:

    { "repository": { "repositoryArn": "arn:aws:ecr:cn-north-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
  3. 从上一步的输出中复制 repositoryUri

  4. 运行 docker tag 命令,将本地映像作为最新版本标记到 Amazon ECR 存储库中。在此命令中:

    • docker-image:test 替换为 Docker 映像的名称和标签

    • 将 <ECRrepositoryUri> 替换为复制的 repositoryUri。确保 URI 末尾包含 :latest

    docker tag docker-image:test <ECRrepositoryUri>:latest

    例如:

    docker tag docker-image:test 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  5. 运行 docker push 命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest

    docker push 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  6. 如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。

  7. 创建 Lambda 函数。对于 ImageUri,指定之前的存储库 URI。确保 URI 末尾包含 :latest

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
    注意

    只要映像与 Lambda 函数位于同一区域内,您就可以使用其他 Amazon 账户中的映像创建函数。有关更多信息,请参阅 Amazon ECR 跨账户权限

  8. 调用函数。

    aws lambda invoke --function-name hello-world response.json

    应出现如下响应:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. 要查看函数的输出,请检查 response.json 文件。

要更新函数代码,您必须重新构建映像,将新映像上传到 Amazon ECR 存储库,然后使用update-function-code命令将映像部署到 Lambda 函数。