带有本机扩展的 Ruby gem 不适用于 AWS Lambda

Zag*_*ags 4 ruby rubygems amazon-web-services aws-lambda

我有一个尝试在 AWS Lambda 上运行的 ruby​​ 脚本。我如何让它使用带有本机扩展的 Ruby gem?

我已经安装了我的 Ruby gembundle install --deployment并将它们包含在我的部署中。当我在 lambda 上运行该函数时,出现错误:

忽略 oj-2.18.5,因为没有构建它的扩展。尝试: gem pristine oj --version 2.18.5

加载处理程序时初始化错误

{

"errorMessage": "libruby.so.2.5: 无法打开共享对象文件:没有那个文件或目录 - /opt/ruby/gems/2.5.0/gems/oj-2.18.5/lib/oj/oj.so" ,

...

我尝试在 lambda 代码本身和 lambda 层中包含依赖项。唯一改变的是错误消息中的路径。

Lambda 能够找到我的红宝石宝石。当它们位于错误的位置时,我会收到不同的错误。

/opt/ruby/gems/2.5.0/gems/oj-2.18.5/lib/oj/oj.so 确实存在。

我已经用bundle installUbuntu 和 AWS-linux生成的文件尝试过这个。在这两个系统上,bundle 通知我它是“使用本机扩展安装 oj 2.18.5”。

如果我将 的副本上传libruby.so到我的 lambda,并将环境变量LD_LIBRARY_PATH设置为其位置并使用安装在 AWS-linux 上的一组依赖项修复上面列出的错误,但只会给我一个更不透明的错误:

/lib64/libc.so.6:未找到版本“GLIBC_2.25”(/opt/ruby/lib/libruby.so.2.5 需要)

Zag*_*ags 6

运行ldd在宝石/ OJ-2.18.5 / lib目录/ OJ / oj.so澄清的第一个错误。问题不是oj.so不存在,而是libruby.so.2.5不存在。第二个问题是当前的 Ruby lambda 有 glibc 版本 2.17,其中 AWS-linux 带有 glibc 版本 2.25。

这里的基本问题是,如果您有本机依赖项,​​您需要将 gem 安装在与它们将运行的系统相同的系统上。我发现做到这一点的最好方法是使用 docker。 https://github.com/lambci/docker-lambda有 lambda 安装的 docker 镜像。

对于 ruby​​,请执行以下操作:

  1. 构建 docker ruby​​ 镜像
  2. 将您的 gemfile 复制到原始目录中
  3. 从该目录运行: docker run -v "$PWD":/var/task --entrypoint bundle lambci/lambda-base:ruby2.5 install --path=/var/task

这将为您提供一个名为ruby与 lambda 兼容的版本依赖项的文件夹。

如果您打算将此输出与 lambda 层一起使用,请记住 bunlde 生成的文件结构是ruby/2.5.0/...并且需要ruby/gems/2.5.0/...在上传之前。


ces*_*ves 6

问题正是如您所说,总结一下:本机扩展 gem 需要在与运行它们相同的环境中构建。因此,在将vendor上传到aws之前,我们必须在类似于lambda的环境中安装gems。


要以符合 lambda 的方式构建供应商/捆绑包,请使用以下 docker 容器:

docker run --rm -v "$PWD":/var/task lambci/lambda:build-ruby2.7 bundle install --deployment
Run Code Online (Sandbox Code Playgroud)

这将为您提供有效的供应商/捆绑包依赖性。

您可以运行另一个容器来检查该功能是否有效:

docker run --rm -v $PWD:/var/task:ro,delegated lambci/lambda:ruby2.7 lambda_handler.lambda_handler
Run Code Online (Sandbox Code Playgroud)

完整的图像列表在这里: https://github.com/lambci/docker-lambda

这个问题已经有 1 年历史了,但我不得不搜索大约 2 个小时才能解决与 gem nokogiri 完全相同的问题,所以我认为这可能对某人有用。

希望这能让您省去谷歌搜索的时间!