使用容器映像部署 Node.js Lambda 函数 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用容器映像部署 Node.js Lambda 函数

有三种方法可以为 Node.js Lambda 函数构建容器映像:

提示

要缩短 Lambda 容器函数激活所需的时间,请参阅 Docker 文档中的使用多阶段构建。要构建高效的容器映像,请遵循编写 Dockerfiles 的最佳实践

此页面介绍了如何为 Lambda 构建、测试和部署容器映像。

Node.js 的 Amazon 基本映像

Amazon 为 Node.js 提供了以下基本映像:

标签 运行时 操作系统 Dockerfile 淘汰

18

Node.js 18 Amazon Linux 2 GitHub 上适用于 Node.js 18 的 Dockerfile

16

Node.js 16 Amazon Linux 2 GitHub 上适用于 Node.js 16 的 Dockerfile

2024 年 3 月 11 日

14

Node.js 14 Amazon Linux 2 GitHub 上适用于 Node.js 14 的 Dockerfile

2023 年 11 月 15 日

Amazon ECR 存储库:gallery.ecr.aws/lambda/nodejs

使用 Node.js 的 Amazon 基本映像

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

从 Node.js 的 Amazon 的基本映像创建容器映像
  1. 为项目创建一个目录,然后切换到该目录。

    mkdir example cd example
  2. 使用 npm 创建新的 Node.js 项目。要在交互式体验中接受提供的默认选项,请按 Enter

    npm init
  3. 创建名为 index.js 的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。

    例 CommonJS 处理程序
    exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
  4. 如果函数依赖于 Amazon SDK for JavaScript 之外的库,请使用 npm 将其添加到程序包。

  5. 使用以下配置创建一个新的 Dockerfile。

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

    • 使用 COPY 命令将函数代码和运行时系统依赖项复制到 {LAMBDA_TASK_ROOT}

    • CMD 参数设置为 Lambda 函数处理程序。

    例 Dockerfile
    FROM public.ecr.aws/lambda/nodejs:16 # Copy function code COPY index.js ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "index.handler" ]
  6. 使用 docker build 命令构建 Docker 映像。以下示例将映像命名为 docker-image 并为其提供 test 标签

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

    docker run -p 9000:8080 docker-image:test

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

  2. 在新的终端窗口中,使用 curl 命令将事件发布到以下端点:

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

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

    curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  3. 获取容器 ID。

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

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

    • --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 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

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

    { "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 映像的名称和标签

    • 将 Amazon ECR 存储库 URI 替换为您复制的 repositoryUri。确保 URI 末尾包含 :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
  8. 调用函数。

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

    应出现如下响应:

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

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

将备用基本映像与运行时系统接口客户端配合使用

If you use a 自定义运行时系统的基本映像 or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Lambda 运行时 API, which manages the interaction between Lambda and your function code.

使用 npm 包管理器安装 Node.js 运行时系统接口客户端

npm install aws-lambda-ric

您也可以从 GitHub 下载 Node.js 运行时接口客户端。运行时系统接口客户端支持以下 NodeJS 版本:

  • 14.x

  • 16.x

  • 18.x

以下示例演示了如何使用非 Amazon 基本映像为 Node.js 构建容器映像。示例 Dockerfile 使用 buster 基本映像。Docker 包含运行时系统接口客户端。

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

要从非 Amazon 基本映像创建容器映像
  1. 为项目创建一个目录,然后切换到该目录。

    mkdir example cd example
  2. 使用 npm 创建新的 Node.js 项目。要在交互式体验中接受提供的默认选项,请按 Enter

    npm init
  3. 创建名为 index.js 的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。

    例 CommonJS 处理程序
    exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
  4. 创建新 Dockerfile。以下 Dockerfile 使用 buster 基本映像而不是 Amazon 基本映像。Dockerfile 包含运行时系统接口客户端,该客户端可使映像与 Lambda 兼容。Dockerfile 使用多阶段构建。第一阶段将创建一个构建映像,作为安装函数依赖项的标准 Node.js 环境。第二阶段创建一个更精简的映像,其中包含函数代码及其依赖项。此机制可缩减最终映像大小。

    • FROM 属性设置为基本映像标识符。

    • 使用 COPY 命令将复制函数代码和运行时系统依赖项。

    • ENTRYPOINT 设置为您希望 Docker 容器在启动时运行的模块。在本例中,模块为运行时系统接口客户端。

    • CMD 参数设置为 Lambda 函数处理程序。

    例 Dockerfile
    # Define custom function directory ARG FUNCTION_DIR="/function" FROM node:18-buster as build-image # Include global arg in this stage of the build ARG FUNCTION_DIR # Install build dependencies RUN apt-get update && \ apt-get install -y \ g++ \ make \ cmake \ unzip \ libcurl4-openssl-dev # Copy function code RUN mkdir -p ${FUNCTION_DIR} COPY . ${FUNCTION_DIR} WORKDIR ${FUNCTION_DIR} # Install Node.js dependencies RUN npm install # Install the runtime interface client RUN npm install aws-lambda-ric # Grab a fresh slim copy of the image to reduce the final size FROM node:18-buster-slim # Required for Node runtimes which use npm@8.6.0+ because # by default npm writes logs under /home/.npm and Lambda fs is read-only ENV NPM_CONFIG_CACHE=/tmp/.npm # Include global arg in this stage of the build ARG FUNCTION_DIR # Set working directory to function root directory WORKDIR ${FUNCTION_DIR} # Copy in the built dependencies COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} # Set runtime interface client as default command for the container runtime ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"] # Pass the name of the function handler as an argument to the runtime CMD ["index.handler"]
  5. 使用 docker build 命令构建 Docker 映像。以下示例将映像命名为 docker-image 并为其提供 test 标签

    docker build -t docker-image:test .

若要在本地测试从自定义运行时系统的基本映像或备用基本映像构建的映像,则必须使用运行时系统接口仿真器。您可以将仿真器构建到映像中,也可以将其安装在本地计算机上。

在本地计算机上安装并运行运行时系统接口仿真器
  1. 从项目目录中,运行以下命令以从 GitHub 下载运行时系统接口仿真器(x86-64 架构)并将其安装在本地计算机上。

    mkdir -p ~/.aws-lambda-rie && \ curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \ chmod +x ~/.aws-lambda-rie/aws-lambda-rie

    要安装 arm64 仿真器,请将上一条命令中的 GitHub 存储库 URL 替换为以下内容:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
  2. 使用 docker run 命令启动 Docker 映像。请注意以下几点:

    • docker-image 是映像名称,test 是标签。

    • /usr/local/bin/npx aws-lambda-ric index.handlerENTRYPOINT,后跟您 Dockerfile 中的 CMD

    docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \ --entrypoint /aws-lambda/aws-lambda-rie \ docker-image:test \ /usr/local/bin/npx aws-lambda-ric index.handler

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

  3. 在新的终端窗口中,使用 curl 命令将事件发布到以下端点:

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

    此命令使用空事件调用函数并返回响应。某些函数可能需要 JSON 负载。示例:

    curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  4. 获取容器 ID。

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

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

    • --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 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

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

    { "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 映像的名称和标签

    • 将 Amazon ECR 存储库 URI 替换为您复制的 repositoryUri。确保 URI 末尾包含 :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
  8. 调用函数。

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

    应出现如下响应:

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

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