這篇文章是使用 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中文網其他相關文章!