将 .zip 文件存档用于 Ruby Lambda 函数 - AWS Lambda

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

将 .zip 文件存档用于 Ruby Lambda 函数

AWS Lambda 函数的代码包含一个 .rb 文件,其中包含函数的处理程序代码,以及代码所依赖的任何其他依赖项(Gem)。要将此函数部署到 Lambda,您可以使用部署包。此包可以是 .zip 文件归档或容器映像。有关在 Ruby 中使用容器映像的更多信息,请参阅使用容器映像部署 Ruby Lambda 函数

要创建 .zip 文件归档格式的部署包,可以使用命令行工具内置的 .zip 文件归档实用工具或任何其他 .zip 文件实用工具(例如 7zip)。以下各部分中显示的示例假设您在 Linux 或 macOS 环境中使用命令行 zip 工具。要在 Windows 中使用相同命令,您可以安装 Windows Subsystem for Linux,以获取 Windows 集成版本的 Ubuntu 和 Bash。

请注意,Lambda 使用 POSIX 文件权限,因此在创建 .zip 文件归档之前,您可能需要为部署包文件夹设置权限

以下部分中的示例命令使用 Bundler 实用程序为部署包添加依赖项。要安装 Bundler,请运行以下命令:

gem install bundler

Ruby 中的依赖项

对于使用 Ruby 运行时系统的 Lambda 函数,依赖项可以是任何 Ruby Gem。使用 .zip 归档部署函数时,可以使用函数代码将这些依赖项添加到 .zip 文件中,也可以使用 Lambda 层。层是可以包含其他代码或其他内容的单独的 .zip 文件。要了解有关使用 Lambda 层的更多信息,请参阅 使用 Lambda 层

Ruby 运行时包括 AWS SDK for Ruby。如果您的函数使用开发工具包,则无需将其与代码捆绑。不过,如果您希望保持对依赖项的完全控制权或使用特定版本的开发工具包,则可将其添加到函数的部署包中。您可以将开发工具包包含在.zip 文件中,也可以使用 Lambda 层进行添加。.zip 文件或 Lambda 层中的依赖项优先于运行时系统中包含的版本。要查找运行时系统版本中包含哪个版本的 SDK for Ruby,请参阅 包含运行时的 SDK 版本

AWS 责任共担模式下,您负责管理函数部署包中的所有依赖项。这包括应用更新和安全补丁。要更新函数部署包中的依赖项,请先创建一个新的 .zip 文件,然后将其上传到 Lambda 中。有关更多信息,请参阅 创建含依赖项的 .zip 部署包使用 .zip 文件创建和更新 Ruby Lambda 函数

创建不含依赖项的 .zip 部署包

如果您的函数代码没有依赖项,则 .zip 文件仅包含带有函数处理程序代码的 .rb 文件。使用首选 ZIP 实用工具创建一个 .zip 文件,并将 .rb 文件置于根目录中。如果 .rb 文件不在 .zip 文件的根目录下,Lambda 将无法运行代码。

要了解如何部署 .zip 文件以创建新的 Lambda 函数或更新现有函数,请参阅 使用 .zip 文件创建和更新 Ruby Lambda 函数

创建含依赖项的 .zip 部署包

如果函数代码依赖其他 Ruby Gem,您可以使用函数代码将这些依赖项添加到 .zip 文件中,也可以使用 Lambda 层进行添加。本部分中的说明旨在向您展示如何将依赖项包含在 .zip 部署包中。有关如何将依赖项包含在层中的说明,请参阅 为依赖项创建 Ruby 层

假设函数代码保存在项目目录下名为 lambda_function.rb 的文件中。以下示例 CLI 命令将创建名为 my_deployment_package.zip 的 .zip 文件,其中包含函数代码及其依赖项。

创建部署包
  1. 在项目目录中,创建 Gemfile 来指定其中的依赖项。

    bundle init
  2. 使用首选文本编辑器对 Gemfile 进行编辑,从而指定函数的依赖项。例如,要使用 TZInfo Gem,请按照如下所示编辑 Gemfile

    source "https://rubygems.org" gem "tzinfo"
  3. 运行以下命令,将 Gemfile 中指定的 Gem 安装到项目目录中。此命令将 vendor/bundle 设置为 Gem 的默认安装路径。

    bundle config set --local path 'vendor/bundle' && bundle install

    您应该可以看到类似于如下所示的输出内容。

    Fetching gem metadata from https://rubygems.org/........... Resolving dependencies... Using bundler 2.4.13 Fetching tzinfo 2.0.6 Installing tzinfo 2.0.6 ...
    注意

    稍后想再次全局安装 Gem,请运行以下命令:

    bundle config set --local system 'true'
  4. 创建 .zip 文件存档,其中包含带有函数处理程序代码以及您在上一步中安装的依赖项的 lambda_function.rb 文件。

    zip -r my_deployment_package.zip lambda_function.rb vendor

    您应该可以看到类似于如下所示的输出内容。

    adding: lambda_function.rb (deflated 37%) adding: vendor/ (stored 0%) adding: vendor/bundle/ (stored 0%) adding: vendor/bundle/ruby/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/build_info/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/cache/ (stored 0%) adding: vendor/bundle/ruby/3.2.0/cache/aws-eventstream-1.0.1.gem (deflated 36%) ...

为依赖项创建 Ruby 层

本部分中的说明旨在向您展示如何将依赖项包含在层中。有关如何将依赖项包含在部署包中的说明,请参阅 创建含依赖项的 .zip 部署包

当您向函数添加层时,Lambda 会将层内容加载到该执行环境的 /opt 目录中。对于每个 Lambda 运行时系统,PATH 变量都包括 /opt 目录中的特定文件夹路径。为了确保 PATH 变量能够获取层内容,请将内容包含在以下文件夹路径中:

  • ruby/gems/2.7.0 (GEM_PATH)

  • ruby/lib (RUBYLIB)

例如,层.zip 文件结构可能如下所示:

json.zip └ ruby/gems/2.7.0/ | build_info | cache | doc | extensions | gems | └ json-2.1.0 └ specifications └ json-2.1.0.gemspec

此外,Lambda 会自动检测 /opt/lib 目录中的任何库,以及 /opt/bin 目录中的任何二进制文件。为确保 Lambda 正确获取层内容,还可以创建包含以下结构的层:

custom-layer.zip └ lib | lib_1 | lib_2 └ bin | bin_1 | bin_2

打包层后,请参阅 在 Lambda 中创建和删除层 和 向函数添加层 以完成层设置。

使用原生库创建 .zip 部署包

许多常见的 Ruby Gem(例如 nokogirinio4rmysql),都包含用 C 语言编写的本机扩展。将包含 C 代码的库添加到部署包时,必须正确构建程序包,确保其与 Lambda 执行环境兼容。

对于生产应用程序,建议您使用 AWS Serverless Application Model(AWS SAM)来构建和部署代码。在 AWS SAM 中,使用 sam build --use-container 选项在类似 Lambda 的 Docker 容器中构建函数。要了解有关使用 AWS SAM 来部署函数代码的更多信息,请参阅《AWS SAM 开发人员指南》中的 Building applications

要在不使用 AWS SAM 的情况下创建包含带本机扩展的 Gem 的.zip 部署包,您也可以使用容器将依赖项捆绑到与 Lambda Ruby 运行时系统环境相同的环境中。要完成这些步骤,就必须在生成计算机上安装 Docker。要了解有关安装 Docker 的更多信息,请参阅 Install Docker Engine

在 Docker 容器中创建.zip 部署包
  1. 在本地生成计算机上创建文件夹来保存容器。在该文件夹中,创建一个名为 dockerfile 的文件,再将以下代码粘贴到该文件中。

    FROM public.ecr.aws/sam/build-ruby3.2:latest-x86_64 RUN gem update bundler CMD "/bin/bash"
  2. 在您创建 dockerfile 的文件夹中,运行以下命令来创建 Docker 容器。

    docker build -t awsruby32 .
  3. 导航到项目目录,其中包含带有函数处理程序代码以及指定函数依赖项的 Gemfile.rb 文件。在该目录中,运行以下命令启动 Lambda Ruby 容器。

    Linux/MacOS
    docker run --rm -it -v $PWD:/var/task -w /var/task awsruby32
    注意

    在 MacOS 中,您可能会看到一条警告,告知您所请求映像的平台与检测到的主机平台不匹配。请忽略该警告。

    Windows PowerShell
    docker run --rm -it -v ${pwd}:var/task -w /var/task awsruby32

    容器启动时,您应该会看到 bash 提示符。

    bash-4.2#
  4. 配置捆绑实用程序,将 Gemfile 中指定的 Gem 安装到本地 vendor/bundle 目录中并安装依赖项。

    bash-4.2# bundle config set --local path 'vendor/bundle' && bundle install
  5. 创建包含函数代码及其依赖项的 .zip 部署包。在此示例中,包含函数处理程序代码的文件名为 lambda_function.rb

    bash-4.2# zip -r my_deployment_package.zip lambda_function.rb vendor
  6. 退出容器并返回到本地项目目录。

    bash-4.2# exit

    现在,您可以使用.zip 文件部署包来创建或更新 Lambda 函数。请参阅 使用 .zip 文件创建和更新 Ruby Lambda 函数

使用 .zip 文件创建和更新 Ruby Lambda 函数

创建 .zip 部署包后,您可以使用它来创建新的 Lambda 函数或更新现有的 Lambda 函数。您可以使用 Lambda 控制台、AWS Command Line Interface 和 Lambda API 部署 .zip 程序包。您也可以使用 AWS Serverless Application Model(AWS SAM)和 AWS CloudFormation 创建和更新 Lambda 函数。

Lambda 的 .zip 部署包的最大大小为 250MB(已解压缩)。请注意,此限制适用于您上传的所有文件(包括任何 Lambda 层)的组合大小。

Lambda 运行时需要权限才能读取部署包中的文件。在 Linux 权限八进制表示法中,Lambda 对于不可执行文件(rw-r--r--)需要 644 个权限,对于目录和可执行文件需要 755 个权限(rwxr-xr-x)。

在 Linux 和 MacOS 中,使用 chmod 命令更改部署包中文件和目录的文件权限。例如,要为可执行文件提供正确的权限,请运行以下命令。

chmod 755 <filepath>

要在 Windows 中更改文件权限,请参阅 Microsoft Windows 文档中的 Set, View, Change, or Remove Permissions on an Object

使用控制台通过 .zip 文件创建和更新函数

要创建新函数,必须先在控制台中创建该函数,然后上传您的 .zip 归档。要更新现有函数,请打开函数页面,然后按照相同的步骤添加更新的 .zip 文件。

如果您的 .zip 文件小于 50MB,则可以通过直接从本地计算机上传该文件来创建或更新函数。对于大于 50MB 的 .zip 文件,必须首先将您的程序包上传到 Amazon S3 存储桶。有关如何使用 AWS Management Console 将文件上传到 Amazon S3 存储桶的说明,请参阅 Amazon S3 入门。要使用 AWS CLI 上传文件,请参阅《AWS CLI 用户指南》中的移动对象

注意

您无法更改现有函数的部署包类型(.zip 或容器映像)。例如,您无法将容器映像函数转换为使用 .zip 文件归档。您必须创建新函数。

创建新函数(控制台)
  1. 打开 Lambda 控制台的“函数”页面,然后选择创建函数

  2. 选择 Author from scratch (从头开始创作)

  3. Basic information (基本信息) 中,执行以下操作:

    1. 对于函数名称,输入函数的名称。

    2. 对于运行时系统,选择要使用的运行时系统。

    3. (可选)对于架构,选择要用于函数的指令集架构。默认架构为 x86_64。确保您的函数的 .zip 部署包与您选择的指令集架构兼容。

  4. (可选)在 Permissions(权限)下,展开 Change default execution role(更改默认执行角色)。您可以创建新的执行角色,也可以使用现有角色。

  5. 选择创建函数。Lambda 使用您选择的运行时系统创建基本“Hello world”函数。

从本地计算机上传 .zip 归档(控制台)
  1. 在 Lambda 控制台的“函数”页面中,选择要为其上传 .zip 文件的函数。

  2. 选择代码选项卡。

  3. 代码源窗格中,选择上传自

  4. 选择 .zip 文件

  5. 要上传 .zip 文件,请执行以下操作:

    1. 选择上传,然后在文件选择器中选择您的 .zip 文件。

    2. 选择打开

    3. 选择保存

从 Amazon S3 存储桶上传 .zip 归档(控制台)
  1. 在 Lambda 控制台的“函数”页面中,选择要为其上传新 .zip 文件的函数。

  2. 选择代码选项卡。

  3. 代码源窗格中,选择上传自

  4. 选择 Amazon S3 位置

  5. 粘贴 .zip 文件的 Amazon S3 链接 URL,然后选择保存

使用控制台代码编辑器更新 .zip 文件函数

对于某些带有 .zip 部署包的函数,您可以使用 Lambda 控制台的内置代码编辑器直接更新函数代码。要使用此功能,函数必须满足以下条件:

  • 函数必须使用一种解释性语言运行时系统(Python、Node.js 或 Ruby)

  • 函数的部署包必须小于 3MB。

带有容器映像部署包的函数的代码不能直接在控制台中编辑。

要使用控制台代码编辑器更新函数代码。
  1. 打开 Lambda 控制台的“函数”页面,然后选择函数。

  2. 选择代码选项卡。

  3. 代码源窗格中,选择源代码文件并在集成的代码编辑器中对其进行编辑。

  4. 编辑完代码后,选择部署以保存更改并更新函数。

使用 AWS CLI 通过 .zip 文件创建和更新函数

您可以使用 AWS CLI 创建新函数或使用 .zip 文件更新现有函数。使用 create-functionupdate-function-code 命令部署 .zip 程序包。如果您的 .zip 文件小于 50MB,则可以从本地生成计算机上的文件位置上传 .zip 程序包。对于较大的文件,必须从 Amazon S3 存储桶上传 .zip 程序包。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明,请参阅《AWS CLI 用户指南》中的移动对象

注意

如果您使用 AWS CLI 从 Amazon S3 存储桶上传 .zip 文件,则该存储桶必须与您的函数位于同一个 AWS 区域 中。

要通过 AWS CLI 使用 .zip 文件创建新函数,则必须指定以下内容:

  • 函数的名称 (--function-name)

  • 函数的运行时系统 (--runtime)

  • 函数的执行角色 (--role) 的 Amazon 资源名称(ARN)

  • 函数代码 (--handler) 中处理程序方法的名称

还必须指定 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中,请使用 --zip-file 选项指定文件路径,如以下示例命令所示。

aws lambda create-function --function-name myFunction \ --runtime ruby3.2 --handler lambda_function.lambda_handler \ --role arn:aws:iam::111122223333:role/service-role/my-lambda-role \ --zip-file fileb://myFunction.zip

要指定 .zip 文件在 Amazon S3 存储桶中的位置,请使用 --code 选项,如以下示例命令所示。您只需对版本控制对象使用 S3ObjectVersion 参数。

aws lambda create-function --function-name myFunction \ --runtime ruby3.2 --handler lambda_function.lambda_handler \ --role arn:aws:iam::111122223333:role/service-role/my-lambda-role \ --code S3Bucket=myBucketName,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion

要使用 CLI 更新现有函数,请使用 --function-name 参数指定函数的名称。您还必须指定要用于更新函数代码的 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中,请使用 --zip-file 选项指定文件路径,如以下示例命令所示。

aws lambda update-function-code --function-name myFunction \ --zip-file fileb://myFunction.zip

要指定 .zip 文件在 Amazon S3 存储桶中的位置,请使用 --s3-bucket--s3-key 选项,如以下示例命令所示。您只需对版本控制对象使用 --s3-object-version 参数。

aws lambda update-function-code --function-name myFunction \ --s3-bucket myBucketName --s3-key myFileName.zip --s3-object-version myObject Version

使用 Lambda API 通过 .zip 文件创建和更新函数

要使用 .zip 文件归档创建和更新函数,请使用以下 API 操作:

使用 AWS SAM 通过 .zip 文件创建和更新函数

AWS Serverless Application Model(AWS SAM)是一个工具包,可帮助简化在 AWS 上构建和运行无服务器应用程序的过程。您可以在 YAML 或 JSON 模板中为应用程序定义资源,并使用 AWS SAM 命令行界面(AWS SAM CLI)构建、打包和部署应用程序。当您通过 AWS SAM 模板构建 Lambda 函数时,AWS SAM 会使用您的函数代码和您指定的任何依赖项自动创建 .zip 部署包或容器映像。要了解有关使用 AWS SAM 构建和部署 Lambda 函数的更多信息,请参阅《AWS Serverless Application Model 开发人员指南》中的 AWS SAM 入门

您可以使用 AWS SAM 创建使用现有 .zip 文件归档的 Lambda 函数。要使用 AWS SAM 创建 Lambda 函数,您可以将 .zip 文件保存在 Amazon S3 存储桶或生成计算机上的本地文件夹中。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明,请参阅《AWS CLI 用户指南》中的移动对象

在 AWS SAM 模板中,AWS::Serverless::Function 资源将指定 Lambda 函数。在此资源中,设置以下属性以创建使用 .zip 文件归档的函数:

  • PackageType – 设置为 Zip

  • CodeUri – 设置为函数代码的 Amazon S3 URI、本地文件夹的路径或 FunctionCode 对象

  • Runtime – 设置为您选择的运行时系统

使用 AWS SAM,如果 .zip 文件大于 50MB,则不需要先将其上传到 Amazon S3 存储桶。AWS SAM 可以从本地生成计算机上的某个位置上传最大允许大小为 250MB(已解压缩)的 .zip 程序包。

要了解有关在 AWS SAM 中使用 .zip 文件部署函数的更多信息,请参阅《AWS SAM 开发人员指南》中的 AWS::Serverless::Function

使用 AWS CloudFormation 通过 .zip 文件创建和更新函数

您可以使用 AWS CloudFormation 创建使用 .zip 文件归档的 Lambda 函数。要从 .zip 文件创建 Lambda 函数,必须先将您的文件上传到 Amazon S3 存储桶。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明,请参阅《AWS CLI 用户指南》中的移动对象

在 AWS CloudFormation 模板中,AWS::Lambda::Function 资源将指定 Lambda 函数。在此资源中,设置以下属性以创建使用 .zip 文件归档的函数:

  • PackageType – 设置为 Zip

  • Code – 在 S3BucketS3Key 字段中输入 Amazon S3 存储桶名称和 .zip 文件名。

  • Runtime – 设置为您选择的运行时系统

AWS CloudFormation 生成的 .zip 文件不能超过 4MB。要了解有关在 AWS CloudFormation 中使用 .zip 文件部署函数的更多信息,请参阅《AWS CloudFormation 用户指南》中的 AWS::Lambda::Function