无服务器 - 层创建


什么是层?

层是隔离代码块的一种方式。假设您想在应用程序中导入 NumPy 库。您信任该库,并且几乎没有机会更改该库的源代码。因此,如果 NumPy 的源代码使您的应用程序工作区变得混乱,您将不会喜欢它。非常粗略地说,您只是希望 NumPy 位于其他位置,与您的应用程序代码隔离。图层可以让你做到这一点。您可以简单地将所有依赖项(NumPy、Pandas、SciPy 等)捆绑在一个单独的层中,然后在无服务器中的 lambda 函数中简单地引用该层。繁荣!该层中捆绑的所有库现在都可以导入到您的应用程序中。同时,您的应用程序工作区仍然完全整洁。您只需查看要编辑的应用程序代码即可。

层 ARN

照片由Iva RajovicUnsplash上拍摄,表明代码分层分离

层的真正酷之处在于它们可以跨函数共享。假设您部署了一个带有包含 NumPy 和 Pandas 的 python 需求层的 lambda 函数。现在,如果另一个 lambda 函数需要 NumPy,则无需为此函数部署单独的层。您可以简单地使用先前功能的图层,它也可以与新功能很好地配合。

这将为您在部署过程中节省大量宝贵的时间。毕竟,您将仅部署应用程序代码。依赖关系已存在于现有层中。因此,一些开发人员将依赖项层保留在单独的堆栈中。然后他们在所有其他应用程序中使用该层。这样,他们就不需要一次又一次地部署依赖项。毕竟依赖性相当重。NumPy 库本身大约是。80 MB 大。每次更改应用程序代码(可能只有几KB)时都部署依赖项将非常不方便。

添加依赖项层只是一个示例。还有其他几个用例。例如, serverless.com上给出的示例涉及使用 FFmpeg 工具创建 GIF。在该示例中,他们将 FFmpeg 工具存储在一个层中。总之,AWS Lambda 允许我们为每个函数添加最多 5 层。唯一的条件是 5 层和应用程序的总大小应小于 250 MB。

创建 python 需求层

现在让我们看看如何使用无服务器创建和部署包含所有依赖项的层。为此,我们需要serverless-python-requirements插件。该插件仅适用于 Serverless 1.34 及更高版本。因此,如果您的版本 <1.34,您可能需要升级您的无服务器版本。您可以使用安装插件 -

sls plugin install -n serverless-python-requirements

接下来,您在 serverless.yml 的插件部分中添加此插件,并在自定义部分中提及它的配置 -

plugins:
   - serverless-python-requirements
custom:
   pythonRequirements:
      dockerizePip: true
      layer: true

在这里,dockerizePip - true启用 docker 的使用,并允许您将所有依赖项打包到 docker 容器中。我们在前面的章节中讨论了使用 docker 进行打包。Layer - true告诉 Serverless Python 需求应该存储在单独的层中。现在,您可能想知道 Serverless 如何理解要打包哪些依赖项?正如插件章节中提到的,答案位于requirements.txt 文件中。

定义层插件和自定义配置后,您可以将层添加到无服务器中的各个功能中,如下所示 -

functions:
   hello:
      handler: handler.hello
      layers:
         - { Ref: PythonRequirementsLambdaLayer }

关键字PythonRequirementsLambdaLayer来自CloudFormation Reference。通常,它源自层的名称。语法为“LayerNameLambdaLayer”(标题大小写,不含空格)。在我们的例子中,由于层名称是 pythonrequirements,因此引用变为PythonRequirementsLambdaLayer。如果您不确定 lambda 层的名称,可以通过以下步骤获取它 -

  • 运行sls 包

  • 打开 .serverless/cloudformation-template-update-stack.json

  • 搜索“LambdaLayer”

使用同一区域中另一个函数的现有图层

正如我在开头提到的,关于层的一个非常酷的事情是能够在函数中使用现有的层。这可以通过使用现有层的 ARN 轻松完成。使用 ARN 将现有层添加到函数的语法非常简单 -

functions:
   hello:
      handler: handler.hello
      layers:
         - arn:aws:lambda:region:XXXXXX:layer:LayerName:Y

就是这样。现在,具有指定 ARN 的层将与您的函数配合使用。如果该层包含 NumPy 库,您只需在“hello”函数中调用import numpy即可。它将运行而不会出现任何错误。

如果您想知道从哪里可以获得 ARN,实际上很简单。只需导航到 AWS 控制台中包含该层的函数,然后单击“层”。

层 ARN

当然,如果该图层不属于您的帐户,则需要公开共享或专门与您的帐户共享。稍后会详细介绍。

另外,请记住该层应该与您的应用程序兼容。不要期望与 node.js 运行时兼容的层与 python3.6 运行时中创建的函数一起运行。

非要求/通用层

正如一开始提到的,这些层的主要功能是隔离代码块。因此,它们不需要只包含依赖项。它们可以包含您指定的任何代码段。在自定义中的pythonRequirements中调用layer: true是通过serverless-python-requirements插件实现的一种快捷方式。但是,要创建通用层,serverless.yml 中的语法(如serverless 文档中所述)如下 -

layers:
   hello:
      path: layer-dir # required, path to layer contents on disk
      name: ${opt:stage, self:provider.stage, 'dev'}-layerName # optional, Deployed Lambda layer name
      description: Description of what the lambda layer does # optional, Description to publish to AWS
      compatibleRuntimes: # optional, a list of runtimes this layer is compatible with
         - python3.8
      licenseInfo: GPLv3 # optional, a string specifying license information
      # allowedAccounts: # optional, a list of AWS account IDs allowed to access this layer.
      #   - '*'
      # note: uncommenting this will give all AWS users access to this layer unconditionally.
      retain: false # optional, false by default. If true, layer versions are not deleted as new ones are created

由于提供了注释,各种配置参数都是不言自明的。除了“路径”之外,所有其他属性都是可选的。path 属性是您选择的目录的路径,您希望将其与应用程序代码隔离。它将被压缩并发布为您的图层。例如,在serverless 的示例项目中,他们在层中托管 FFmpeg 工具,他们将该工具下载到名为“layer”的单独文件夹中,并在路径属性中指定该文件夹。

layers:
   ffmpeg:
      path: layer

如前所述,我们可以在Layers - 属性中添加最多 5 层。

要在函数中使用这些通用层,您可以使用 CloudFormation 参考或指定 ARN。

允许其他帐户访问图层

只需在“allowedAccounts”属性中提及帐号,即可向更多帐户提供对您的图层的访问权限。例如 -

layers:
   testLayer:
      path: testLayer
      allowedAccounts:
         - 999999999999 # a specific account ID
         - 000123456789 # a different specific account ID

如果您希望该层可公开访问,您可以在 allowedAccounts 中添加“*” -

layers:
   testLayer:
      path: testLayer
      allowedAccounts:
      - '*'

参考