使用容器镜像部署 Ruby Lambda 函数
有三种方法可以为 Ruby Lambda 函数构建容器映像:
-
Amazon 基本映像会预加载一个语言运行时系统、一个用于管理 Lambda 和函数代码之间交互的运行时系统接口客户端,以及一个用于本地测试的运行时系统接口仿真器。
-
Amazon 仅限操作系统的运行时系统
包含 Amazon Linux 发行版和运行时系统接口模拟器 。这些镜像通常用于为编译语言(例如 Go 和 Rust)以及 Lambda 未提供基础映像的语言或语言版本(例如 Node.js 19)创建容器镜像。您也可以使用仅限操作系统的基础映像来实施自定义运行时系统。要使映像与 Ruby 兼容,您必须在映像中包含 Java 的运行时系统接口客户端。 -
您还可以使用其他容器注册表的备用基本映像,例如 Alpine Linux 或 Debian。您还可以使用您的组织创建的自定义映像。要使映像与 Ruby 兼容,您必须在映像中包含 Java 的运行时系统接口客户端。
提示
要缩短 Lambda 容器函数激活所需的时间,请参阅 Docker 文档中的使用多阶段构建
此页面介绍了如何为 Lambda 构建、测试和部署容器映像。
Ruby Amazon 基本映像
Amazon 为 Ruby 提供了以下基本映像:
标签 | 运行时 | 操作系统 | Dockerfile | 淘汰 |
---|---|---|---|---|
3.3 |
Ruby 3.3 | Amazon Linux 2023 | GitHub 上的适用于 Ruby 3.3 的 Dockerfile |
未计划 |
3.2 |
Ruby 3.2 | Amazon Linux 2 | GitHub 上的适用于 Ruby 3.2 的 Dockerfile |
未计划 |
Amazon ECR 存储库:gallery.ecr.aws/lambda/ruby
使用 Ruby 的 Amazon 基本映像
要完成本节中的步骤,您必须满足以下条件:
-
Ruby
要创建适用于 Ruby 的容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
创建名为
Gemfile
的新文件。您可以在此处列出应用程序所需的 RubyGems 软件包。Amazon SDK for Ruby 可从 RubyGems 获得。您应该选择特定的 Amazon 服务 Gem 进行安装。例如,要使用适用于 Lambda 的 Ruby Gem,Gemfile 应如下所示: source 'https://rubygems.org' gem 'aws-sdk-lambda'
或者,aws-sdk
Gem 包含所有可用的 Amazon 服务 Gem。此 Gem 非常大。我们建议您仅在依赖许多 Amazon 服务时使用它。 -
使用 bundle 安装
来安装 Gemfile 中指定的依赖项。 bundle install
-
创建名为
lambda_function.rb
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 Ruby 函数
module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
-
创建新 Dockerfile。以下示例 Dockerfile 使用 Amazon 基本映像。此 Docerfile 使用以下配置:
-
将
FROM
属性设置为基本映像的 URI。 -
使用 COPY 命令将函数代码和运行时系统依赖项复制到
{LAMBDA_TASK_ROOT}
,此为 Lambda 定义的环境变量。 -
将
CMD
参数设置为 Lambda 函数处理程序。
请注意,示例 Dockerfile 不包含 USER 指令
。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER
指令时默认为root
用户。例 Dockerfile
FROM
public.ecr.aws/lambda/ruby:3.2
# Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPYlambda_function.rb
${LAMBDA_TASK_ROOT}/ # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process
" ] -
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build --platform linux/amd64 -t
docker-image
:test
.注意
该命令指定了
--platform linux/amd64
选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64
选项。
-
使用 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
-
在新的终端窗口中,将事件发布到本地端点。
-
获取容器 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
--regioncn-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" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 docker tag
命令,将本地映像作为最新版本标记到 Amazon ECR 存储库中。在此命令中: -
docker-image:test
是 Docker 映像的名称和标签。这是您在 docker build
命令中指定的映像名称和标签。 -
将
<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 -
-
运行 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
注意
只要映像与 Lambda 函数位于同一区域内,您就可以使用其他 Amazon 账户中的映像创建函数。有关更多信息,请参阅 Amazon ECR 跨账户权限。
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code
Lambda 会将映像标签解析为特定的映像摘要。这意味着,如果您将用于部署函数的映像标签指向 Amazon ECR 中的新映像,则 Lambda 不会自动更新该函数以使用新映像。
要将新映像部署到相同的 Lambda 函数,即使 Amazon ECR 中的映像标签保持不变,也必须使用 update-function-code--publish
选项使用更新的容器映像创建函数的新版本。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
\ --publish
将备用基本映像与运行时系统接口客户端配合使用
如果使用仅限操作系统的基础映像或者备用基础映像,则必须在映像中包括运行时系统接口客户端。运行时系统接口客户端可扩展 将 Lambda 运行时 API 用于自定义运行时,用于管理 Lambda 和函数代码之间的交互。
使用 RubyGems.org 程序包管理器安装适用于 Ruby 的 Lambda 运行时系统接口客户端
gem install aws_lambda_ric
您也可以从 GitHub 下载 Ruby 运行时接口客户端
以下示例演示了如何使用非 Amazon 基本映像构建适用于 Ruby 的容器映像。示例 Dockerfile 使用官方 Ruby 基本映像。Docker 包含运行时系统接口客户端。
要完成本节中的步骤,您必须满足以下条件:
-
Ruby
要使用备用基本映像创建适用于 Ruby 的容器映像
-
为项目创建一个目录,然后切换到该目录。
mkdir example cd example
-
创建名为
Gemfile
的新文件。您可以在此处列出应用程序所需的 RubyGems 软件包。Amazon SDK for Ruby 可从 RubyGems 获得。您应该选择特定的 Amazon 服务 Gem 进行安装。例如,要使用适用于 Lambda 的 Ruby Gem,Gemfile 应如下所示: source 'https://rubygems.org' gem 'aws-sdk-lambda'
或者,aws-sdk
Gem 包含所有可用的 Amazon 服务 Gem。此 Gem 非常大。我们建议您仅在依赖许多 Amazon 服务时使用它。 -
使用 bundle 安装
来安装 Gemfile 中指定的依赖项。 bundle install
-
创建名为
lambda_function.rb
的新文件。您可以将以下示例函数代码添加到文件中进行测试,也可以使用您自己的函数代码。例 Ruby 函数
module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
-
创建新 Dockerfile。以下 Dockerfile 使用 Ruby 基本映像而不是 Amazon 基本映像。Dockerfile 包含适用于 Ruby 的运行时系统接口客户端
,该客户端可使映像与 Lambda 兼容。或者,您可以将运行时系统接口客户端添加到应用程序的 Gemfile 中。 -
将
FROM
属性设置为 Ruby 基本映像。 -
为函数代码创建目录和指向该目录的环境变量。在本示例中,目录为
/var/task
,会镜像 Lambda 执行环境。不过,您可以为函数代码选择任何目录,因为 Dockerfile 不使用 Amazon 基础映像。 -
将
ENTRYPOINT
设置为您希望 Docker 容器在启动时运行的模块。在本例中,模块为运行时系统接口客户端。 -
将
CMD
参数设置为 Lambda 函数处理程序。
请注意,示例 Dockerfile 不包含 USER 指令
。当您将容器映像部署到 Lambda 时,Lambda 会自动定义具有最低权限的默认 Linux 用户。这与标准 Docker 行为不同,标准 Docker 在未提供 USER
指令时默认为root
用户。例 Dockerfile
FROM
ruby:2.7
# Install the runtime interface client for Ruby RUN gem install aws_lambda_ric # Add the runtime interface client to the PATH ENV PATH="/usr/local/bundle/bin:${PATH}" # Create a directory for the Lambda function ENV LAMBDA_TASK_ROOT=/var/task RUN mkdir -p ${LAMBDA_TASK_ROOT} WORKDIR ${LAMBDA_TASK_ROOT} # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPYlambda_function.rb
${LAMBDA_TASK_ROOT}/ # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "aws_lambda_ric
" ] # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
-
-
使用 docker build
命令构建 Docker 映像。以下示例将映像命名为 docker-image
并为其提供test
标签。 docker build --platform linux/amd64 -t
docker-image
:test
.注意
该命令指定了
--platform linux/amd64
选项,可确保无论生成计算机的架构如何,容器始终与 Lambda 执行环境兼容。如果打算使用 ARM64 指令集架构创建 Lambda 函数,请务必将命令更改为使用--platform linux/arm64
选项。
使用运行时系统接口仿真器
在本地计算机上安装并运行运行时系统接口仿真器
-
从项目目录中,运行以下命令以从 GitHub 下载运行时系统接口仿真器(x86-64 架构)并将其安装在本地计算机上。
-
使用 docker run 命令启动 Docker 映像。请注意以下几点:
-
docker-image
是映像名称,test
是标签。 -
aws_lambda_ric lambda_function.LambdaFunction::Handler.process
是ENTRYPOINT
,后跟您 Dockerfile 中的CMD
。
此命令会将映像作为容器运行,并在
localhost:9000/2015-03-31/functions/function/invocations
创建本地端点。注意
如果为 ARM64 指令集架构创建 Docker 映像,请务必使用
--platform linux/
选项,而不是arm64
--platform linux/
选项。amd64
-
-
将事件发布到本地端点。
-
获取容器 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
--regioncn-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" } } }
-
从上一步的输出中复制
repositoryUri
。 -
运行 docker tag
命令,将本地映像作为最新版本标记到 Amazon ECR 存储库中。在此命令中: -
docker-image:test
是 Docker 映像的名称和标签。这是您在 docker build
命令中指定的映像名称和标签。 -
将
<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 -
-
运行 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
注意
只要映像与 Lambda 函数位于同一区域内,您就可以使用其他 Amazon 账户中的映像创建函数。有关更多信息,请参阅 Amazon ECR 跨账户权限。
-
调用函数。
aws lambda invoke --function-name
hello-world
response.json应出现如下响应:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
要查看函数的输出,请检查
response.json
文件。
要更新函数代码,您必须再次构建映像,将新映像上传到 Amazon ECR 存储库,然后使用 update-function-code
Lambda 会将映像标签解析为特定的映像摘要。这意味着,如果您将用于部署函数的映像标签指向 Amazon ECR 中的新映像,则 Lambda 不会自动更新该函数以使用新映像。
要将新映像部署到相同的 Lambda 函数,即使 Amazon ECR 中的映像标签保持不变,也必须使用 update-function-code--publish
选项使用更新的容器映像创建函数的新版本。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
\ --publish