首页 > 后端开发 > Golang > 使用 Dockerfile 和 Makefile 在 AWS SAM 上自定义 Go 构建

使用 Dockerfile 和 Makefile 在 AWS SAM 上自定义 Go 构建

Susan Sarandon
发布: 2025-01-20 14:27:09
原创
857 人浏览过

Customize Go Builds on AWS SAM with Dockerfiles and Makefiles

这篇文章是使用 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 如何编译代码和管理库链接。

将 Go 项目部署到 AWS

存在两种部署方法:

压缩文件?

本地编译并将可执行文件以 .zip 文件形式发送到 AWS。 AWS 将可执行文件复制到 Docker 容器。这提供了最快的冷启动。

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 指定的位置。

Docker 镜像?

在根目录创建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>
登录后复制
登录后复制

注意MetadataPackageType: ImageDockerBuildArgsENTRY_POINT 传递 Dockerfile,允许所有 lambda 使用单个 Dockerfile

结论

此详细说明提供了一种使用 Zip 文件和 Docker 映像在 AWS SAM 中管理 Go 构建的全面方法。 选择取决于构建速度与部署一致性的优先级。

以上是使用 Dockerfile 和 Makefile 在 AWS SAM 上自定义 Go 构建的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板