使用容器映像部署 Node.js Lambda 函数
有三种方法可以为 Node.js Lambda 函数构建容器映像:
-
Amazon 基本映像会预加载一个语言运行时系统、一个用于管理 Lambda 和函数代码之间交互的运行时系统接口客户端,以及一个用于本地测试的运行时系统接口仿真器。
-
Amazon 提供的基本映像
包含 Amazon Linux 或 Amazon Linux 2 操作系统。您可以将首选的运行时系统、依赖项和代码添加到这些映像中。要使映像与 Lambda 兼容,您必须在映像中包含 Node.js 的运行时系统接口客户端。 -
您还可以使用其他容器注册表的备用基本映像,例如 Alpine Linux 或 Debian。您还可以使用您的组织创建的自定义映像。要使映像与 Lambda 兼容,您必须在映像中包含 Node.js 的运行时系统接口客户端。
提示
要缩短 Lambda 容器函数激活所需的时间,请参阅 Docker 文档中的使用多阶段构建
此页面介绍了如何为 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 的基本映像创建容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
使用
npm
创建新的 Node.js 项目。要在交互式体验中接受提供的默认选项,请按Enter
。npm init
-
创建名为
index.js
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 CommonJS 处理程序
exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
-
如果函数依赖于 Amazon SDK for JavaScript 之外的库,请使用 npm
将其添加到程序包。 -
使用以下配置创建一个新的 Dockerfile。
-
将
FROM
属性设置为基本映像的 URI。 -
使用 COPY 命令将函数代码和运行时系统依赖项复制到
{LAMBDA_TASK_ROOT}
。 -
将
CMD
参数设置为 Lambda 函数处理程序。
例 Dockerfile
FROM
public.ecr.aws/lambda/nodejs:16
# Copy function code COPYindex.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
" ] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build -t
docker-image
:test
.
-
使用 docker run 命令启动 Docker 映像。在此示例中,
docker-image
是映像名称,test
是标签。docker run -p 9000:8080
docker-image
:test
此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations
创建本地端点。 -
在新的终端窗口中,使用 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!"}
' -
获取容器 ID。
docker ps
-
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c
替换为上一步中的容器 ID。docker kill
3766c4ab331c
将映像上传到 Amazon ECR 并创建 Lambda 函数
-
运行 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-stdin111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn -
-
使用 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" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 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 -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest
。docker push
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 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 \ --rolearn:aws:iam::111122223333:role/lambda-ex
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code
将备用基本映像与运行时系统接口客户端配合使用
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 运行时接口客户端
14.x
16.x
18.x
以下示例演示了如何使用非 Amazon 基本映像为 Node.js 构建容器映像。示例 Dockerfile 使用 buster
基本映像。Docker 包含运行时系统接口客户端。
要完成本节中的步骤,您必须满足以下条件:
要从非 Amazon 基本映像创建容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
使用
npm
创建新的 Node.js 项目。要在交互式体验中接受提供的默认选项,请按Enter
。npm init
-
创建名为
index.js
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 CommonJS 处理程序
exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
-
创建新 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 FROMnode: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
"] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build -t
docker-image
:test
.
若要在本地测试从自定义运行时系统的基本映像或备用基本映像构建的映像,则必须使用运行时系统接口仿真器。您可以将仿真器构建到映像中,也可以将其安装在本地计算机上。
在本地计算机上安装并运行运行时系统接口仿真器
-
从项目目录中,运行以下命令以从 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
-
使用 docker run 命令启动 Docker 映像。请注意以下几点:
-
docker-image
是映像名称,test
是标签。 -
/usr/local/bin/npx aws-lambda-ric index.handler
是ENTRYPOINT
,后跟您 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
创建本地端点。 -
-
在新的终端窗口中,使用 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!"}
' -
获取容器 ID。
docker ps
-
使用 docker kill
命令停止容器。在此命令中,将 3766c4ab331c
替换为上一步中的容器 ID。docker kill
3766c4ab331c
将映像上传到 Amazon ECR 并创建 Lambda 函数
-
运行 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-stdin111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn -
-
使用 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" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 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 -
-
运行 docker push
命令,以将本地映像部署到 Amazon ECR 存储库。确保存储库 URI 末尾包含 :latest
。docker push
111122223333
.dkr.ecr.cn-north-1
.amazonaws.com.cn/hello-world
:latest -
如果您还没有函数的执行角色,请创建执行角色。在下一步中,您需要提供角色的 Amazon 资源名称(ARN)。
-
创建 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 \ --rolearn:aws:iam::111122223333:role/lambda-ex
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code