这篇文章是使用 AWS SAM 和 Go 构建应用程序系列的延续,以第一部分为基础。 上一章强调了 AWS 在构建无冗余代码的可扩展 Go 项目方面的有限指导。
本文演示了使用 Dockerfile 和 Makefile 管理构建过程的技术。
附带的代码可以在这里获取:https://www.php.cn/link/5655cf23be4dda7082c8bb3a8d8f8016。 探索不同的 Git 分支的不同用例。
我们开始吧!
开发新的项目结构后,我选择 Nix 进行依赖管理(语言、工具、库)。 Nix 通过创建具有指定依赖项的临时 shell 来进行操作。
我在执行 Nix shell 中构建的二进制文件时遇到错误:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
这会停止 Lambda 的执行。 调试揭示了根本原因:Go 有时会动态地将 C 库链接到可执行文件,指定系统路径。 链接到 Nix 构建的可执行文件的库是:
<code>$ ldd bootstrap linux-vdso.so.1 (0x00007ffff7fc4000) libresolv.so.2 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libresolv.so.2 (0x00007ffff7fac000) libpthread.so.0 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libpthread.so.0 (0x00007ffff7fa7000) libc.so.6 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/libc.so.6 (0x00007ffff7c00000) /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib/ld-linux-x86-64.so.2 => /nix/store/65h17wjrrlsj2rj540igylrx7fqcd6vq-glibc-2.40-36/lib64/ld-linux-x86-64.so.2 (0x00007ffff7fc6000)</code>
Nix 的非标准依赖存储与 Lambda 的隔离 Docker 容器相结合,阻止 Lambda 定位这些库,因为它们只存在于我本地的 Nix 安装中。 需要一个解决方案来指导 AWS SAM 如何编译代码和管理库链接。
存在两种部署方法:
本地编译并将可执行文件以 .zip 文件形式发送到 AWS。 AWS 将可执行文件复制到 Docker 容器。这提供了最快的冷启动。
向 AWS 提供在执行 Docker 容器中进行编译的指令。这确保了兼容性,但会导致冷启动速度变慢。
我选择 Dockerfiles 继续使用 Nix,但这两种方法都在下面介绍。
对于 Zip 文件,请使用此项目结构(注意 Makefile):
<code>. ├── cmd/ │ ├── function1/ │ │ └── function1.go # contains main() │ └── function2/ │ └── function2.go # contains main() ├── internal/ │ └── SHAREDFUNC.go ├── Makefile ├── go.mod ├── go.sum ├── samconfig.toml └── template.yaml</code>
Makefile 使用 build-<function_name>
模式定义每个函数的构建命令(AWS SAM 需要):
<code>.PHONY: build build: sam build build-HelloWorldFunction: GOARCH=amd64 GOOS=linux go build -tags lambda.norpc -o bootstrap ./cmd/function1/main.go cp ./bootstrap $(ARTIFACTS_DIR) build-ByeWorldFunction: GOARCH=amd64 GOOS=linux go build -tags lambda.norpc -o bootstrap ./cmd/function2/main.go cp ./bootstrap $(ARTIFACTS_DIR)</code>
通知 SAM 此过程:
<code> HelloWorldFunction: Type: AWS::Serverless::Function Metadata: BuildMethod: makefile Properties: CodeUri: ./ Handler: bootstrap Runtime: provided.al2023 Architectures: - x86_64 Events: CatchAll: Type: Api Properties: Path: /hello Method: GET</code>
BuildMethod: makefile
告诉 SAM 使用 Makefile,位于 CodeUri
指定的位置。
在根目录创建Dockerfile
和.dockerignore
:
<code>. ├── cmd/ │ ├── function1/ │ │ └── function1.go # contains main() │ └── function2/ │ └── function2.go # contains main() ├── internal/ │ └── SHAREDFUNC.go ├── Dockerfile ├── .dockerignore ├── go.mod ├── go.sum ├── samconfig.toml └── template.yaml</code>
Dockerfile
指定构建步骤。 ARG ENTRY_POINT
指定构建时的 lambda 入口点:
<code>FROM public.ecr.aws/docker/library/golang:1.19 as build-image ARG ENTRY_POINT # !IMPORTANT WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -tags lambda.norpc -o lambda-handler ${ENTRY_POINT} FROM public.ecr.aws/lambda/provided:al2023 COPY --from=build-image /src/lambda-handler . ENTRYPOINT ./lambda-handler</code>
修改template.yaml
:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
注意Metadata
和PackageType: Image
。 DockerBuildArgs
从 ENTRY_POINT
传递 Dockerfile
,允许所有 lambda 使用单个 Dockerfile
。
此详细说明提供了一种使用 Zip 文件和 Docker 映像在 AWS SAM 中管理 Go 构建的全面方法。 选择取决于构建速度与部署一致性的优先级。
以上是使用 Dockerfile 和 Makefile 在 AWS SAM 上自定义 Go 构建的详细内容。更多信息请关注PHP中文网其他相关文章!