繁体   English   中英

应该在基于 PHP 的 Docker AWS lambda 的容器中运行什么?

[英]What should be run in a container for a PHP-based Docker AWS lambda?

PHP 不是 AWS Lambda 中本机支持的语言,但我想我会尝试使用自定义 Docker 映像来使其工作。 我正在使用这个官方 AWS 示例来构建图像。

我还不太明白这些片段。 我将在这篇文章中添加我拥有的文件。

首先,我的 Dockerfile:

# Demo of a PHP-based lambda
#
# See example:
# https://github.com/aws-samples/php-examples-for-aws-lambda/blob/master/0.7-PHP-Lambda-functions-with-Docker-container-images/Dockerfile

FROM php:8.0-cli-alpine

WORKDIR /root

# Install Composer
COPY bin bin
RUN sh /root/bin/install-composer.sh
RUN php /root/composer.phar --version

# Install Composer deps
COPY composer.json composer.lock /root/
RUN php composer.phar install

# Install runtimes
COPY runtime /var/runtime
COPY src /var/task/

# Entrypoint
CMD ["index"]

基于这个例子,我还有:

  • /var/runtime/bootstrap的 PHP 侦听器程序(几乎是示例存储库的逐字副本)
  • 引导程序加载的/root/vendor/...中的 Composer 依赖项
  • /var/task/index.php一个简单索引文件(示例 repo 的逐字副本)

我所做的一项更改是将映像基于来自 PHP 的 Alpine 映像,而不是使用 Amazon Linux 映像。 我想知道,亚马逊图像中是否有需要的东西?

我使用的测试是 AWS Lambda UI 中的“hello world”:

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

无论如何,我已经使用docker logindocker push将图像发送到 ECR。 当我在 AWS 仪表板中运行 hello world 测试时,我在 CloudWatch 中收到了这组错误日志:

2021-11-13T19:12:12.449+00:00   IMAGE Launch error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied Entrypoint: [docker-php-entrypoint] Cmd: [index] WorkingDir: [/root]
2021-11-13T19:12:12.493+00:00   START RequestId: 38da1e10-4c93-4109-be10-32c58f83a2fb Version: $LATEST
2021-11-13T19:12:12.502+00:00   IMAGE Launch error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied Entrypoint: [docker-php-entrypoint] Cmd: [index] WorkingDir: [/root]
2021-11-13T19:12:12.504+00:00   END RequestId: 38da1e10-4c93-4109-be10-32c58f83a2fb
2021-11-13T19:12:12.504+00:00   REPORT RequestId: 38da1e10-4c93-4109-be10-32c58f83a2fb Duration: 9.20 ms Billed Duration: 10 ms Memory Size: 128 MB Max Memory Used: 3 MB
2021-11-13T19:12:12.504+00:00   RequestId: 38da1e10-4c93-4109-be10-32c58f83a2fb Error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied Runtime.InvalidEntrypoint 

这很有意义,因为我也不理解“索引”的入口点,但它在示例 Dockerfile 中作为CMD存在。 这是某物的别名吗? 我倾向于使用类似php /var/runtime/bootstrap东西,但我宁愿理解事物,而不是猜测。

我相信我可以使用Lambda RIE在本地测试这个,但我想知道这是否会告诉我我已经知道的 - 我需要修复CMD

对于它的价值,我也看不到index.php文件是如何在 lambda 中触发的。 它是如何被调用的?

更新

我想知道示例中的父图像 ( public.ecr.aws/lambda/provided ) 是否有一个ENTRYPOINT可以阐明显然令人困惑的CMD 我想知道我接下来是否会调查。

更新 2

我可能不得不使用 Amazon Linux 映像父级的想法是错误的转向 -此官方资源显示了标准 Python 和 Node 映像的使用。

我决定尝试修复主要的 Docker 命令:

CMD ["php", "/var/runtime/bootstrap"]

然而它不喜欢这样:

START RequestId: d95a29d3-6764-4bae-9976-09830c1c17af Version: $LATEST
IMAGE   Launch error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied Entrypoint: [docker-php-entrypoint] Cmd: [php,/var/runtime/bootstrap]   WorkingDir: [/root]
IMAGE   Launch error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied Entrypoint: [docker-php-entrypoint] Cmd: [php,/var/runtime/bootstrap]   WorkingDir: [/root]
END RequestId: d95a29d3-6764-4bae-9976-09830c1c17af
REPORT RequestId: d95a29d3-6764-4bae-9976-09830c1c17af  Duration: 19.88 ms  Billed Duration: 20 ms  Memory Size: 128 MB Max Memory Used: 3 MB   
RequestId: d95a29d3-6764-4bae-9976-09830c1c17af Error: fork/exec /usr/local/bin/docker-php-entrypoint: permission denied
Runtime.InvalidEntrypoint

更新 3

无论我做什么,我似乎都遇到了入口点的问题。 我什至尝试了一个运行时脚本在它不喜欢的各种二进制文件上chmod +x ,但是当然,如​​果我尝试在ENTRYPOINT启动它,容器认为/bin/sh无法执行。 这变得相当愚蠢 - 容器在 Lambda 环境中行为不正确。

更新 4

我现在试图远离 Alpine,以防更标准的操作系统能够正常工作。 没有快乐 - 我也一样。 我现在正处于随机尝试的阶段,考虑到构建-推送-安装循环很麻烦,所以这个过程相当缓慢。

这个问题看起来很有希望,但是将引导文件放在/var/task似乎直接与我正在使用的示例背道而驰。

这个问题很棘手,因为有两个主要的连锁问题——一个看似过度的权限要求,以及让我印象深刻的是对 ENTRYPOINT/CMD 系统的大量非标准使用。

工作解决方案

工作的 Dockerfile 如下:

# Demo of a PHP-based lambda
#
# See example:
# https://github.com/aws-samples/php-examples-for-aws-lambda/blob/master/0.7-PHP-Lambda-functions-with-Docker-container-images/Dockerfile

FROM php:8.0-cli-alpine

WORKDIR /root

# Install Composer
COPY bin bin
RUN sh /root/bin/install-composer.sh
RUN php /root/composer.phar --version

# Install Composer deps
COPY composer.json composer.lock /root/
# Move deps to /opt, /root has significant permission issues
RUN php /root/composer.phar install && \
    mv /root/vendor /opt/vendor

# Install runtimes
COPY runtime/bootstrap /var/runtime/
COPY src/index.php /var/task/

RUN chmod 777 /usr/local/bin/php /var/task/* /var/runtime/*

# The entrypoint seems to be the main handler
# and the CMD specifies what kind of event to process
WORKDIR /var/task
ENTRYPOINT ["/var/runtime/bootstrap"]
CMD ["index"]

因此,这解决了我关于 Amazon Linux 的一个烦人的问题——这不是必需的。 请注意,虽然我在/root安装了 Composer 依赖项,但它们不能留在那里 - 即使它们上的777 perms 似乎也不够。

如您所见,我对/var内容使用了 777 权限。 755 可能有效,甚至 750 也可能有效 - 但这里的关键是亚马逊似乎是一个不是构建(root)用户的用户。 这让我很受挫。

现在ENTRYPOINT用于运行引导脚本,该脚本似乎在 AWS 端的事件和/var/tasks “用例”之间进行一般调解。 Docker 入口点的正常用途是作为CMD的命令包装器,因此将CMD用作“默认 lambda 类型”似乎严重违反了最小意外原则。 我原以为 lambda 类型将由传入事件定义,而不是由任何 lambda 端设置定义。

测试

为了测试这个 lambda,我在 Lambda UI 中使用了这个事件:

{
  "queryStringParameters": { "name": "halfer" }
}

演示代码将响应:

{
  "statusCode": 200,
  "headers": {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Headers": "Content-Type",
    "Access-Control-Allow-Methods": "OPTIONS,POST"
  },
  "body": "Hello, halfer"
}

可以说这感觉相当脆弱。 诚然,演示代码不是生产质量,但即便如此,我怀疑这需要一个管道在合并或部署之前进行真正的 AWS Lambda 测试。

表现

这就是为什么 lambda 很诱人的原因,尤其是对于 cron 之类的不频繁调用 - 它们被快速实例化并迅速消亡,没有运行基础设施。 在我的一次演示电话中,我有:

Init duration     188.75 ms
Duration           39.45 ms
Billed duration   229 ms

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM