为 Scikit-image 构建自定义 AWS Lambda 层
Build custom AWS Lambda layer for Scikit-image
大纲: 我需要在一些 AWS lambda 函数中使用 scikit-image
,所以我希望构建一个包含 scikit-image
的自定义 AWS lambda 层.
我的问题通常应该适用于任何 python 模块,特别是 scikit-learn,或者我认为一般的任何自定义层。
背景: 经过大量谷歌搜索和阅读,似乎最好的方法是使用 docker 到 运行 AWS lambda 运行本地时间,然后在里面 install/compile scikit-image(或您要查找的任何模块)。完成后,您可以 upload/install 将其作为自定义层发送到 AWS。
这在概念上非常简单,但我正在努力寻找最佳实践方法来做到这一点。我已经开始工作了,但不确定我是按照 best/right/optimal/secure 的方式来做的……
有数百万篇关于此的略有不同的博客文章,AWS 文档本身(恕我直言)过于详细但跳过了一些基本问题。
我基本上一直在尝试关注两个不错的中型帖子,here and here ...向那些人致敬。
我的主要问题是:
- 在哪里可以找到最新的 AWS AMI docker 映像?
有多个(甚至在亚马逊本身)多个 locations/versions 等据称是最新的图像。例如 https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html, or https://cdn.amazonlinux.com/os-images/2.0.20190823.1/.
..这忽略了大量非亚马逊 github 托管的可能性,例如 lambci/lambda:build-python3.6
来自中等帖子 here, or onema/amazonlinux4lambda
from here.
我更愿意使用亚马逊提供的 docker 图片,以确保安全性和最新性。
- AWS lambda 运行时间here, which links to this AMI是docker图像吗?如果是(或不是)你如何下载它运行 在本地?
- 您如何确保知道何时可能需要重建层,因为 AWS lambda 运行time 已被亚马逊更改,这会破坏您使用较旧的 运行time?
的图层
- 在 docker AIM 容器中构建 (在 scikit-image 的情况下编译)pip 安装模块是否更好,或者只是告诉 pip 下载预构建版本 和 hope/trust 它将获得最适合 AMI 的编译库,你 运行ning?
基本上我关心的是稳定性和性能。我想确保在这种情况下为 scikit-image 编译的库尽可能针对 AMI 容器进行了优化。
- 下载并使用 AWS's SAM 来完成所有这些是否更好?(看起来有点矫枉过正和复杂,但它确实解决了问题确保您一直在使用 'correct' AMI docker 容器)
- 周围是否有任何(良好的、可信赖的)预构建 lambda 层的回购(这可能会使所有这些成为一个有争议的问题)?我找了找也没找到。
...感谢任何建议、想法和评论!
我不是这方面的专家,但我碰巧在同一天遇到了完全相同的一组问题。但是我可以回答问题#1 和#2。将它们打乱:
2) AMI 不是 docker 映像,它用于 EC2 实例。
1) 以下是我如何获得合适的 docker 图片:
我安装了 SAM cli 并执行了以下命令:
sam init --runtime python3.7(设置 hello world 示例)
sam build -u(构建应用程序,-u 表示使用容器)
sam build -u 的输出:
Fetching lambci/lambda:build-python3.7 Docker container image
好了。您可以直接从 dockerhub 获取图像,或者如果您安装了 SAM cli,则可以执行 "sam build -u"。现在您有了图像,如果您不想要开销,则不必遵循完整的 SAM 工作流程。
有趣的几天弄清楚了这一点。 ...希望下面的答案对那些努力弄清楚如何制作自定义层(对于 python 以及其他语言)的人有所帮助。
在哪里可以找到最新的 AWS AMI docker 映像?
正如 Greg 上面指出的那样,答案是 "right" docker 用于构建图层的图像在哪里:lambci/lambda:build-python3.7
。这是他们使用的 docker 图像的官方 SAM 存储库。
所有 AWS lambda 运行时间环境的完整列表,而不仅仅是 python,是 here
构建您自己的 AWS lambda 层的最佳方法是什么? ...构建自定义 python 模块层的最佳方法是什么?
迄今为止,我发现的最佳方法是使用 AWS's SAM in combination with some tweaks I used from a great blog here。
调整是必要的,因为(在我写这篇文章的时候)AWS SAM 允许您定义层,但实际上不会为您构建它们。 ...请参见 SAM 组的 github 中的 this request。
我不打算在这里详细解释 - 请查看 bryson3gps blog。他解释得很好,所有的功劳都归功于他。*
好的,使用过程的快速背景:
目前,AWS SAM 不会为您构建您的层。
意思是,如果你为一组模块定义了一个requirement.txt安装在一个层中,它实际上不会install/build它们进入本地目录准备上传到 AWS(就像你用它来定义 lambda 函数一样)。
但是,如果您在 SAM 中定义一个层,它将打包(压缩所有内容并上传到 S3)并部署(定义它在带有 ARN 等的 AWS Cloud 中,因此可以使用)那个层适合你。
让 SAM 也构建图层的方法
目前,从 bryson3Gps 博客 here 中 "fool" SAM 也为您构建图层的方法是
- 在 SAM 中定义虚拟 AWS lambda 函数模板。
然后对于该功能,制作一个 pip
requirement.txt
,SAM 将在构建期间使用它来将您想要的模块加载到您的层中。您实际上不会将此功能用于任何事情。
这需要制作一个定义基本功能的 SAM template.yaml
文件。查看 SAM 教程,然后查看 bryson3gps 的博客。很简单。
在同一 template.yaml
文件中定义一个 AWS 层。再次不太难 - 查看博客
在您的层定义的 SAM 规范中,将 ContentUri
(即查找 files/directories 以压缩并上传到 AWS 的位置)设置为 您在 (1).
中定义的函数的构建位置
因此,当您使用 sam build
时,它会为您构建函数(即为函数处理 requirements.txt
)并将生成的函数包放在一个目录中,以便稍后压缩并发送到 AWS。
但是(这是关键)您定义的图层 ContentUri
指向相同的目录 sam build 用于为(虚拟)函数创建目录。
那么,当您告诉 SAM 将模板作为一个整体打包(发送到 S3)和部署(使用 AWS 配置)时,它将 upload/create 您定义的层,但它也会使用为(虚拟)函数构建的图层的正确内容。
效果很好。
一些额外的提示
1
在 bryson3gps 的博客中,他指出这种方法没有将图层包放在 lambda AMI 目录中的正确位置,默认情况下无法找到它们(对于 python 即 /opt/python).相反,它们被放置在 /opt.
他的解决方法是在导入之前将 /opt 添加到 lambda 脚本中的 sys.path:
sys.path.append('/opt')
import <a module in your layer>
在 sam package
上传到 S3 之前(sam build
之后),您可以进入适当的 .aws-sam/<your package subdir>
目录并将所有内容移动到新的 /python 该包目录中的目录。这导致层模块正确放置在 /opt/python 中,而不仅仅是 /opt.
cd .aws-sam/<wherever you package is>/
mkdir .python
mv * .python
mv .python python
2
如果您正在使用编译代码制作 python 图层(例如我正在使用的 scikit-image)确保 你使用 sam build -u
(带有 -u 标志)。
这将确保构建(pip'ing requirements.txt)将在与 AWS lambda 运行time 匹配的 docker 容器内发生,DL 也将正确的库) 运行时间。
3
如果您包含任何依赖于 numpy 或 scipy 的模块,则 在 sam build -u 之后,但 在 [=160 之前=]、确保进入构建的适当.aws-sam/<your package>
目录并删除numpy和scipy模块依赖项将安装
cd .aws-sam/<wherever you package is>/
rm -r numpy*
rm -f scipy*
相反,您应该在 lambda 函数中指定使用 AWS 提供的 numpy/scipy 层。
我找不到告诉 SAM 使用 --no_dep 运行 pip 的方法,所以必须手动执行此操作
从 v0.50.0 开始,sam cli 有 direct support for building layers。您使用有关要使用的运行时策略的元数据来装饰 AWS::Serverless::LayerVersion
资源。
MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer description
ContentUri: 'my_layer/'
CompatibleRuntimes:
- python3.8
Metadata:
BuildMethod: python3.8
大纲: 我需要在一些 AWS lambda 函数中使用 scikit-image
,所以我希望构建一个包含 scikit-image
的自定义 AWS lambda 层.
我的问题通常应该适用于任何 python 模块,特别是 scikit-learn,或者我认为一般的任何自定义层。
背景: 经过大量谷歌搜索和阅读,似乎最好的方法是使用 docker 到 运行 AWS lambda 运行本地时间,然后在里面 install/compile scikit-image(或您要查找的任何模块)。完成后,您可以 upload/install 将其作为自定义层发送到 AWS。
这在概念上非常简单,但我正在努力寻找最佳实践方法来做到这一点。我已经开始工作了,但不确定我是按照 best/right/optimal/secure 的方式来做的…… 有数百万篇关于此的略有不同的博客文章,AWS 文档本身(恕我直言)过于详细但跳过了一些基本问题。
我基本上一直在尝试关注两个不错的中型帖子,here and here ...向那些人致敬。
我的主要问题是:
- 在哪里可以找到最新的 AWS AMI docker 映像?
有多个(甚至在亚马逊本身)多个 locations/versions 等据称是最新的图像。例如 https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html, or https://cdn.amazonlinux.com/os-images/2.0.20190823.1/.
..这忽略了大量非亚马逊 github 托管的可能性,例如 lambci/lambda:build-python3.6
来自中等帖子 here, or onema/amazonlinux4lambda
from here.
我更愿意使用亚马逊提供的 docker 图片,以确保安全性和最新性。
- AWS lambda 运行时间here, which links to this AMI是docker图像吗?如果是(或不是)你如何下载它运行 在本地?
- 您如何确保知道何时可能需要重建层,因为 AWS lambda 运行time 已被亚马逊更改,这会破坏您使用较旧的 运行time? 的图层
- 在 docker AIM 容器中构建 (在 scikit-image 的情况下编译)pip 安装模块是否更好,或者只是告诉 pip 下载预构建版本 和 hope/trust 它将获得最适合 AMI 的编译库,你 运行ning?
基本上我关心的是稳定性和性能。我想确保在这种情况下为 scikit-image 编译的库尽可能针对 AMI 容器进行了优化。
- 下载并使用 AWS's SAM 来完成所有这些是否更好?(看起来有点矫枉过正和复杂,但它确实解决了问题确保您一直在使用 'correct' AMI docker 容器)
- 周围是否有任何(良好的、可信赖的)预构建 lambda 层的回购(这可能会使所有这些成为一个有争议的问题)?我找了找也没找到。
...感谢任何建议、想法和评论!
我不是这方面的专家,但我碰巧在同一天遇到了完全相同的一组问题。但是我可以回答问题#1 和#2。将它们打乱:
2) AMI 不是 docker 映像,它用于 EC2 实例。
1) 以下是我如何获得合适的 docker 图片:
我安装了 SAM cli 并执行了以下命令:
sam init --runtime python3.7(设置 hello world 示例)
sam build -u(构建应用程序,-u 表示使用容器)
sam build -u 的输出:
Fetching lambci/lambda:build-python3.7 Docker container image
好了。您可以直接从 dockerhub 获取图像,或者如果您安装了 SAM cli,则可以执行 "sam build -u"。现在您有了图像,如果您不想要开销,则不必遵循完整的 SAM 工作流程。
有趣的几天弄清楚了这一点。 ...希望下面的答案对那些努力弄清楚如何制作自定义层(对于 python 以及其他语言)的人有所帮助。
在哪里可以找到最新的 AWS AMI docker 映像?
正如 Greg 上面指出的那样,答案是 "right" docker 用于构建图层的图像在哪里:lambci/lambda:build-python3.7
。这是他们使用的 docker 图像的官方 SAM 存储库。
所有 AWS lambda 运行时间环境的完整列表,而不仅仅是 python,是 here
构建您自己的 AWS lambda 层的最佳方法是什么? ...构建自定义 python 模块层的最佳方法是什么?
迄今为止,我发现的最佳方法是使用 AWS's SAM in combination with some tweaks I used from a great blog here。
调整是必要的,因为(在我写这篇文章的时候)AWS SAM 允许您定义层,但实际上不会为您构建它们。 ...请参见 SAM 组的 github 中的 this request。
我不打算在这里详细解释 - 请查看 bryson3gps blog。他解释得很好,所有的功劳都归功于他。*
好的,使用过程的快速背景:
目前,AWS SAM 不会为您构建您的层。
意思是,如果你为一组模块定义了一个requirement.txt安装在一个层中,它实际上不会install/build它们进入本地目录准备上传到 AWS(就像你用它来定义 lambda 函数一样)。
但是,如果您在 SAM 中定义一个层,它将打包(压缩所有内容并上传到 S3)并部署(定义它在带有 ARN 等的 AWS Cloud 中,因此可以使用)那个层适合你。
让 SAM 也构建图层的方法
目前,从 bryson3Gps 博客 here 中 "fool" SAM 也为您构建图层的方法是
- 在 SAM 中定义虚拟 AWS lambda 函数模板。
然后对于该功能,制作一个 pip
requirement.txt
,SAM 将在构建期间使用它来将您想要的模块加载到您的层中。您实际上不会将此功能用于任何事情。
这需要制作一个定义基本功能的 SAM template.yaml
文件。查看 SAM 教程,然后查看 bryson3gps 的博客。很简单。
在同一
template.yaml
文件中定义一个 AWS 层。再次不太难 - 查看博客在您的层定义的 SAM 规范中,将
ContentUri
(即查找 files/directories 以压缩并上传到 AWS 的位置)设置为 您在 (1). 中定义的函数的构建位置
因此,当您使用 sam build
时,它会为您构建函数(即为函数处理 requirements.txt
)并将生成的函数包放在一个目录中,以便稍后压缩并发送到 AWS。
但是(这是关键)您定义的图层 ContentUri
指向相同的目录 sam build 用于为(虚拟)函数创建目录。
那么,当您告诉 SAM 将模板作为一个整体打包(发送到 S3)和部署(使用 AWS 配置)时,它将 upload/create 您定义的层,但它也会使用为(虚拟)函数构建的图层的正确内容。
效果很好。
一些额外的提示
1
在 bryson3gps 的博客中,他指出这种方法没有将图层包放在 lambda AMI 目录中的正确位置,默认情况下无法找到它们(对于 python 即 /opt/python).相反,它们被放置在 /opt.
他的解决方法是在导入之前将 /opt 添加到 lambda 脚本中的 sys.path:
sys.path.append('/opt')
import <a module in your layer>
在 sam package
上传到 S3 之前(sam build
之后),您可以进入适当的 .aws-sam/<your package subdir>
目录并将所有内容移动到新的 /python 该包目录中的目录。这导致层模块正确放置在 /opt/python 中,而不仅仅是 /opt.
cd .aws-sam/<wherever you package is>/
mkdir .python
mv * .python
mv .python python
2
如果您正在使用编译代码制作 python 图层(例如我正在使用的 scikit-image)确保 你使用 sam build -u
(带有 -u 标志)。
这将确保构建(pip'ing requirements.txt)将在与 AWS lambda 运行time 匹配的 docker 容器内发生,DL 也将正确的库) 运行时间。
3
如果您包含任何依赖于 numpy 或 scipy 的模块,则 在 sam build -u 之后,但 在 [=160 之前=]、确保进入构建的适当.aws-sam/<your package>
目录并删除numpy和scipy模块依赖项将安装
cd .aws-sam/<wherever you package is>/
rm -r numpy*
rm -f scipy*
相反,您应该在 lambda 函数中指定使用 AWS 提供的 numpy/scipy 层。
我找不到告诉 SAM 使用 --no_dep 运行 pip 的方法,所以必须手动执行此操作
从 v0.50.0 开始,sam cli 有 direct support for building layers。您使用有关要使用的运行时策略的元数据来装饰 AWS::Serverless::LayerVersion
资源。
MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer description
ContentUri: 'my_layer/'
CompatibleRuntimes:
- python3.8
Metadata:
BuildMethod: python3.8