我正在尝试为运行 golang 处理程序的 lambda 创建一个 docker 映像,但该映像不来自 public.ecr.aws/lambda/go:1
或 public.ecr.aws/lambda/provided:al2
。
我尝试按照 aws 文档中的步骤获取替代基本映像。
还有这个教程: https://hichaelmart.medium.com/using-container-images-with-aws-lambda-7ffbd23697f1
这根本行不通。 lambda 启动但不会处理任何请求。提出请求:
curl -xpost "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"body":{"name":"test"}}'
一去不复返。
如果我使用 public.ecr.aws/lambda/go:1
它工作正常。
据我所知,它可能缺少“运行时接口”,但他们的 go api 声称将其实现为处理程序代码的包装器。
这是我的 dockerfile
from alpine:3.16 add https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie run chmod 755 /usr/bin/aws-lambda-rie workdir /var/task copy main ./ entrypoint ["/usr/bin/aws-lambda-rie", "/var/task/main"]
这是我的 lambda 处理程序
type myevent struct { name string `json:"name"` } func handlerequest(_ context.context, name myevent) (string, error) { return fmt.sprintf("hello %s!", name.name), nil } func main() { lambda.start(handlerequest) }
服务请求的 docker 上的日志是
15 May 2023 06:34:03,985 [INFO] (rapid) exec '/var/task/main' (cwd=/var/task, handler=/var/task/main) 15 May 2023 06:34:08,178 [INFO] (rapid) extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory 15 May 2023 06:34:08,180 [INFO] (rapid) Configuring and starting Operator Domain 15 May 2023 06:34:08,182 [INFO] (rapid) Starting runtime domain 15 May 2023 06:34:08,188 [WARNING] (rapid) Cannot list external agents error=open /opt/extensions: no such file or directory START RequestId: dfbc9842-2a7b-4a3e-bfd2-2434aa126f63 Version: $LATEST 15 May 2023 06:34:08,198 [INFO] (rapid) Starting runtime without AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN , Expected?: false START RequestId: 5e0f07ac-46a3-42e0-8a60-851293544020 Version: $LATEST
任何有关我需要添加到 dockerfile 的内容的帮助将不胜感激。
尚不清楚 main
二进制文件是如何构建的,但很可能它不是为 alpine
构建的。如果您检查容器的日志,您应该看到如下内容:
[warning] (rapid) first fatal error stored in appctx: runtime.invalidentrypoint [error] (rapid) init failed error=fork/exec /var/task/main: no such file or directory invokeid=
解决办法是:
main
的构建目的;alpine
重建 main
二进制文件。下面的 dockerfile
显示了如何为 alpine
构建 main
二进制文件:
# ==== build stage ==== from golang:1.18.4-alpine3.16 as build workdir /app copy . . run go build -o main . # ==== final stage ==== from alpine:3.16.1 add https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie run chmod 755 /usr/bin/aws-lambda-rie workdir /var/task copy --from=build /app/main ./ entrypoint ["/usr/bin/aws-lambda-rie", "/var/task/main"]
我也很好奇为什么 aws-lambda-rie
可以在 alpine
上运行。我发现它是用 cgo_enabled=0
构建的(请参阅 此处)。我们可以做同样的事情,因为简单的演示不需要 cgo:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
这个 main
二进制文件也适用于 alpine
。