Ric*_*ard 7 python-3.x scikit-learn scikit-image aws-lambda
大纲:我需要scikit-image在一些 AWS lambda 函数中使用,所以我希望构建一个包含scikit-image.
我的问题一般应该适用于任何 python 模块,特别是 scikit-learn,或者我认为一般的任何自定义层。
背景:经过大量谷歌搜索和阅读后,似乎最好的方法是使用 docker 在本地运行 AWS lambda 运行时,然后在那里安装/编译 scikit-image(或您正在寻找的任何模块)。完成后,您可以将其作为自定义层上传/安装到 AWS。
这在概念上非常简单,但我正在努力使用最佳实践方法来做到这一点。我已经完成了这项工作,但不确定我是否以最好/正确/最佳/安全的方式做这件事…… 有数百万篇关于此的完全不同的博客文章,AWS 文档本身也是(恕我直言)详细但略过一些基本问题。
我一直试图基本上遵循两个很好的中等职位,这里和这里......对这些人的敬意。
我的主要问题是:
对于所谓的最新图像,有多个(甚至在亚马逊本身)多个位置/版本等。例如https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html或https://cdn.amazonlinux.com/os-images/2.0.20190823.1/。
..这忽略了大量非亚马逊 github 托管的可能性,例如lambci/lambda:build-python3.6来自此处的中等帖子或onema/amazonlinux4lambda来自此处。
为了安全性和最新性,我更喜欢使用亚马逊提供的 docker 镜像。
基本上在这里我关心稳定性和性能。我想确保在这种情况下为 scikit-image 编译的库尽可能针对 AMI 容器进行优化。
...感谢您的任何建议、想法和评论!
有趣的几天弄清楚这一点。...希望下面的答案对任何努力弄清楚如何制作自定义层(适用于 python 以及其他语言)的人有所帮助。
在哪里可以找到最新的 AWS AMI docker 镜像?
答案,正如上面 Greg 指出的,用于构建层的“正确”docker 镜像在哪里:lambci/lambda:build-python3.7. 这是他们使用的 docker 镜像的官方 SAM 存储库。
所有 AWS lambda 运行时环境的完整列表,不仅仅是 python,在这里
构建自己的 AWS lambda 层的最佳方法是什么?...构建自定义python模块层的最佳方法是什么?
迄今为止,我发现的最好方法是将AWS 的 SAM 与我从这里的一个很棒的博客中使用的一些调整结合使用。
需要进行调整是因为(在我撰写本文时)AWS SAM 允许您定义层,但实际上不会为您构建它们。...从 SAM 组的 github 中查看此请求。
我不打算在这里详细解释这一点 - 相反,请查看bryson3gps 博客。他解释得很好,所有功劳都归功于他。 *
目前,AWS SAM 不会为您构建层。
意思是,如果您为要安装在层中的一组模块定义了一个 requirements.txt,它实际上不会将它们安装/构建到准备上传到 AWS 的本地目录中(就像您使用它来定义一个 lambda功能)。
但是,如果您在 SAM 中定义一个层,它将为您打包(压缩所有内容并上传到 S3)并部署(在 AWS 云中使用 ARN 等定义它以便可以使用)该层。
目前,从这里的 bryson3Gps 博客中“愚弄”SAM 为您构建图层的技巧是
requirement.txt,SAM 将在构建期间使用该 pip将您想要的模块加载到您的层中。您实际上不会将此功能用于任何事情。这需要制作一个template.yaml定义基本功能的 SAM文件。查看 SAM 教程,然后查看 bryson3gps 的博客。这很容易。
在同一template.yaml文件中定义 AWS 层。再次不太难 - 查看博客
在层定义的 SAM 规范中,将 ContentUri(即它查找文件/目录压缩并上传到 AWS的位置)设置为您在 (1) 中定义的函数的构建位置。
因此,当您使用 时sam build,它会为您构建函数(即为requirements.txt函数处理)并将生成的函数包放在一个目录中,以便稍后压缩并发送到 AWS。
但是(这是关键)您定义的层ContentUri指向了 sam build 用于为(虚拟)函数创建目录的同一目录。
那么,当您告诉 SAM 为整个模板打包(发送到 S3)和部署(使用 AWS 配置)时,它会上传/创建您定义的层,但它也会使用该层的正确内容为(虚拟)功能构建的。
它运作良好。
1
在 bryson3gps 的博客中,他指出这种方法没有将图层包放在 lambda AMI 目录中的正确位置,以便默认情况下可以找到它们(对于 /opt/python 的 python)。相反,它们被放置在 /opt 中。
他的解决方法是在导入之前将 /opt 添加到 lambda 脚本中的 sys.path 中:
sys.path.append('/opt')
import <a module in your layer>
Run Code Online (Sandbox Code Playgroud)
而不是这样做,在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
Run Code Online (Sandbox Code Playgroud)
2
如果您使用编译代码(例如我正在使用的 scikit-image)制作python 层,请确保您使用sam build -u(使用 -u 标志)。
这将确保构建(pip'ing requirements.txt)将发生在与 AWS lambda 运行时匹配的 docker 容器内,因此将 DL 正确的库)用于运行时。
3
如果您包含任何依赖于 numpy 或 scipy 的模块,则在 sam build -u 之后,但在 package/deploy 之前,请确保进入.aws-sam/<your package>构建的适当目录并删除依赖项将安装的 numpy 和 scipy 模块
cd .aws-sam/<wherever you package is>/
rm -r numpy*
rm -f scipy*
Run Code Online (Sandbox Code Playgroud)
相反,您应该在 lambda 函数中指定使用 AWS 提供的 numpy/scipy 层。
我找不到告诉 SAM 使用 --no_dep 运行 pip 的方法,因此必须手动执行此操作
从 v0.50.0 开始,sam cli直接支持构建层。您AWS::Serverless::LayerVersion可以使用有关要使用的运行时策略的元数据来装饰您的资源。
MyLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer description
ContentUri: 'my_layer/'
CompatibleRuntimes:
- python3.8
Metadata:
BuildMethod: python3.8
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2959 次 |
| 最近记录: |