Dieser Beitrag setzt die Serie Apps erstellen mit AWS SAM and Go fort und baut auf dem ersten Teil auf. Im vorherigen Kapitel wurde die begrenzte Anleitung von AWS zur Strukturierung skalierbarer Go-Projekte ohne redundanten Code hervorgehoben.
Dieser Artikel demonstriert Techniken zum Verwalten von Build-Prozessen mithilfe von Dockerfiles und Makefiles.
Der zugehörige Code ist hier verfügbar: https://www.php.cn/link/5655cf23be4dda7082c8bb3a8d8f8016. Entdecken Sie die verschiedenen Git-Zweige für verschiedene Anwendungsfälle.
Lasst uns beginnen!
Nachdem ich eine neue Projektstruktur entwickelt hatte, entschied ich mich für Nix für das Abhängigkeitsmanagement (Sprachen, Tools, Bibliotheken). Nix erstellt eine temporäre Shell mit den angegebenen Abhängigkeiten.
Beim Ausführen von Binärdateien, die in einer Nix-Shell erstellt wurden, ist ein Fehler aufgetreten:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
Dadurch wurde die Lambda-Ausführung gestoppt. Beim Debuggen wurde die Grundursache entdeckt: Go verknüpft manchmal C-Bibliotheken dynamisch mit ausführbaren Dateien und gibt dabei Systempfade an. Die mit Nix-erstellten ausführbaren Dateien verknüpften Bibliotheken waren:
<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>
Der nicht standardmäßige Abhängigkeitsspeicher von Nix in Kombination mit den isolierten Docker-Containern von Lambda verhinderte, dass Lambda diese Bibliotheken finden konnte, da sie nur in meiner lokalen Nix-Installation vorhanden waren. Es wurde eine Lösung benötigt, um AWS SAM anzuweisen, den Code zu kompilieren und die Bibliotheksverknüpfung zu verwalten.
Es gibt zwei Bereitstellungsmethoden:
Lokal kompilieren und die ausführbare Datei in einer ZIP-Datei an AWS senden. AWS kopiert die ausführbare Datei in den Docker-Container. Dies bietet die schnellsten Kaltstarts.
Stellen Sie AWS Anweisungen zum Kompilieren innerhalb des Ausführungs-Docker-Containers bereit. Dies stellt die Kompatibilität sicher, führt aber zu langsameren Kaltstarts.
Ich habe mich für Dockerfiles entschieden, um weiterhin Nix zu verwenden, aber beide Methoden werden unten vorgestellt.
Für Zip-Dateien verwenden Sie diese Projektstruktur (beachten Sie das 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>
Das Makefile definiert Build-Befehle für jede Funktion unter Verwendung des build-<function_name>
-Musters (erforderlich von 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>
Informieren Sie SAM über diesen Vorgang:
<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
weist SAM an, das Makefile zu verwenden, das sich dort befindet, wo CodeUri
angibt.
Erstellen Sie ein Dockerfile
und ein .dockerignore
im Stammverzeichnis:
<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>
Das Dockerfile
gibt Build-Schritte an. ARG ENTRY_POINT
gibt den Lambda-Einstiegspunkt zur Erstellungszeit an:
<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>
Ändern template.yaml
:
<code>libc.so.6 not found in /nix/23fj39chsggb09s.libc</code>
Beachten Sie Metadata
und PackageType: Image
. DockerBuildArgs
übergibt ENTRY_POINT
vom Dockerfile
und ermöglicht so ein einziges Dockerfile
für alle Lambdas.
Diese ausführliche Erklärung bietet einen umfassenden Ansatz zur Verwaltung von Go-Builds in AWS SAM unter Verwendung von Zip-Dateien und Docker-Images. Die Wahl hängt von den Prioritäten der Build-Geschwindigkeit gegenüber der Bereitstellungskonsistenz ab.
Das obige ist der detaillierte Inhalt vonPassen Sie Go Builds auf AWS SAM mit Dockerfiles und Makefiles an. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!